Changeset cb4a66d2 in mainline
- Timestamp:
- 2012-08-01T23:43:10Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b8d45e9e
- Parents:
- 47a728e1
- Location:
- uspace/app/bithenge
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/transform.c
r47a728e1 rcb4a66d2 54 54 { 55 55 assert(ops); 56 assert(ops->apply );56 assert(ops->apply || ops->prefix_apply); 57 57 assert(ops->destroy); 58 58 self->ops = ops; … … 65 65 { 66 66 assert(false); 67 } 68 69 /** Apply a transform. Takes ownership of nothing. 70 * @memberof bithenge_transform_t 71 * @param self The transform. 72 * @param scope The scope. 73 * @param in The input tree. 74 * @param[out] out Where the output tree will be stored. 75 * @return EOK on success or an error code from errno.h. */ 76 int bithenge_transform_apply(bithenge_transform_t *self, 77 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 78 { 79 assert(self); 80 assert(self->ops); 81 if (self->ops->apply) 82 return self->ops->apply(self, scope, in, out); 83 84 if (bithenge_node_type(in) != BITHENGE_NODE_BLOB) 85 return EINVAL; 86 aoff64_t self_size, whole_size; 87 int rc = bithenge_transform_prefix_apply(self, scope, 88 bithenge_node_as_blob(in), out, &self_size); 89 if (rc != EOK) 90 return rc; 91 rc = bithenge_blob_size(bithenge_node_as_blob(in), &whole_size); 92 if (rc == EOK && whole_size != self_size) 93 rc = EINVAL; 94 if (rc != EOK) { 95 bithenge_node_dec_ref(*out); 96 return rc; 97 } 98 return EOK; 99 } 100 101 /** Find the length of the prefix of a blob this transform can use as input. In 102 * other words, figure out how many bytes this transform will use up. This 103 * method is optional and can return an error, but it must succeed for struct 104 * subtransforms. Takes ownership of nothing. 105 * @memberof bithenge_transform_t 106 * @param self The transform. 107 * @param scope The scope. 108 * @param blob The blob. 109 * @param[out] out Where the prefix length will be stored. 110 * @return EOK on success, ENOTSUP if not supported, or another error code from 111 * errno.h. */ 112 int bithenge_transform_prefix_length(bithenge_transform_t *self, 113 bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out) 114 { 115 assert(self); 116 assert(self->ops); 117 if (self->ops->prefix_length) 118 return self->ops->prefix_length(self, scope, blob, out); 119 if (!self->ops->prefix_apply) 120 return ENOTSUP; 121 122 bithenge_node_t *node; 123 int rc = bithenge_transform_prefix_apply(self, scope, blob, &node, 124 out); 125 if (rc != EOK) 126 return rc; 127 bithenge_node_dec_ref(node); 128 return EOK; 129 } 130 131 /** Apply this transform to a prefix of a blob. In other words, feed as much of 132 * the blob into this transform as possible. Takes ownership of nothing. 133 * @memberof bithenge_transform_t 134 * @param self The transform. 135 * @param scope The scope. 136 * @param blob The blob. 137 * @param[out] out_node Holds the result of applying this transform to the 138 * prefix. 139 * @param[out] out_size Holds the size of the prefix. 140 * @return EOK on success, ENOTSUP if not supported, or another error code from 141 * errno.h. */ 142 int bithenge_transform_prefix_apply(bithenge_transform_t *self, 143 bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_node_t **out_node, 144 aoff64_t *out_size) 145 { 146 assert(self); 147 assert(self->ops); 148 if (self->ops->prefix_apply) 149 return self->ops->prefix_apply(self, scope, blob, out_node, 150 out_size); 151 if (!self->ops->prefix_length) 152 return ENOTSUP; 153 154 int rc = bithenge_transform_prefix_length(self, scope, blob, out_size); 155 if (rc != EOK) 156 return rc; 157 bithenge_node_t *prefix_blob; 158 bithenge_blob_inc_ref(blob); 159 rc = bithenge_new_subblob(&prefix_blob, blob, 0, *out_size); 160 if (rc != EOK) 161 return rc; 162 rc = bithenge_transform_apply(self, scope, prefix_blob, out_node); 163 bithenge_node_dec_ref(prefix_blob); 164 return rc; 67 165 } 68 166 … … 471 569 size_t index) 472 570 { 473 aoff64_t start_pos , end_pos;571 aoff64_t start_pos; 474 572 int rc = struct_node_field_offset(self, &start_pos, index); 475 573 if (rc != EOK) 476 574 return rc; 477 rc = struct_node_field_offset(self, &end_pos, index + 1); 478 if (rc != EOK) 479 return rc; 480 481 bithenge_node_t *blob_node; 482 bithenge_blob_inc_ref(self->blob); 483 rc = bithenge_new_subblob(&blob_node, self->blob, start_pos, 484 end_pos - start_pos); 485 if (rc != EOK) 486 return rc; 487 488 rc = bithenge_transform_apply( 489 self->transform->subtransforms[index].transform, &self->scope, 490 blob_node, out); 491 bithenge_node_dec_ref(blob_node); 492 if (rc != EOK) 493 return rc; 575 576 if (index == self->num_ends) { 577 /* We can apply the subtransform and cache its prefix length at 578 * the same time. */ 579 bithenge_node_t *blob_node; 580 bithenge_blob_inc_ref(self->blob); 581 rc = bithenge_new_offset_blob(&blob_node, self->blob, 582 start_pos); 583 if (rc != EOK) 584 return rc; 585 586 aoff64_t size; 587 rc = bithenge_transform_prefix_apply( 588 self->transform->subtransforms[index].transform, 589 &self->scope, bithenge_node_as_blob(blob_node), out, 590 &size); 591 bithenge_node_dec_ref(blob_node); 592 if (rc != EOK) 593 return rc; 594 595 self->ends[self->num_ends++] = start_pos + size; 596 } else { 597 aoff64_t end_pos; 598 int rc = struct_node_field_offset(self, &end_pos, index + 1); 599 if (rc != EOK) 600 return rc; 601 602 bithenge_node_t *blob_node; 603 bithenge_blob_inc_ref(self->blob); 604 rc = bithenge_new_subblob(&blob_node, self->blob, start_pos, 605 end_pos - start_pos); 606 if (rc != EOK) 607 return rc; 608 609 rc = bithenge_transform_apply( 610 self->transform->subtransforms[index].transform, 611 &self->scope, blob_node, out); 612 bithenge_node_dec_ref(blob_node); 613 if (rc != EOK) 614 return rc; 615 } 494 616 495 617 return EOK; … … 692 814 } 693 815 816 static int struct_transform_prefix_apply(bithenge_transform_t *base, 817 bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_node_t **out_node, 818 aoff64_t *out_size) 819 { 820 struct_transform_t *self = transform_as_struct(base); 821 int rc = struct_transform_make_node(self, out_node, scope, blob, 822 true); 823 if (rc != EOK) 824 return rc; 825 826 rc = struct_node_field_offset(node_as_struct(*out_node), out_size, 827 self->num_subtransforms); 828 if (rc != EOK) { 829 bithenge_node_dec_ref(*out_node); 830 return rc; 831 } 832 833 return EOK; 834 } 835 694 836 static void free_subtransforms(bithenge_named_transform_t *subtransforms) 695 837 { … … 711 853 .apply = struct_transform_apply, 712 854 .prefix_length = struct_transform_prefix_length, 855 .prefix_apply = struct_transform_prefix_apply, 713 856 .destroy = struct_transform_destroy, 714 857 }; -
uspace/app/bithenge/transform.h
r47a728e1 rcb4a66d2 57 57 } bithenge_scope_t; 58 58 59 /** Operations that may be provided by a transform. */ 59 /** Operations that may be provided by a transform. All transforms must provide 60 * apply and/or prefix_apply. To be used in struct transforms and repeat 61 * transforms, transforms must provide prefix_length and/or prefix_apply. */ 60 62 typedef struct bithenge_transform_ops { 61 63 /** @copydoc bithenge_transform_t::bithenge_transform_apply */ … … 65 67 int (*prefix_length)(bithenge_transform_t *self, 66 68 bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out); 69 /** @copydoc bithenge_transform_t::bithenge_transform_prefix_apply */ 70 int (*prefix_apply)(bithenge_transform_t *self, 71 bithenge_scope_t *scope, bithenge_blob_t *blob, 72 bithenge_node_t **out_node, aoff64_t *out_size); 67 73 /** Destroy the transform. 68 74 * @param self The transform. */ … … 191 197 assert(self); 192 198 return self->num_params; 193 }194 195 /** Apply a transform. Takes ownership of nothing.196 * @memberof bithenge_transform_t197 * @param self The transform.198 * @param scope The scope.199 * @param in The input tree.200 * @param[out] out Where the output tree will be stored.201 * @return EOK on success or an error code from errno.h. */202 static inline int bithenge_transform_apply(bithenge_transform_t *self,203 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)204 {205 assert(self);206 assert(self->ops);207 return self->ops->apply(self, scope, in, out);208 }209 210 /** Find the length of the prefix of a blob this transform can use as input. In211 * other words, figure out how many bytes this transform will use up. This212 * method is optional and can return an error, but it must succeed for struct213 * subtransforms. Takes ownership of nothing.214 * @memberof bithenge_transform_t215 * @param self The transform.216 * @param scope The scope.217 * @param blob The blob.218 * @param[out] out Where the prefix length will be stored.219 * @return EOK on success, ENOTSUP if not supported, or another error code from220 * errno.h. */221 static inline int bithenge_transform_prefix_length(bithenge_transform_t *self,222 bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)223 {224 assert(self);225 assert(self->ops);226 if (!self->ops->prefix_length)227 return ENOTSUP;228 return self->ops->prefix_length(self, scope, blob, out);229 199 } 230 200 … … 269 239 int bithenge_init_transform(bithenge_transform_t *, 270 240 const bithenge_transform_ops_t *, int); 241 int bithenge_transform_apply(bithenge_transform_t *, bithenge_scope_t *, 242 bithenge_node_t *, bithenge_node_t **); 243 int bithenge_transform_prefix_length(bithenge_transform_t *, 244 bithenge_scope_t *, bithenge_blob_t *, aoff64_t *); 245 int bithenge_transform_prefix_apply(bithenge_transform_t *, bithenge_scope_t *, 246 bithenge_blob_t *, bithenge_node_t **, aoff64_t *); 271 247 int bithenge_new_param_transform(bithenge_transform_t **, 272 248 bithenge_transform_t *, int);
Note:
See TracChangeset
for help on using the changeset viewer.