代码之家  ›  专栏  ›  技术社区  ›  LukeN

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

  •  4
  • LukeN  · 技术社区  · 14 年前

    我想为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
      • 0x00 0x0b =名称长度为11个字符
    • 0x08 =标记字符串
      • 0x00 0x04
      • 0x00 0x09 =有效负载为9个字符
      • “巴纳拉马”
    • 0x00 =标记结束

    它可以变得越来越复杂,越来越多的嵌套 TAG_Compound 就像树一样。

    现在我的问题不完全是解析格式,它真的很简单。我更想知道我怎样才能更有效率,更重要的是 方便地

    我知道我不能像你这样轻松

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

    但是,在保持易用性的同时,最好的储存方法是什么呢?我想到了一个 nbt_compound nbt_value

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

    1 回复  |  直到 14 年前
        1
  •  1
  •   user414677 user414677    14 年前

    我确信这段代码被破坏了,但我想表达的是这个想法。我想我应该用一个标记对象,比如

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