| 134 | | ||ascii ||blob node ||string ||decodes some bytes as ASCII characters || `hex:6869` becomes `"hi"` || |
| 135 | | ||uint8 ||1‐byte blob node ||integer node ||decodes a 1‐byte unsigned integer || `hex:11` becomes `17` || |
| 136 | | ||uint16be ||2‐byte blob node ||integer node ||decodes a 2‐byte big‐endian unsigned integer || `hex:0201` becomes `513` || |
| 137 | | ||uint16le ||2‐byte blob node ||integer node ||decodes a 2‐byte little‐endian unsigned integer || `hex:0101` becomes `257` || |
| 138 | | ||uint32be ||4‐byte blob node ||integer node ||decodes a 4‐byte big‐endian unsigned integer || `hex:00000201` becomes `513` || |
| 139 | | ||uint32le ||4‐byte blob node ||integer node ||decodes a 4‐byte little‐endian unsigned integer || `hex:01010000` becomes `257` || |
| 140 | | ||uint64be ||8‐byte blob node ||integer node ||decodes a 8‐byte big‐endian unsigned integer || `hex:0000000000000201` becomes `513` || |
| 141 | | ||uint64le ||8‐byte blob node ||integer node ||decodes a 8‐byte little‐endian unsigned integer || `hex:0101000000000000` becomes `257` || |
| 142 | | ||zero_terminated ||blob node ||blob node ||takes bytes up until the first `00` || `hex:7f0400` becomes `hex:7f04` || |
| | 134 | ||ascii ||blob node ||string ||decodes some bytes as ASCII characters || `hex:6869` becomes `"hi"` || |
| | 135 | ||known_length(len) ||blob node ||blob node ||requires the input to have a known length || || |
| | 136 | ||nonzero_boolean ||integer ||boolean ||decodes a boolean where nonzero values are true || `0` becomes `false` || |
| | 137 | ||uint8 ||1‐byte blob node ||integer node ||decodes a 1‐byte unsigned integer || `hex:11` becomes `17` || |
| | 138 | ||uint16be ||2‐byte blob node ||integer node ||decodes a 2‐byte big‐endian unsigned integer || `hex:0201` becomes `513` || |
| | 139 | ||uint16le ||2‐byte blob node ||integer node ||decodes a 2‐byte little‐endian unsigned integer || `hex:0101` becomes `257` || |
| | 140 | ||uint32be ||4‐byte blob node ||integer node ||decodes a 4‐byte big‐endian unsigned integer || `hex:00000201` becomes `513` || |
| | 141 | ||uint32le ||4‐byte blob node ||integer node ||decodes a 4‐byte little‐endian unsigned integer || `hex:01010000` becomes `257` || |
| | 142 | ||uint64be ||8‐byte blob node ||integer node ||decodes a 8‐byte big‐endian unsigned integer || `hex:0000000000000201` becomes `513` || |
| | 143 | ||uint64le ||8‐byte blob node ||integer node ||decodes a 8‐byte little‐endian unsigned integer || `hex:0101000000000000` becomes `257` || |
| | 144 | ||zero_terminated ||blob node ||blob node ||takes bytes up until the first `00` || `hex:7f0400` becomes `hex:7f04` || |
| | 211 | == Flow Control == |
| | 212 | |
| | 213 | Boolean conditions can use |
| | 214 | `if (expression) { transform-if-true } else { transform-if-false }`, for |
| | 215 | example: `if (little_endian) { uint32le } else { uint32be }`. There is also |
| | 216 | syntax for switches: `switch (expression) { expression: transform; ... }`. Both |
| | 217 | of these have syntactic sugar for use in `struct`s; in a `struct`, |
| | 218 | `if (expression) { fields... }` is equivalent to |
| | 219 | `<- if (expression) { struct { fields... } };`. |
| | 220 | |
| | 221 | Three kinds of repetition are supported. `repeat(expression) {transform}` |
| | 222 | applies the transform a given number of times. `repeat {transform}` applies the |
| | 223 | transform until it fails or the end of the data is reached. |
| | 224 | `do {transform} while(expression)` applies the transform until the expression, |
| | 225 | evaluated within the result of the transform, is false; this can be used for |
| | 226 | things like |
| | 227 | `do { struct { .keep_going <- nonzero_boolean <- uint8; .val <- uint8; } } while(.keep_going)`. |
| | 228 | For each type of repetition, the result is an internal node with sequential |
| | 229 | keys starting at `0`. |
| | 230 | |