Changeset e3f2765 in mainline for uspace/app/bithenge/sequence.c


Ignore:
Timestamp:
2012-08-04T00:56:49Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c3437d9
Parents:
0caaaa00
Message:

Bithenge: add repeat without count

File:
1 edited

Legend:

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

    r0caaaa00 re3f2765  
    5151        aoff64_t *ends;
    5252        size_t num_ends;
     53        bool end_on_empty;
    5354        bithenge_int_t num_xforms;
    5455} seq_node_t;
     
    9495                }
    9596
     97                if (self->end_on_empty) {
     98                        bool empty;
     99                        rc = bithenge_blob_empty(
     100                            bithenge_node_as_blob(subblob_node), &empty);
     101                        if (rc == EOK && empty) {
     102                                self->num_xforms = self->num_ends;
     103                                rc = ENOENT;
     104                        }
     105                        if (rc != EOK) {
     106                                bithenge_transform_dec_ref(subxform);
     107                                bithenge_node_dec_ref(subblob_node);
     108                                return rc;
     109                        }
     110                }
     111
    96112                bithenge_blob_t *subblob = bithenge_node_as_blob(subblob_node);
    97113                aoff64_t field_size;
     
    102118                if (rc != EOK)
    103119                        return rc;
     120
     121                if (self->num_xforms == -1) {
     122                        aoff64_t *new_ends = realloc(self->ends,
     123                            (self->num_ends + 1)*sizeof(*new_ends));
     124                        if (!new_ends)
     125                                return ENOMEM;
     126                        self->ends = new_ends;
     127                }
    104128
    105129                prev_offset = self->ends[self->num_ends] =
     
    135159                }
    136160
     161                if (self->end_on_empty) {
     162                        bool empty;
     163                        rc = bithenge_blob_empty(
     164                            bithenge_node_as_blob(blob_node), &empty);
     165                        if (rc == EOK && empty) {
     166                                self->num_xforms = self->num_ends;
     167                                rc = ENOENT;
     168                        }
     169                        if (rc != EOK) {
     170                                bithenge_transform_dec_ref(subxform);
     171                                bithenge_node_dec_ref(blob_node);
     172                                return rc;
     173                        }
     174                }
     175
    137176                aoff64_t size;
    138177                rc = bithenge_transform_prefix_apply(subxform, &self->scope,
     
    143182                        return rc;
    144183
     184                if (self->num_xforms == -1) {
     185                        aoff64_t *new_ends = realloc(self->ends,
     186                            (self->num_ends + 1)*sizeof(*new_ends));
     187                        if (!new_ends)
     188                                return ENOMEM;
     189                        self->ends = new_ends;
     190                }
    145191                self->ends[self->num_ends++] = start_pos + size;
    146192        } else {
     
    198244
    199245static int seq_node_init(seq_node_t *self, const seq_node_ops_t *ops,
    200     bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_int_t num_xforms)
     246    bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_int_t num_xforms,
     247    bool end_on_empty)
    201248{
    202249        self->ops = ops;
    203         self->ends = malloc(sizeof(*self->ends) * num_xforms);
    204         if (!self->ends) {
    205                 return ENOMEM;
    206         }
     250        if (num_xforms != -1) {
     251                self->ends = malloc(sizeof(*self->ends) * num_xforms);
     252                if (!self->ends)
     253                        return ENOMEM;
     254        } else
     255                self->ends = NULL;
    207256        bithenge_blob_inc_ref(blob);
    208257        self->blob = blob;
    209258        self->num_xforms = num_xforms;
    210259        self->num_ends = 0;
     260        self->end_on_empty = end_on_empty;
    211261        bithenge_scope_init(&self->scope);
    212262        int rc = bithenge_scope_copy(&self->scope, scope);
     
    405455
    406456        rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, scope,
    407             blob, self->num_subtransforms);
     457            blob, self->num_subtransforms, false);
    408458        if (rc != EOK) {
    409459                free(node);
     
    582632        repeat_node_t *self = node_as_repeat(base);
    583633
    584         for (bithenge_int_t i = 0; i < self->count; i++) {
     634        for (bithenge_int_t i = 0; self->count == -1 || i < self->count; i++) {
    585635                bithenge_node_t *subxform_result;
    586636                rc = seq_node_subtransform(repeat_as_seq(self),
    587637                    &subxform_result, i);
     638                if (rc != EOK && self->count == -1) {
     639                        rc = EOK;
     640                        break;
     641                }
    588642                if (rc != EOK)
    589643                        return rc;
     
    624678        bithenge_int_t index = bithenge_integer_node_value(key);
    625679        bithenge_node_dec_ref(key);
    626         if (index < 0 || index >= self->count)
     680        if (index < 0 || (self->count != -1 && index >= self->count))
    627681                return ENOENT;
    628682        return seq_node_subtransform(repeat_as_seq(self), out, index);
     
    660714    bool prefix)
    661715{
    662         bithenge_int_t count;
    663         bithenge_node_t *count_node;
    664         int rc = bithenge_expression_evaluate(self->expr, scope, &count_node);
    665         if (rc != EOK)
    666                 return rc;
    667         if (bithenge_node_type(count_node) != BITHENGE_NODE_INTEGER) {
     716        bithenge_int_t count = -1;
     717        if (self->expr != NULL) {
     718                bithenge_node_t *count_node;
     719                int rc = bithenge_expression_evaluate(self->expr, scope,
     720                    &count_node);
     721                if (rc != EOK)
     722                        return rc;
     723                if (bithenge_node_type(count_node) != BITHENGE_NODE_INTEGER) {
     724                        bithenge_node_dec_ref(count_node);
     725                        return EINVAL;
     726                }
     727                count = bithenge_integer_node_value(count_node);
    668728                bithenge_node_dec_ref(count_node);
    669                 return EINVAL;
    670         }
    671         count = bithenge_integer_node_value(count_node);
    672         bithenge_node_dec_ref(count_node);
    673         if (count < 0)
    674                 return EINVAL;
     729                if (count < 0)
     730                        return EINVAL;
     731        }
    675732
    676733        repeat_node_t *node = malloc(sizeof(*node));
     
    678735                return ENOMEM;
    679736
    680         rc = bithenge_init_internal_node(repeat_as_node(node),
     737        int rc = bithenge_init_internal_node(repeat_as_node(node),
    681738            &repeat_node_ops);
    682739        if (rc != EOK) {
     
    686743
    687744        rc = seq_node_init(repeat_as_seq(node), &repeat_node_seq_ops, scope,
    688             blob, count);
     745            blob, count, count == -1);
    689746        if (rc != EOK) {
    690747                free(node);
     
    700757}
    701758
     759static int repeat_transform_apply(bithenge_transform_t *base,
     760    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
     761{
     762        repeat_transform_t *self = transform_as_repeat(base);
     763        if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
     764                return EINVAL;
     765        return repeat_transform_make_node(self, out, scope,
     766            bithenge_node_as_blob(in), false);
     767}
     768
    702769static int repeat_transform_prefix_apply(bithenge_transform_t *base,
    703770    bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_node_t **out_node,
     
    710777
    711778        bithenge_int_t count = node_as_repeat(*out_node)->count;
    712         rc = seq_node_field_offset(node_as_seq(*out_node), out_size, count);
    713         if (rc != EOK) {
    714                 bithenge_node_dec_ref(*out_node);
    715                 return rc;
     779        if (count != -1) {
     780                rc = seq_node_field_offset(node_as_seq(*out_node), out_size, count);
     781                if (rc != EOK) {
     782                        bithenge_node_dec_ref(*out_node);
     783                        return rc;
     784                }
     785        } else {
     786                *out_size = 0;
     787                for (count = 1; ; count++) {
     788                        aoff64_t size;
     789                        rc = seq_node_field_offset(node_as_seq(*out_node),
     790                            &size, count);
     791                        if (rc != EOK)
     792                                break;
     793                        *out_size = size;
     794                }
    716795        }
    717796        return EOK;
     
    727806
    728807static const bithenge_transform_ops_t repeat_transform_ops = {
     808        .apply = repeat_transform_apply,
    729809        .prefix_apply = repeat_transform_prefix_apply,
    730810        .destroy = repeat_transform_destroy,
Note: See TracChangeset for help on using the changeset viewer.