When saving a ds_map
object using ds_map_write
, it gets serialized to a string. I found no documentation anywhere about the format of this string, so I decided to reverse engineer it.
The string consists of hexadecimal numbers representing an array of bytes. For example, "CAFEBABE"
would represent the array [0xCA, 0xFE, 0xBA, 0xBE]
.
This array of bytes represents data in a custom format.
All serialized ds_map
objects follow the structure below:
Data | Size | Type |
---|---|---|
Magic number | 4 bytes | Integer (402) |
Number of entries | 4 bytes | Integer |
Entry 1 | Variable | Entry |
Entry 2 | Variable | Entry |
... | ||
Entry n | Variable | Entry |
Each entry follows the format below:
Data | Size | Type |
---|---|---|
Key | Variable | Object |
Value | Variable | Object |
There are two types of objects: numbers and strings.
Data | Size | Type |
---|---|---|
Type | 4 bytes | Integer (0) |
Value | 8 bytes | IEEE754 Double precision |
Data | Size | Type |
---|---|---|
Type | 4 bytes | Integer (1) |
Length | 4 bytes | Integer |
Value | Variable | ASCII string |
All integers and doubles are stored in little-endian order.
Suppose we serialize the following ds_map
:
map = ds_map_create();
ds_map_add(map, "random", 4);
ds_map_add(map, "universe", 42);
ds_map_add(map, 3.14, "pi");
show_debug_message(ds_map_write(map));
The output is the following:
9201000003000000010000000600000072616E646F6D000000000000000000001040000000001F85EB51B81E0940010000000200000070690100000008000000756E697665727365000000000000000000004540
Now, let's parse the bytes following the format specification previously described.
Data | Raw bytes | Value |
---|---|---|
Magic number | 92 01 00 00 | 402 |
Number of entries | 03 00 00 00 | 3 |
Data | Raw bytes | Value |
---|---|---|
Type | 01 00 00 00 | 1 (string) |
Length | 06 00 00 00 | 6 |
Value | 72 61 6E 64 6F 6D | random |
Data | Raw bytes | Value |
---|---|---|
Type | 00 00 00 00 | 0 (number) |
Value | 00 00 00 00 00 00 10 40 | 4 |
Data | Raw bytes | Value |
---|---|---|
Type | 00 00 00 00 | 0 (number) |
Value | 1F 85 EB 51 B8 1E 09 40 | 3.14 |
Data | Raw bytes | Value |
---|---|---|
Type | 01 00 00 00 | 1 (string) |
Length | 02 00 00 00 | 2 |
Value | 70 69 | pi |
Data | Raw bytes | Value |
---|---|---|
Type | 01 00 00 00 | 1 (string) |
Length | 08 00 00 00 | 8 |
Value | 75 6E 69 76 65 72 73 65 | universe |
Data | Raw bytes | Value |
---|---|---|
Type | 00 00 00 00 | 0 (number) |
Value | 00 00 00 00 00 00 45 40 | 42 |
As you can see, the original ds_map
has been correctly deserialized!