1*99e0aae7SDavid Rees<!-- TODO(bolms): this file could use a review to make sure it is still correct 2*99e0aae7SDavid Rees(as of 2017 December). --> 3*99e0aae7SDavid Rees 4*99e0aae7SDavid Rees# Text Format 5*99e0aae7SDavid Rees 6*99e0aae7SDavid Rees[TOC] 7*99e0aae7SDavid Rees 8*99e0aae7SDavid Rees## Background 9*99e0aae7SDavid Rees 10*99e0aae7SDavid ReesEmboss messages may be automatically converted between a human-readable text 11*99e0aae7SDavid Reesformat and machine-readable bytes. For example, if you have the following 12*99e0aae7SDavid Rees`.emb` file: 13*99e0aae7SDavid Rees 14*99e0aae7SDavid Rees``` 15*99e0aae7SDavid Reesstruct Foo: 16*99e0aae7SDavid Rees 0 [+1] UInt a 17*99e0aae7SDavid Rees 1 [+1] UInt b 18*99e0aae7SDavid Rees 19*99e0aae7SDavid Reesstruct Bar: 20*99e0aae7SDavid Rees 0 [+2] Foo c 21*99e0aae7SDavid Rees 2 [+2] Foo d 22*99e0aae7SDavid Rees``` 23*99e0aae7SDavid Rees 24*99e0aae7SDavid ReesYou may decode a Bar like so: 25*99e0aae7SDavid Rees 26*99e0aae7SDavid Rees```c++ 27*99e0aae7SDavid Reesuint8_t buffer[4]; 28*99e0aae7SDavid Reesauto bar_writer = BarWriter(buffer, sizeof buffer); 29*99e0aae7SDavid Reesbar_writer.UpdateFromText(R"( 30*99e0aae7SDavid Rees { 31*99e0aae7SDavid Rees c: { 32*99e0aae7SDavid Rees a: 12 33*99e0aae7SDavid Rees b: 0x20 # Hex numbers are supported. 34*99e0aae7SDavid Rees } 35*99e0aae7SDavid Rees d: { 36*99e0aae7SDavid Rees a: 33 37*99e0aae7SDavid Rees b: 0b10110011 # ... as are binary. 38*99e0aae7SDavid Rees } 39*99e0aae7SDavid Rees } 40*99e0aae7SDavid Rees)"); 41*99e0aae7SDavid Reesassert(bar_writer.c().a().Read() == 12); 42*99e0aae7SDavid Reesassert(bar_writer.c().b().Read() == 32); 43*99e0aae7SDavid Reesassert(bar_writer.d().a().Read() == 33); 44*99e0aae7SDavid Reesassert(bar_writer.d().b().Read() == 0xb3); 45*99e0aae7SDavid Rees``` 46*99e0aae7SDavid Rees 47*99e0aae7SDavid ReesNote that you can use `#`-style comments inside of the text format. 48*99e0aae7SDavid Rees 49*99e0aae7SDavid ReesIt is also acceptable to omit fields, in which case they will not be updated: 50*99e0aae7SDavid Rees 51*99e0aae7SDavid Rees```c++ 52*99e0aae7SDavid Reesbar_writer.UpdateFromText("d { a: 123 }"); 53*99e0aae7SDavid Reesassert(bar_writer.c().a().Read() == 12); 54*99e0aae7SDavid Reesassert(bar_writer.d().a().Read() == 123); 55*99e0aae7SDavid Rees``` 56*99e0aae7SDavid Rees 57*99e0aae7SDavid ReesBecause Emboss does not enforce dependencies or duplicate field sets in 58*99e0aae7SDavid Rees`UpdateFromText`, it is currently possible to do something like this: 59*99e0aae7SDavid Rees 60*99e0aae7SDavid Rees``` 61*99e0aae7SDavid Rees# memory_selector.emb 62*99e0aae7SDavid Reesstruct MemorySelector: 63*99e0aae7SDavid Rees 0 [+1] UInt addr 64*99e0aae7SDavid Rees addr [+1] UInt:8 byte 65*99e0aae7SDavid Rees``` 66*99e0aae7SDavid Rees 67*99e0aae7SDavid Rees```c++ 68*99e0aae7SDavid Rees// memory_select_writer.cc 69*99e0aae7SDavid Reesuint8_t buffer[4]; 70*99e0aae7SDavid Reesauto memory_writer = MemoryWriter(buffer, sizeof buffer); 71*99e0aae7SDavid Reesmemory_writer.UpdateFromText(R"( 72*99e0aae7SDavid Rees { 73*99e0aae7SDavid Rees addr: 1 74*99e0aae7SDavid Rees byte: 10 75*99e0aae7SDavid Rees addr: 2 76*99e0aae7SDavid Rees byte: 20 77*99e0aae7SDavid Rees addr: 3 78*99e0aae7SDavid Rees byte: 30 79*99e0aae7SDavid Rees addr: 0 80*99e0aae7SDavid Rees } 81*99e0aae7SDavid Rees)"); 82*99e0aae7SDavid Reesassert(buffer[1] == 10); 83*99e0aae7SDavid Reesassert(buffer[2] == 20); 84*99e0aae7SDavid Reesassert(buffer[3] == 30); 85*99e0aae7SDavid Reesassert(buffer[0] == 0); 86*99e0aae7SDavid Rees``` 87*99e0aae7SDavid Rees 88*99e0aae7SDavid Rees*Do not rely on this behavior.* A future version of Emboss may add tracking to 89*99e0aae7SDavid Reesensure that this example is an error. 90*99e0aae7SDavid Rees 91*99e0aae7SDavid Rees 92*99e0aae7SDavid Rees## Text Format Details 93*99e0aae7SDavid Rees 94*99e0aae7SDavid ReesThe exact text format accepted by an Emboss view depends on the view type. 95*99e0aae7SDavid ReesExtra whitespace is ignored between tokens. Any place where whitespace is 96*99e0aae7SDavid Reesallowed, the `#` character denotes a comment which extends to the end of the 97*99e0aae7SDavid Reesline. 98*99e0aae7SDavid Rees 99*99e0aae7SDavid Rees 100*99e0aae7SDavid Rees### `struct` and `bits` 101*99e0aae7SDavid Rees 102*99e0aae7SDavid ReesThe text format of a `struct` or `bits` is a sequence of name/value pairs 103*99e0aae7SDavid Reessurrounded by braces, where field names are separated from field values by 104*99e0aae7SDavid Reescolons: 105*99e0aae7SDavid Rees 106*99e0aae7SDavid Rees { 107*99e0aae7SDavid Rees field_name: FIELD_VALUE 108*99e0aae7SDavid Rees field_name_2: FIELD_VALUE_2 109*99e0aae7SDavid Rees substructure: { 110*99e0aae7SDavid Rees subfield: 123 111*99e0aae7SDavid Rees } 112*99e0aae7SDavid Rees } 113*99e0aae7SDavid Rees 114*99e0aae7SDavid ReesOnly fields which are actually listed in the text will be set. 115*99e0aae7SDavid Rees 116*99e0aae7SDavid ReesIf a field's address depends on another field's value, then the order in which 117*99e0aae7SDavid Reesthey are listed in the text format becomes important. When setting both, 118*99e0aae7SDavid Reesalways make sure to set the dependee field before the dependent field. 119*99e0aae7SDavid Rees 120*99e0aae7SDavid ReesIt is currently possible to specify a field more than once, but this may not be 121*99e0aae7SDavid Reessupported in the future. 122*99e0aae7SDavid Rees 123*99e0aae7SDavid Rees 124*99e0aae7SDavid Rees### `UInt` and `Int` 125*99e0aae7SDavid Rees 126*99e0aae7SDavid Rees`UInt`s and `Int`s accept numeric values in the same formats that are allowed 127*99e0aae7SDavid Reesin Emboss source files: 128*99e0aae7SDavid Rees 129*99e0aae7SDavid Rees 123456 130*99e0aae7SDavid Rees 123_456 131*99e0aae7SDavid Rees 0x1234cdef 132*99e0aae7SDavid Rees 0x1234_cdef 133*99e0aae7SDavid Rees 0b10100101 134*99e0aae7SDavid Rees 0b1010_0101 135*99e0aae7SDavid Rees -123 136*99e0aae7SDavid Rees -0b111 137*99e0aae7SDavid Rees 138*99e0aae7SDavid Rees 139*99e0aae7SDavid Rees### `Flag` 140*99e0aae7SDavid Rees 141*99e0aae7SDavid Rees`Flag`s expect either `true` or `false`. 142*99e0aae7SDavid Rees 143*99e0aae7SDavid Rees 144*99e0aae7SDavid Rees### `enum` 145*99e0aae7SDavid Rees 146*99e0aae7SDavid ReesAn `enum`'s value may be either a name listed in the enum definition, or a 147*99e0aae7SDavid Reesnumeric value: 148*99e0aae7SDavid Rees 149*99e0aae7SDavid Rees FOO 150*99e0aae7SDavid Rees 2 151*99e0aae7SDavid Rees 100 152*99e0aae7SDavid Rees 153*99e0aae7SDavid Rees 154*99e0aae7SDavid Rees### Arrays 155*99e0aae7SDavid Rees 156*99e0aae7SDavid ReesAn array is a list of values (in the appropriate format for the type of the 157*99e0aae7SDavid Reesarray), separated by commas and surrounded by braces. Values may be optionally 158*99e0aae7SDavid Reesprefixed with index markers of the form `[0]:`, where `0` may be any unsigned 159*99e0aae7SDavid Reesinteger. An extra comma at the end of the list is allowed, but not required: 160*99e0aae7SDavid Rees 161*99e0aae7SDavid Rees { 0, 1, 2, 3, 4, 5, 6, 7 } 162*99e0aae7SDavid Rees { 0, 1, 2, 3, 4, 5, 6, 7, } 163*99e0aae7SDavid Rees { 0, 1, 2, 3, 4, [7]: 7, [6]: 6, [5]: 5 } 164*99e0aae7SDavid Rees 165*99e0aae7SDavid ReesWhen no index marker is specified, values are written to the index which is one 166*99e0aae7SDavid Reesgreater than the previous value's index: 167*99e0aae7SDavid Rees 168*99e0aae7SDavid Rees { [4]: 4, 5, 6, 7, [0]: 0, 1, 2, 3 } 169*99e0aae7SDavid Rees 170*99e0aae7SDavid ReesIt is currently possible to specify multiple values for a single index, but 171*99e0aae7SDavid Reesthis may not be supported in the future. 172*99e0aae7SDavid Rees 173*99e0aae7SDavid Rees*TODO(bolms): In the future section about creating new `external` types, make 174*99e0aae7SDavid Reessure to note that the `external`'s text format should not start with `[` or 175*99e0aae7SDavid Rees`}`.* 176*99e0aae7SDavid Rees 177*99e0aae7SDavid Rees 178*99e0aae7SDavid Rees 179