Changeset 2988aec7 in mainline for uspace/app/bithenge/blob.c
- Timestamp:
- 2012-08-14T03:17:17Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 71b0d4d4
- Parents:
- 1b6b76d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/blob.c
r1b6b76d r2988aec7 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 461 589 /** Check whether the contents of two blobs are equal. 462 590 * @memberof bithenge_blob_t
Note:
See TracChangeset
for help on using the changeset viewer.