Changeset 3a7356dc in mainline for uspace/lib/bithenge/blob.c


Ignore:
Timestamp:
2012-08-18T03:58:10Z (13 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1f9c9a4
Parents:
681a985
Message:

Bithenge: make concatenation lazier

File:
1 edited

Legend:

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

    r681a985 r3a7356dc  
    459459}
    460460
    461 typedef struct {
    462         bithenge_blob_t base;
    463         bithenge_blob_t *a, *b;
    464         aoff64_t a_size;
    465 } concat_blob_t;
    466 
    467 static inline concat_blob_t *blob_as_concat(bithenge_blob_t *base)
    468 {
    469         return (concat_blob_t *)base;
    470 }
    471 
    472 static inline bithenge_blob_t *concat_as_blob(concat_blob_t *blob)
    473 {
    474         return &blob->base;
    475 }
    476 
    477 static 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 
    485 static 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 
    510 static 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 
    536 static 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 
    544 static 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. */
    556 int 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 
    582 error:
    583         bithenge_blob_dec_ref(a);
    584         bithenge_blob_dec_ref(b);
    585         free(self);
    586         return rc;
    587 }
    588 
    589461/** Check whether the contents of two blobs are equal.
    590462 * @memberof bithenge_blob_t
Note: See TracChangeset for help on using the changeset viewer.