155 | | order. The transform `ascii <- zero_terminated` |
156 | | first removes the 0x00 from the end of the blob, then decodes it as ascii. Note |
157 | | that the order of composition is consistent with function composition and |
158 | | nested application in mathematics, and also consistent with the general idea |
159 | | that data moves from right to left as it is decoded. |
| 155 | order. The transform `ascii <- zero_terminated` first removes the 0x00 from the |
| 156 | end of the blob, then decodes it as ascii. Note that the order of composition |
| 157 | is consistent with function composition and nested application in mathematics, |
| 158 | and also consistent with the general idea that data moves from right to left as |
| 159 | it is decoded. |
| 160 | |
| 161 | Transforms can have parameters that affect how they decode data: |
| 162 | `transform u16(little_endian) = if (little_endian) { uint16le } else { uint16be };`. |
| 163 | When such a transform is used, expressions must be given to calculate its |
| 164 | parameters. Currently, the only possible expressions are parameters given to |
| 165 | the current transform, boolean and integer literals, and previously decoded |
| 166 | fields in the current `struct`: |
| 167 | {{{ |
| 168 | transform item(little_endian) = struct { |
| 169 | .len <- u16(little_endian); |
| 170 | .text <- ascii <- known_length(.len); |
| 171 | .data <- known_length(8); |
| 172 | }; |
| 173 | }}} |
| 218 | === Using the API === |
| 219 | |
| 220 | An overview of the API will be written later. |
| 221 | |
| 222 | Nodes, expressions, and transforms use reference counting. Functions that |
| 223 | produce such objects (through a `bithenge_xxx_t **` argument) create a new |
| 224 | reference to the object; you are responsible for ensuring the reference count |
| 225 | is eventually decremented. If a function’s documentation says it “takes |
| 226 | [ownership of] a reference” to an object, the function guarantees the object’s |
| 227 | reference count will eventually be decremented, even if an error occurs. |
| 228 | Therefore, if you create an object only to immediately pass it to such a |
| 229 | function, you do not need to worry about its reference count. |
| 230 | |
207 | | |
208 | | === Transform parameters === |
209 | | |
210 | | Currently, a transform can only have one input. Parameters will allow a |
211 | | transform to use multiple inputs: |
212 | | {{{ |
213 | | transform strings(len) = struct { |
214 | | .str1 <- ascii <- known_length(len); |
215 | | .str2 <- ascii <- known_length(len); |
216 | | }; |
217 | | }}} |
218 | | A transform with parameters can be defined as in `transform strings(len)`, and |
219 | | the parameters can be referenced inside the transform. When a transform is |
220 | | used, expressions are given for the values of its parameters. |
221 | | |
222 | | At first the only expressions will be parameters, as above, integer literals or previously decoded |
223 | | fields, as in |
224 | | {{{ |
225 | | .len <- uint32le; |
226 | | .data <- known_length(.len); |
227 | | }}} |