source: mainline/uspace/app/bithenge/tree.c@ 8b36bf2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8b36bf2 was 8375d0eb, checked in by Sean Bartell <wingedtachikoma@…>, 13 years ago

Bithenge: add Doxygen comments

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2012 Sean Bartell
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup bithenge
30 * @{
31 */
32/**
33 * @file
34 * Trees and nodes.
35 */
36
37#include <errno.h>
38#include <stdlib.h>
39#include "blob.h"
40#include "tree.h"
41
42static int blob_destroy(bithenge_node_t *base)
43{
44 bithenge_blob_t *blob = bithenge_node_as_blob(base);
45 assert(blob->base.blob_ops);
46 return blob->base.blob_ops->destroy(blob);
47}
48
49/** Destroy a node.
50 * @memberof bithenge_node_t
51 * @param node The node to destroy.
52 * @return EOK on success or an error code from errno.h. */
53int bithenge_node_destroy(bithenge_node_t *node)
54{
55 switch (bithenge_node_type(node)) {
56 case BITHENGE_NODE_BLOB:
57 return blob_destroy(node);
58 case BITHENGE_NODE_STRING:
59 if (node->string_value.needs_free)
60 free(node->string_value.ptr);
61 break;
62 case BITHENGE_NODE_INTERNAL:
63 return node->internal_ops->destroy(node);
64 case BITHENGE_NODE_BOOLEAN:
65 return EOK; // the boolean nodes are allocated statically below
66 case BITHENGE_NODE_INTEGER: /* pass-through */
67 break;
68 }
69 free(node);
70 return EOK;
71}
72
73typedef struct
74{
75 bithenge_node_t base;
76 bithenge_node_t **nodes;
77 bithenge_int_t len;
78 bool needs_free;
79} simple_internal_node_t;
80
81static simple_internal_node_t *node_as_simple(bithenge_node_t *node)
82{
83 return (simple_internal_node_t *)node;
84}
85
86static int simple_internal_node_for_each(bithenge_node_t *base,
87 bithenge_for_each_func_t func, void *data)
88{
89 int rc;
90 simple_internal_node_t *node = node_as_simple(base);
91 for (bithenge_int_t i = 0; i < node->len; i++) {
92 rc = func(node->nodes[2*i+0], node->nodes[2*i+1], data);
93 if (rc != EOK)
94 return rc;
95 }
96 return EOK;
97}
98
99static int simple_internal_node_destroy(bithenge_node_t *base)
100{
101 int rc;
102 simple_internal_node_t *node = node_as_simple(base);
103 for (bithenge_int_t i = 0; i < node->len; i++) {
104 rc = bithenge_node_destroy(node->nodes[2*i+0]);
105 if (rc != EOK)
106 return rc;
107 rc = bithenge_node_destroy(node->nodes[2*i+1]);
108 if (rc != EOK)
109 return rc;
110 }
111 if (node->needs_free)
112 free(node->nodes);
113 free(node);
114 return EOK;
115}
116
117static bithenge_internal_node_ops_t simple_internal_node_ops = {
118 .for_each = simple_internal_node_for_each,
119 .destroy = simple_internal_node_destroy,
120};
121
122static bithenge_node_t *simple_internal_as_node(simple_internal_node_t *node)
123{
124 return &node->base;
125}
126
127/** Create an internal node from a set of keys and values. The node must be
128 * freed with @a bithenge_node_t::bithenge_node_destroy after it is used, which
129 * will also destroy all the key and value nodes.
130 * @memberof bithenge_node_t
131 * @param[out] out Stores the created internal node.
132 * @param nodes The array of key-value pairs. Keys are stored at even indices
133 * and values are stored at odd indices.
134 * @param len The number of key-value pairs in the node array.
135 * @param needs_free If true, when the internal node is destroyed it will free
136 * the nodes array as well as destroying each node inside it.
137 * @return EOK on success or an error code from errno.h. */
138int bithenge_new_simple_internal_node(bithenge_node_t **out,
139 bithenge_node_t **nodes, bithenge_int_t len, bool needs_free)
140{
141 assert(out);
142 simple_internal_node_t *node = malloc(sizeof(*node));
143 if (!node)
144 return ENOMEM;
145 node->base.type = BITHENGE_NODE_INTERNAL;
146 node->base.internal_ops = &simple_internal_node_ops;
147 node->nodes = nodes;
148 node->len = len;
149 node->needs_free = needs_free;
150 *out = simple_internal_as_node(node);
151 return EOK;
152}
153
154static bithenge_node_t false_node = { BITHENGE_NODE_BOOLEAN, .boolean_value = false };
155static bithenge_node_t true_node = { BITHENGE_NODE_BOOLEAN, .boolean_value = true };
156
157/** Create a boolean node. The node must be freed with @a
158 * bithenge_node_t::bithenge_node_destroy after it is used.
159 * @memberof bithenge_node_t
160 * @param[out] out Stores the created boolean node.
161 * @param value The value for the node to hold.
162 * @return EOK on success or an error code from errno.h. */
163int bithenge_new_boolean_node(bithenge_node_t **out, bool value)
164{
165 assert(out);
166 *out = value ? &true_node : &false_node;
167 return EOK;
168}
169
170/** Create an integer node. The node must be freed with @a
171 * bithenge_node_t::bithenge_node_destroy after it is used.
172 * @memberof bithenge_node_t
173 * @param[out] out Stores the created integer node.
174 * @param value The value for the node to hold.
175 * @return EOK on success or an error code from errno.h. */
176int bithenge_new_integer_node(bithenge_node_t **out, bithenge_int_t value)
177{
178 assert(out);
179 bithenge_node_t *node = malloc(sizeof(*node));
180 if (!node)
181 return ENOMEM;
182 node->type = BITHENGE_NODE_INTEGER;
183 node->integer_value = value;
184 *out = node;
185 return EOK;
186}
187
188/** Create a string node. The node must be freed with @a
189 * bithenge_node_t::bithenge_node_destroy after it is used.
190 * @memberof bithenge_node_t
191 * @param[out] out Stores the created string node.
192 * @param value The value for the node to hold.
193 * @param needs_free Whether the string should be freed when the node is
194 * destroyed.
195 * @return EOK on success or an error code from errno.h. */
196int bithenge_new_string_node(bithenge_node_t **out, const char *value, bool needs_free)
197{
198 assert(out);
199 bithenge_node_t *node = malloc(sizeof(*node));
200 if (!node)
201 return ENOMEM;
202 node->type = BITHENGE_NODE_STRING;
203 node->string_value.ptr = value;
204 node->string_value.needs_free = needs_free;
205 *out = node;
206 return EOK;
207}
208
209/** @}
210 */
Note: See TracBrowser for help on using the repository browser.