我想为NBT(命名二进制标记)结构编写解析器。格式如下所示:
TAG_Compound("hello world"): 1 entries
{
TAG_String("name"): Bananrama
}
在内存中(或存储在其中的文件)为十六进制视图:
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个字符0x08
= TAG_String
0x00 0x04
=名称长度为4个字符0x00 0x09
=有效负载为9个字符0x00
= TAG_End 越来越多的嵌套TAG_Compound
就像树结构一样,它会变得更复杂。
现在我的问题并不是解析格式,这很简单。我想知道如何有效,更重要的是方便地存储它以供以后使用。
我知道我不能像
那样获得一定程度的轻松tags["hello world"]["name"] = "Bananrama"
但是什么是保存它易于使用的最佳方式?我考虑过nbt_compound
结构(因为每个NBT树至少有一个根化合物),让它存储它有多少个子节点,并包含一个nbt_value
结构数组,用于存储类型和内容那个价值。这是个好主意吗?
编辑:可以看到完整的规范here
答案 0 :(得分:1)
我确信这段代码已被破坏,但这个想法正是我想要传达的。我想我会使用Tag对象,比如
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;
}
有一个功能,比如
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;
}
然后访问它:
get_value(get_value(root, "Hello World"), "name");