| 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 | | }}} |