Changeset 3a7356dc in mainline for uspace/lib/bithenge/blob.c
- Timestamp:
- 2012-08-18T03:58:10Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1f9c9a4
- Parents:
- 681a985
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/bithenge/blob.c
r681a985 r3a7356dc 459 459 } 460 460 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 589 461 /** Check whether the contents of two blobs are equal. 590 462 * @memberof bithenge_blob_t
Note:
See TracChangeset
for help on using the changeset viewer.