Changeset 2988aec7 in mainline for uspace/app/bithenge/blob.c


Ignore:
Timestamp:
2012-08-14T03:17:17Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
71b0d4d4
Parents:
1b6b76d
Message:

Bithenge: read FAT files/subdirs; self-recursion and more operators

File:
1 edited

Legend:

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

    r1b6b76d r2988aec7  
    459459}
    460460
     461typedef struct {
     462        bithenge_blob_t base;
     463        bithenge_blob_t *a, *b;
     464        aoff64_t a_size;
     465} concat_blob_t;
     466
     467static inline concat_blob_t *blob_as_concat(bithenge_blob_t *base)
     468{
     469        return (concat_blob_t *)base;
     470}
     471
     472static inline bithenge_blob_t *concat_as_blob(concat_blob_t *blob)
     473{
     474        return &blob->base;
     475}
     476
     477static int concat_blob_size(bithenge_blob_t *base, aoff64_t *size)
     478{
     479        concat_blob_t *self = blob_as_concat(base);
     480        int rc = bithenge_blob_size(self->b, size);
     481        *size += self->a_size;
     482        return rc;
     483}
     484
     485static int concat_blob_read(bithenge_blob_t *base, aoff64_t offset,
     486    char *buffer, aoff64_t *size)
     487{
     488        int rc = EOK;
     489        concat_blob_t *self = blob_as_concat(base);
     490
     491        aoff64_t a_size = 0, b_size = 0;
     492        if (offset < self->a_size) {
     493                a_size = *size;
     494                rc = bithenge_blob_read(self->a, offset, buffer, &a_size);
     495                if (rc != EOK)
     496                        return rc;
     497        }
     498        if (offset + *size > self->a_size) {
     499                b_size = *size - a_size;
     500                rc = bithenge_blob_read(self->b,
     501                    offset + a_size - self->a_size, buffer + a_size, &b_size);
     502                if (rc != EOK)
     503                        return rc;
     504        }
     505        assert(a_size + b_size <= *size);
     506        *size = a_size + b_size;
     507        return rc;
     508}
     509
     510static int concat_blob_read_bits(bithenge_blob_t *base, aoff64_t offset,
     511    char *buffer, aoff64_t *size, bool little_endian)
     512{
     513        int rc = EOK;
     514        concat_blob_t *self = blob_as_concat(base);
     515
     516        aoff64_t a_size = 0, b_size = 0;
     517        if (offset < self->a_size) {
     518                a_size = *size;
     519                rc = bithenge_blob_read_bits(self->a, offset, buffer, &a_size,
     520                    little_endian);
     521                if (rc != EOK)
     522                        return rc;
     523        }
     524        if (offset + *size > self->a_size) {
     525                b_size = offset + *size - self->a_size;
     526                rc = bithenge_blob_read_bits(self->b,
     527                    offset + a_size - self->a_size, buffer + a_size, &b_size,
     528                    little_endian);
     529                if (rc != EOK)
     530                        return rc;
     531        }
     532        *size = a_size + b_size;
     533        return rc;
     534}
     535
     536static void concat_blob_destroy(bithenge_blob_t *base)
     537{
     538        concat_blob_t *self = blob_as_concat(base);
     539        bithenge_blob_dec_ref(self->a);
     540        bithenge_blob_dec_ref(self->b);
     541        free(self);
     542}
     543
     544static const bithenge_random_access_blob_ops_t concat_blob_ops = {
     545        .size = concat_blob_size,
     546        .read = concat_blob_read,
     547        .read_bits = concat_blob_read_bits,
     548        .destroy = concat_blob_destroy,
     549};
     550
     551/** Create a concatenated blob. Takes references to @a a and @a b.
     552 * @param[out] out Holds the new blob.
     553 * @param a The first blob.
     554 * @param b The second blob.
     555 * @return EOK on success or an error code from errno.h. */
     556int bithenge_concat_blob(bithenge_node_t **out, bithenge_blob_t *a,
     557    bithenge_blob_t *b)
     558{
     559        assert(out);
     560        assert(a);
     561        assert(b);
     562        int rc;
     563        concat_blob_t *self = malloc(sizeof(*self));
     564        if (!self) {
     565                rc = ENOMEM;
     566                goto error;
     567        }
     568
     569        rc = bithenge_blob_size(a, &self->a_size);
     570        if (rc != EOK)
     571                goto error;
     572
     573        rc = bithenge_init_random_access_blob(concat_as_blob(self),
     574            &concat_blob_ops);
     575        if (rc != EOK)
     576                goto error;
     577        self->a = a;
     578        self->b = b;
     579        *out = bithenge_blob_as_node(concat_as_blob(self));
     580        return EOK;
     581
     582error:
     583        bithenge_blob_dec_ref(a);
     584        bithenge_blob_dec_ref(b);
     585        free(self);
     586        return rc;
     587}
     588
    461589/** Check whether the contents of two blobs are equal.
    462590 * @memberof bithenge_blob_t
Note: See TracChangeset for help on using the changeset viewer.