/* The Dano Message Format0. DisclaimerThe information herein is based on reverse engeneering flattened BMessages.The conclusions might be wrong in the details, and an implementation canprobably not be drawn right from this description, but the overall formatdescribed here should come close to the one found on Dano based systems.1. ConceptIn the Dano message format, data is kept in a flat buffer and is organisedin multiple "sections". Each section has a header that identifies the typeof the section and it's size. Each section contains a field that then holdsmore information on the data and the data itself. Everything is usuallypadded to 8 byte boundaries.2. Section HeadersThe section header looks like this:typedef struct section_header_s {int32 code;ssize_t size;uint8 data[0];} SectionHeader;The code identifies the type of the data following the header. Valid typesare the following:enum {SECTION_MESSAGE_HEADER = 'FOB2',SECTION_OFFSET_TABLE = 'STof',SECTION_TARGET_INFORMATION = 'ENwh',SECTION_SINGLE_ITEM_DATA = 'SGDa'SECTION_FIXED_SIZE_ARRAY_DATA = 'FADa',SECTION_VARIABLE_SIZE_ARRAY_DATA = 'VADa',SECTION_SORTED_INDEX_TABLE = 'DXIn',SECTION_END_OF_DATA = 'DDEn'};The size field includes the size of the header itself and its data.3. Message Header SectionThe message header section stores the what field of the message. Its code,conveniently at the very first 4 bytes, also identifies the message as aDano message ('FOB2'). The layout is as follows:typedef struct message_header_s {int32 what;int32 padding;} MessageHeader;4. Offset Table SectionThe offset table stores the byte offsets to the sorted index table and tothe end of data section. It looks like this:typedef struct offset_table_s {int32 indexTable;int32 endOfData;int64 padding;} OffsetTable;The index table offset is important since we will usually insert new fieldsbefore the index table. The end of data offset can be used to directlyknow where the index table ends. It's also possible that the end of indexoffset is actually the end of the index table.Both offsets are based on the beginning of the first data section and notfrom the top of the message.5. Single Item Data SectionThe single item data section holds information on exactly one data item.Since when only dealing with one item it doesn't matter wether it is fixedsize or not we do not distinct between these two types. The format is asfollows:typedef struct single_item_s {type_code type;ssize_t itemSize;uint8 nameLength;char name[0];} SingleItem;The the name is padded to the next 8 byte boundary. After nameLength + 1bytes the item data begins. The nameLength field does not count theterminating 0 of the name, but the name is actually 0 terminated.6. Fixed Size Item Array DataThis type of section holds an array of fixed size items. Describing theformat of this section in a struct is a bit harder, since the countvariable is stored after the name field. In pseudo code it would look likethis:typedef struct fixed_size_s {type_code type;ssize_t sizePerItem;uint8 nameLength;char name[pad_to_8(nameLength + 1)];int32 count;int32 padding;uint8 data[0];} FixedSize;7. Variable Sized Item Array DataThe format is very similar to the one of the fixed size item array above.Again in pseudo code:typedef struct variable_size_s {type_code type;int32 padding;uint8 nameLength;char name[pad_to_8(nameLength + 1)];int32 count;ssize_t totalSize;uint8 data[0];} VariableSize;The data itself is constructed of the variable sized items, each padded toan eight byte boundary. Where they begin and where they end is not encodedin the data itself but in an "endpoint table" following the data (at data+ totalSize). The endpoint table is an array of int32 items each pointingto the end of an item (not including padding). As an example we take anarray of three variable sized items layouted like this:<data>76 61 72 69 61 62 6c 65 variable20 73 69 7a 65 64 20 64 sized d61 74 61 00 00 00 00 00 ata..... (pad)61 72 69 61 62 6c 65 20 ariable73 69 7a 65 64 20 64 61 sized da74 61 00 00 00 00 00 00 ta...... (pad)6c 61 73 74 20 69 6e 20 last in74 68 69 73 20 61 72 72 this arr61 79 21 00 00 00 00 00 ay!..... (pad)</data>Then the endpoint table would look like this:<endPointTable><endPoint 20 /><endPoint 43 /><endPoint 68 /><endPointTable>The first endpoint (20) means that the size of the first item is 20 bytes.The second endpoint (43) is constructed from the start of the second itemwhich is at pad_to_8(endpoint[0]) plus the size of the item. In this casepad_to_8(endpoint[0]) results in 24, this is where the second item begins.So 43 - 24 gives us the unpadded length of item 2 (19). The third itemstarts at pad_to_8(endpoint[1]) and is in our case 48. The length of itemthree is therefor 68 - 48 = 20 bytes. Note that in this example we aretalking about strings where the 0 termination is included in the item size.8. Sorted Index TableThe sorted index table is a list of direct offsets to the fields. It isbinary sorted using the field names. This means that we can use it forname lookups with a O(log(n)) complexity instead of doing linear searches.The section data is composed directly out of the int32 array of offsets.No extra data is stored in this section. All offsets have the first datasection as their base.9. End Of Data SectionThis section terminates the section stream. No other data is stored in thissection.10. Target Information SectionThe target information section is used to hold the target team, handler,port information for message delivery. As this data is not relevant whenhandling disk stored messages only, the format of this section is notdiscussed here.*/