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

Changeset c54f5d0 in mainline


Ignore:
Timestamp:
2012-08-09T05:23:54Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
71450c8
Parents:
3c70376
Message:

Bithenge: partial transforms

Location:
uspace/app/bithenge
Files:
3 edited

Legend:

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

    r3c70376 rc54f5d0  
    260260}
    261261
     262
     263
     264/***************** partial_transform                         *****************/
     265
     266typedef struct {
     267        bithenge_transform_t base;
     268        bithenge_transform_t *xform;
     269} partial_transform_t;
     270
     271static inline bithenge_transform_t *partial_as_transform(
     272    partial_transform_t *self)
     273{
     274        return &self->base;
     275}
     276
     277static inline partial_transform_t *transform_as_partial(
     278    bithenge_transform_t *base)
     279{
     280        return (partial_transform_t *)base;
     281}
     282
     283static int partial_transform_apply(bithenge_transform_t *base,
     284    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
     285{
     286        partial_transform_t *self = transform_as_partial(base);
     287        if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
     288                return EINVAL;
     289        uint64_t size;
     290        return bithenge_transform_prefix_apply(self->xform, scope,
     291            bithenge_node_as_blob(in), out, &size);
     292}
     293
     294static void partial_transform_destroy(bithenge_transform_t *base)
     295{
     296        partial_transform_t *self = transform_as_partial(base);
     297        bithenge_transform_dec_ref(self->xform);
     298        free(self);
     299}
     300
     301static const bithenge_transform_ops_t partial_transform_ops = {
     302        .apply = partial_transform_apply,
     303        .destroy = partial_transform_destroy,
     304};
     305
     306/** Create a transform that doesn't require its subtransform to use the whole
     307 * input. Takes a reference to @a xform.
     308 * @param[out] out Holds the new transform.
     309 * @param xform The subtransform to apply.
     310 * @return EOK on success or an error code from errno.h. */
     311int bithenge_partial_transform(bithenge_transform_t **out,
     312    bithenge_transform_t *xform)
     313{
     314        int rc;
     315        partial_transform_t *self = malloc(sizeof(*self));
     316        if (!self) {
     317                rc = ENOMEM;
     318                goto error;
     319        }
     320
     321        rc = bithenge_init_transform(partial_as_transform(self),
     322            &partial_transform_ops, 0);
     323        if (rc != EOK)
     324                goto error;
     325
     326        self->xform = xform;
     327        *out = partial_as_transform(self);
     328        return EOK;
     329
     330error:
     331        free(self);
     332        bithenge_transform_dec_ref(xform);
     333        return rc;
     334}
     335
    262336/** @}
    263337 */
  • uspace/app/bithenge/compound.h

    r3c70376 rc54f5d0  
    4545int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *,
    4646    bithenge_transform_t *, bithenge_transform_t *);
     47int bithenge_partial_transform(bithenge_transform_t **,
     48    bithenge_transform_t *);
    4749
    4850#endif
  • uspace/app/bithenge/script.c

    r3c70376 rc54f5d0  
    6666        TOKEN_IF,
    6767        TOKEN_IN,
     68        TOKEN_PARTIAL,
    6869        TOKEN_REPEAT,
    6970        TOKEN_STRUCT,
     
    232233                } else if (!str_cmp(value, "in")) {
    233234                        state->token = TOKEN_IN;
     235                        free(value);
     236                } else if (!str_cmp(value, "partial")) {
     237                        state->token = TOKEN_PARTIAL;
    234238                        free(value);
    235239                } else if (!str_cmp(value, "repeat")) {
     
    871875}
    872876
     877static bithenge_transform_t *parse_partial(state_t *state)
     878{
     879        expect(state, TOKEN_PARTIAL);
     880        bithenge_transform_t *offset_xform = NULL;
     881        if (state->token == '(') {
     882                next_token(state);
     883                bithenge_expression_t *offset = parse_expression(state);
     884                expect(state, ')');
     885
     886                bithenge_expression_t *in_expr;
     887                int rc = bithenge_in_node_expression(&in_expr);
     888                if (rc != EOK)
     889                        error_errno(state, rc);
     890                if (state->error != EOK) {
     891                        bithenge_expression_dec_ref(offset);
     892                        return NULL;
     893                }
     894
     895                rc = bithenge_subblob_expression(&offset, in_expr, offset,
     896                    NULL, true);
     897                if (rc != EOK) {
     898                        error_errno(state, rc);
     899                        return NULL;
     900                }
     901
     902                rc = bithenge_expression_transform(&offset_xform, offset);
     903                if (rc != EOK) {
     904                        error_errno(state, rc);
     905                        return NULL;
     906                }
     907        }
     908        expect(state, '{');
     909        bithenge_transform_t *xform = parse_transform(state);
     910        expect(state, '}');
     911        if (state->error != EOK) {
     912                bithenge_transform_dec_ref(offset_xform);
     913                bithenge_transform_dec_ref(xform);
     914                return NULL;
     915        }
     916
     917        int rc = bithenge_partial_transform(&xform, xform);
     918        if (rc != EOK) {
     919                error_errno(state, rc);
     920                bithenge_transform_dec_ref(offset_xform);
     921                return NULL;
     922        }
     923
     924        if (offset_xform) {
     925                bithenge_transform_t **xforms = malloc(2 * sizeof(*xforms));
     926                if (!xforms) {
     927                        error_errno(state, ENOMEM);
     928                        bithenge_transform_dec_ref(xform);
     929                        bithenge_transform_dec_ref(offset_xform);
     930                        return NULL;
     931                }
     932                xforms[0] = xform;
     933                xforms[1] = offset_xform;
     934                rc = bithenge_new_composed_transform(&xform, xforms, 2);
     935                if (rc != EOK) {
     936                        error_errno(state, rc);
     937                        return NULL;
     938                }
     939        }
     940
     941        return xform;
     942}
     943
    873944/* The TOKEN_STRUCT and '{' must already have been skipped. */
    874945static bithenge_transform_t *parse_struct(state_t *state)
     
    9521023        } else if (state->token == TOKEN_IF) {
    9531024                return parse_if(state, false);
     1025        } else if (state->token == TOKEN_PARTIAL) {
     1026                return parse_partial(state);
    9541027        } else if (state->token == TOKEN_REPEAT) {
    9551028                return parse_repeat(state);
Note: See TracChangeset for help on using the changeset viewer.