Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b8d45e9e in mainline for uspace/app/bithenge/transform.c


Ignore:
Timestamp:
2012-08-02T21:06:59Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
0f8062a4
Parents:
cb4a66d2
Message:

Bithenge: make each transform definition have its own scope

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/transform.c

    rcb4a66d2 rb8d45e9e  
    165165}
    166166
     167/** Initialize a transform scope. It must be destroyed with @a
     168 * bithenge_scope_destroy after it is used.
     169 * @param[out] scope The scope to initialize. */
     170void bithenge_scope_init(bithenge_scope_t *scope)
     171{
     172        scope->num_params = 0;
     173        scope->params = NULL;
     174        scope->current_node = NULL;
     175}
     176
     177/** Destroy a transform scope.
     178 * @param scope The scope to destroy.
     179 * @return EOK on success or an error code from errno.h. */
     180void bithenge_scope_destroy(bithenge_scope_t *scope)
     181{
     182        bithenge_node_dec_ref(scope->current_node);
     183        for (int i = 0; i < scope->num_params; i++)
     184                bithenge_node_dec_ref(scope->params[i]);
     185        free(scope->params);
     186}
     187
     188/** Copy a scope.
     189 * @param[out] out The scope to fill in; must have been initialized with @a
     190 * bithenge_scope_init.
     191 * @param scope The scope to copy.
     192 * @return EOK on success or an error code from errno.h. */
     193int bithenge_scope_copy(bithenge_scope_t *out, bithenge_scope_t *scope)
     194{
     195        out->params = malloc(sizeof(*out->params) * scope->num_params);
     196        if (!out->params)
     197                return ENOMEM;
     198        memcpy(out->params, scope->params, sizeof(*out->params) *
     199            scope->num_params);
     200        out->num_params = scope->num_params;
     201        for (int i = 0; i < out->num_params; i++)
     202                bithenge_node_inc_ref(out->params[i]);
     203        out->current_node = scope->current_node;
     204        if (out->current_node)
     205                bithenge_node_inc_ref(out->current_node);
     206        return EOK;
     207}
     208
     209/** Set the current node being created. Takes a reference to @a node.
     210 * @param scope The scope to set the current node in.
     211 * @param node The current node being created, or NULL.
     212 * @return EOK on success or an error code from errno.h. */
     213void bithenge_scope_set_current_node(bithenge_scope_t *scope,
     214    bithenge_node_t *node)
     215{
     216        bithenge_node_dec_ref(scope->current_node);
     217        scope->current_node = node;
     218}
     219
     220/** Get the current node being created, which may be NULL.
     221 * @param scope The scope to get the current node from.
     222 * @return The node being created, or NULL. */
     223bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *scope)
     224{
     225        if (scope->current_node)
     226                bithenge_node_inc_ref(scope->current_node);
     227        return scope->current_node;
     228}
     229
     230/** Allocate parameters. The parameters must then be set with @a
     231 * bithenge_scope_set_param. This must not be called on a scope that already
     232 * has parameters.
     233 * @param scope The scope in which to allocate parameters.
     234 * @param num_params The number of parameters to allocate.
     235 * @return EOK on success or an error code from errno.h. */
     236int bithenge_scope_alloc_params(bithenge_scope_t *scope, int num_params)
     237{
     238        scope->params = malloc(sizeof(*scope->params) * num_params);
     239        if (!scope->params)
     240                return ENOMEM;
     241        scope->num_params = num_params;
     242        for (int i = 0; i < num_params; i++)
     243                scope->params[i] = NULL;
     244        return EOK;
     245}
     246
     247/** Set a parameter. Takes a reference to @a value. Note that range checking is
     248 * not done in release builds.
     249 * @param scope The scope in which to allocate parameters.
     250 * @param i The index of the parameter to set.
     251 * @param value The value to store in the parameter.
     252 * @return EOK on success or an error code from errno.h. */
     253int bithenge_scope_set_param( bithenge_scope_t *scope, int i,
     254    bithenge_node_t *node)
     255{
     256        assert(scope);
     257        assert(i >= 0 && i < scope->num_params);
     258        scope->params[i] = node;
     259        return EOK;
     260}
     261
     262/** Get a parameter. Note that range checking is not done in release builds.
     263 * @param scope The scope to get the parameter from.
     264 * @param i The index of the parameter to set.
     265 * @param[out] out Stores a new reference to the parameter.
     266 * @return EOK on success or an error code from errno.h. */
     267int bithenge_scope_get_param(bithenge_scope_t *scope, int i,
     268    bithenge_node_t **out)
     269{
     270        assert(scope);
     271        assert(i >= 0 && i < scope->num_params);
     272        *out = scope->params[i];
     273        bithenge_node_inc_ref(*out);
     274        return EOK;
     275}
     276
    167277typedef struct {
    168278        bithenge_transform_t base;
    169279        bithenge_transform_t *transform;
    170 } param_transform_t;
    171 
    172 static inline param_transform_t *transform_as_param(
     280} scope_transform_t;
     281
     282static inline scope_transform_t *transform_as_param(
    173283    bithenge_transform_t *base)
    174284{
    175         return (param_transform_t *)base;
     285        return (scope_transform_t *)base;
    176286}
    177287
    178288static inline bithenge_transform_t *param_as_transform(
    179     param_transform_t *self)
     289    scope_transform_t *self)
    180290{
    181291        return &self->base;
    182292}
    183293
    184 static int param_transform_apply(bithenge_transform_t *base,
     294static int scope_transform_apply(bithenge_transform_t *base,
    185295    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
    186296{
    187         param_transform_t *self = transform_as_param(base);
    188         return bithenge_transform_apply(self->transform, scope, in, out);
    189 }
    190 
    191 static int param_transform_prefix_length(bithenge_transform_t *base,
     297        scope_transform_t *self = transform_as_param(base);
     298        bithenge_scope_t inner_scope;
     299        bithenge_scope_init(&inner_scope);
     300        int rc = bithenge_scope_copy(&inner_scope, scope);
     301        if (rc != EOK)
     302                goto error;
     303        bithenge_scope_set_current_node(&inner_scope, NULL);
     304        rc = bithenge_transform_apply(self->transform, scope, in, out);
     305error:
     306        bithenge_scope_destroy(&inner_scope);
     307        return rc;
     308}
     309
     310static int scope_transform_prefix_length(bithenge_transform_t *base,
    192311    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
    193312{
    194         param_transform_t *self = transform_as_param(base);
     313        scope_transform_t *self = transform_as_param(base);
    195314        return bithenge_transform_prefix_length(self->transform, scope, in,
    196315            out);
    197316}
    198317
    199 static void param_transform_destroy(bithenge_transform_t *base)
    200 {
    201         param_transform_t *self = transform_as_param(base);
     318static void scope_transform_destroy(bithenge_transform_t *base)
     319{
     320        scope_transform_t *self = transform_as_param(base);
    202321        bithenge_transform_dec_ref(self->transform);
    203322        free(self);
    204323}
    205324
    206 static const bithenge_transform_ops_t param_transform_ops = {
    207         .apply = param_transform_apply,
    208         .prefix_length = param_transform_prefix_length,
    209         .destroy = param_transform_destroy,
    210 };
    211 
    212 /** Create a wrapper transform with a different number of parameters. Takes a
    213  * reference to @a transform, which it will use for all operations.
     325static const bithenge_transform_ops_t scope_transform_ops = {
     326        .apply = scope_transform_apply,
     327        .prefix_length = scope_transform_prefix_length,
     328        .destroy = scope_transform_destroy,
     329};
     330
     331/** Create a wrapper transform that creates a new outer scope. This ensures
     332 * nothing from the transform's users is passed in, other than parameters. The
     333 * wrapper may have a different value for num_params. Takes a reference to
     334 * @a transform, which it will use for all operations.
    214335 * @param[out] out Holds the created transform.
    215336 * @param transform The transform to wrap.
    216  * @param num_params The number of parameters to require.
     337 * @param num_params The number of parameters to require, which may be 0.
    217338 * @return EOK on success or an error code from errno.h. */
    218 int bithenge_new_param_transform(bithenge_transform_t **out,
     339int bithenge_new_scope_transform(bithenge_transform_t **out,
    219340    bithenge_transform_t *transform, int num_params)
    220341{
    221342        assert(transform);
    222343        assert(bithenge_transform_num_params(transform) == 0);
    223         assert(num_params != 0);
    224344
    225345        int rc;
    226         param_transform_t *self = malloc(sizeof(*self));
     346        scope_transform_t *self = malloc(sizeof(*self));
    227347        if (!self) {
    228348                rc = ENOMEM;
     
    230350        }
    231351        rc = bithenge_init_transform(param_as_transform(self),
    232             &param_transform_ops, num_params);
     352            &scope_transform_ops, num_params);
    233353        if (rc != EOK)
    234354                goto error;
     
    497617
    498618typedef struct {
     619        bithenge_transform_t base;
     620        bithenge_named_transform_t *subtransforms;
     621        size_t num_subtransforms;
     622} struct_transform_t;
     623
     624typedef struct {
    499625        bithenge_node_t base;
    500626        bithenge_scope_t scope;
    501         struct struct_transform *transform;
     627        struct_transform_t *transform;
    502628        bithenge_blob_t *blob;
    503629        aoff64_t *ends;
     
    505631        bool prefix;
    506632} struct_node_t;
    507 
    508 typedef struct struct_transform {
    509         bithenge_transform_t base;
    510         bithenge_named_transform_t *subtransforms;
    511         size_t num_subtransforms;
    512 } struct_transform_t;
    513633
    514634static bithenge_node_t *struct_as_node(struct_node_t *node)
Note: See TracChangeset for help on using the changeset viewer.