What is an efficient and easy way to store a data structure?

I want to write a parser for NBT structures (Named Binary Labels). The format is as follows:

TAG_Compound("hello world"): 1 entries { TAG_String("name"): Bananrama } 

And in memory (or a file stored in it) as a hexadecimal representation:

 0000000: 0a 00 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 08 00 ...hello world.. 0000010: 04 6e 61 6d 65 00 09 42 61 6e 61 6e 72 61 6d 61 .name..Bananrama 0000020: 00 . 
  • 0x0a = TAG_Compound
    • 0x00 0x0b = 11 character name
    • "Hello World"
  • 0x08 = TAG_String
    • 0x00 0x04 = 4 character name
    • "name"
    • 0x00 0x09 = payload - 9 characters
    • "Bananarama"
  • 0x00 = TAG_End

This can get complicated with the more and more nested TAG_Compound as a tree structure.

Now my question is not really about parsing the format, it is very simple. I would like to know how I can effectively and, more importantly, save it for later use.

I know that I can’t get such ease as

 tags["hello world"]["name"] = "Bananrama" 

But what is the best way to store it while keeping it easy to use? I was thinking about the nbt_compound structure (because each NBT tree has at least one root connection), let it store the number of children and contain an array of nbt_value structures that will store the type and contents of this value. Is that a good idea?

Edit: full specification can be seen here

+4
source share
1 answer

I'm sure this code is broken, but the idea is what I'm trying to convey. I think I would use a Tag object like

 struct TagHeader { TagType type; // Enum of COMPOUND, STRING, etc char *name; } struct TagCompound { TagHeader header; int nelems; void *children; } struct TagString { TagHeader hearder; char *value; } 

Using a function like

 void *get_value(void *root, char *name) { int i; if (! root) return NULL; if (((TagHeader *) root)->type == COMPOUND) { TagCompound *c = (TagCompound *)root; for (i = 0; i < c->nelems; i++) { if (strcmp(((TagHeader *) c->values[i])->name, name) == 0) { return c->values[i]; } } return NULL; } else if ( /* handle other tag Types */ ) { } return NULL; } 

Then enter it like this:

 get_value(get_value(root, "Hello World"), "name"); 
+1
source

All Articles