source: mainline/uspace/app/bithenge/transform.h@ 5a7c0e6

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

Bithenge: rename transform parameters "scopes" and add room for parameters

  • Property mode set to 100644
File size: 7.8 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 * Transforms.
35 */
36
37#ifndef BITHENGE_TRANSFORM_H_
38#define BITHENGE_TRANSFORM_H_
39
40#include "blob.h"
41#include "tree.h"
42
43/** A transform that creates a new tree from an old tree. */
44typedef struct {
45 /** @privatesection */
46 const struct bithenge_transform_ops *ops;
47 unsigned int refs;
48} bithenge_transform_t;
49
50/** Context and parameters used when applying transforms. */
51typedef struct {
52 /** @privatesection */
53 bithenge_node_t **params;
54 int num_params;
55} bithenge_scope_t;
56
57/** Operations that may be provided by a transform. */
58typedef struct bithenge_transform_ops {
59 /** @copydoc bithenge_transform_t::bithenge_transform_apply */
60 int (*apply)(bithenge_transform_t *self, bithenge_scope_t *scope,
61 bithenge_node_t *in, bithenge_node_t **out);
62 /** @copydoc bithenge_transform_t::bithenge_transform_prefix_length */
63 int (*prefix_length)(bithenge_transform_t *self,
64 bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out);
65 /** Destroy the transform.
66 * @param self The transform. */
67 void (*destroy)(bithenge_transform_t *self);
68 /** The number of parameters required. */
69 int num_params;
70} bithenge_transform_ops_t;
71
72/** Initialize a transform scope. It must be destroyed with @a
73 * bithenge_scope_destroy after it is used.
74 * @param[out] scope The scope to initialize. */
75static inline void bithenge_scope_init(bithenge_scope_t *scope)
76{
77 scope->params = NULL;
78 scope->num_params = 0;
79}
80
81/** Destroy a transform scope.
82 * @param scope The scope to destroy.
83 * @return EOK on success or an error code from errno.h. */
84static inline void bithenge_scope_destroy(bithenge_scope_t *scope)
85{
86 for (int i = 0; i < scope->num_params; i++)
87 bithenge_node_dec_ref(scope->params[i]);
88 free(scope->params);
89}
90
91/** Allocate parameters. The parameters must then be set with @a
92 * bithenge_scope_set_param.
93 * @param scope The scope in which to allocate parameters.
94 * @param num_params The number of parameters to allocate.
95 * @return EOK on success or an error code from errno.h. */
96static inline int bithenge_scope_alloc_params(bithenge_scope_t *scope,
97 int num_params)
98{
99 scope->params = malloc(sizeof(*scope->params) * num_params);
100 if (!scope->params)
101 return ENOMEM;
102 scope->num_params = num_params;
103 return EOK;
104}
105
106/** Set a parameter. Takes a reference to @a value. Note that range checking is
107 * not done in release builds.
108 * @param scope The scope in which to allocate parameters.
109 * @param i The index of the parameter to set.
110 * @param value The value to store in the parameter.
111 * @return EOK on success or an error code from errno.h. */
112static inline int bithenge_scope_set_param( bithenge_scope_t *scope, int i,
113 bithenge_node_t *node)
114{
115 assert(scope);
116 assert(i >= 0 && i < scope->num_params);
117 scope->params[i] = node;
118 return EOK;
119}
120
121/** Get a parameter. Note that range checking is not done in release builds.
122 * @param scope The scope to get the parameter from.
123 * @param i The index of the parameter to set.
124 * @param[out] out Stores a new reference to the parameter.
125 * @return EOK on success or an error code from errno.h. */
126static inline int bithenge_scope_get_param(bithenge_scope_t *scope, int i,
127 bithenge_node_t **out)
128{
129 assert(scope);
130 assert(i >= 0 && i < scope->num_params);
131 *out = scope->params[i];
132 bithenge_node_inc_ref(*out);
133 return EOK;
134}
135
136/** Get the number of parameters required by a transform. Takes ownership of
137 * nothing.
138 * @param self The transform.
139 * @return The number of parameters required. */
140static inline int bithenge_transform_num_params(bithenge_transform_t *self)
141{
142 assert(self);
143 assert(self->ops);
144 return self->ops->num_params;
145}
146
147/** Apply a transform. Takes ownership of nothing.
148 * @memberof bithenge_transform_t
149 * @param self The transform.
150 * @param scope The scope.
151 * @param in The input tree.
152 * @param[out] out Where the output tree will be stored.
153 * @return EOK on success or an error code from errno.h. */
154static inline int bithenge_transform_apply(bithenge_transform_t *self,
155 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
156{
157 assert(self);
158 assert(self->ops);
159 return self->ops->apply(self, scope, in, out);
160}
161
162/** Find the length of the prefix of a blob this transform can use as input. In
163 * other words, figure out how many bytes this transform will use up. This
164 * method is optional and can return an error, but it must succeed for struct
165 * subtransforms. Takes ownership of nothing.
166 * @memberof bithenge_transform_t
167 * @param self The transform.
168 * @param scope The scope.
169 * @param blob The blob.
170 * @param[out] out Where the prefix length will be stored.
171 * @return EOK on success, ENOTSUP if not supported, or another error code from
172 * errno.h. */
173static inline int bithenge_transform_prefix_length(bithenge_transform_t *self,
174 bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
175{
176 assert(self);
177 assert(self->ops);
178 if (!self->ops->prefix_length)
179 return ENOTSUP;
180 return self->ops->prefix_length(self, scope, blob, out);
181}
182
183/** Increment a transform's reference count.
184 * @param self The transform to reference. */
185static inline void bithenge_transform_inc_ref(bithenge_transform_t *self)
186{
187 assert(self);
188 self->refs++;
189}
190
191/** Decrement a transform's reference count and free it if appropriate.
192 * @param self The transform to dereference, or NULL. */
193static inline void bithenge_transform_dec_ref(bithenge_transform_t *self)
194{
195 if (!self)
196 return;
197 assert(self->ops);
198 if (--self->refs == 0)
199 self->ops->destroy(self);
200}
201
202/** A transform with a name. */
203typedef struct {
204 const char *name;
205 bithenge_transform_t *transform;
206} bithenge_named_transform_t;
207
208extern bithenge_transform_t bithenge_ascii_transform;
209extern bithenge_transform_t bithenge_uint8_transform;
210extern bithenge_transform_t bithenge_uint16le_transform;
211extern bithenge_transform_t bithenge_uint16be_transform;
212extern bithenge_transform_t bithenge_uint32le_transform;
213extern bithenge_transform_t bithenge_uint32be_transform;
214extern bithenge_transform_t bithenge_uint64le_transform;
215extern bithenge_transform_t bithenge_uint64be_transform;
216extern bithenge_transform_t bithenge_zero_terminated_transform;
217extern bithenge_named_transform_t *bithenge_primitive_transforms;
218
219int bithenge_init_transform(bithenge_transform_t *self,
220 const bithenge_transform_ops_t *ops);
221int bithenge_new_struct(bithenge_transform_t **out,
222 bithenge_named_transform_t *subtransforms);
223int bithenge_new_composed_transform(bithenge_transform_t **,
224 bithenge_transform_t **, size_t);
225
226#endif
227
228/** @}
229 */
Note: See TracBrowser for help on using the repository browser.