存储数据结构的有效且简单的方法是什么?

时间:2010-08-08 22:32:31

标签: c data-structures

我想为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个字符
    • “Bananarama”
  • 0x00 = TAG_End

越来越多的嵌套TAG_Compound就像树结构一样,它会变得更复杂。

现在我的问题并不是解析格式,这很简单。我想知道如何有效,更重要的是方便地存储它以供以后使用。

我知道我不能像

那样获得一定程度的轻松
tags["hello world"]["name"] = "Bananrama"

但是什么是保存它易于使用的最佳方式?我考虑过nbt_compound结构(因为每个NBT树至少有一个根化合物),让它存储它有多少个子节点,并包含一个nbt_value结构数组,用于存储类型和内容那个价值。这是个好主意吗?

编辑:可以看到完整的规范here

1 个答案:

答案 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");