3

在 Kaitai Struct 中迈出第一步,我一直在尝试将 BSON 解析器作为练习。我解析 BSON 元素的 .ksy 代码现在看起来像这样:

  element:
    seq:
      - id: el_type
        type: u1
        enum: bson_type
      - id: el_name
        type: strz
        encoding: UTF-8
        if: el_type != bson_type::end_of_document
      - id: el_string
        type: bson_string
        if: el_type == bson_type::string
      - id: el_document
        type: bson_document
        if: el_type == bson_type::document
      - id: el_boolean
        type: u1
        if: el_type == bson_type::boolean
      - id: el_int32
        type: s4
        if: el_type == bson_type::int32
      - id: el_int64
        type: s4
        if: el_type == bson_type::int64
enums:
  bson_type:
    0: end_of_document
    1: double
    2: string
    3: document
    8: boolean
    0x10: int32
    0x12: int64

您可能已经注意到,有很多重复。if每当一个人想要做额外的元素类型时,就需要去重复块。更糟糕的是,您基本上必须在每个此类字段中复制 3 次内容,即:

  - id: el_string                    # <= string!
    type: bson_string                # <= string!
    if: el_type == bson_type::string # <= string!

我的目标语言是Java。在 Kaitai 之前,我只尝试过 Preon,我们有这样的子句:

@Choices(prefixSize = 8, alternatives = {
    @Choice(condition = "prefix==0x01", type = FloatNamedElement.class),
    @Choice(condition = "prefix==0x02", type = UTF8NamedElement.class)
}
private NamedElement elements;

在那里,您会根据“前缀”的值自动获取这两个元素。在开泰可以吗?

4

1 回答 1

2

好吧,你是对的,这个功能已经被请求了 3 到 4 次;)我已经为此提出了问题

不过,我不能同意 Preon 的实施,但这对我来说似乎非常有限。您只能有一个“前缀”,它始终是整数,并且它必须始终紧接在您的选择点之前。

我想实现一个更通用的switch样式声明,比如:

  - id: value
    switch: code
    cases:
      string:
        type: bson_string
      document:
        type: bson_document
      boolean:
        type: u1
      int32:
        type: s4
      int64:
        type: s8

你对那个怎么想的?

请注意,您可能不会获得“正确的”OOP 对象层次结构,因为您正在使用 Preon。这是因为 Preon 的类是手工制作的,你实际上可以做公共超类并从它继承两者FloatNamedElementUTF8NamedElement但我现在想不出在当前 KS 模型中这样做的方法。

于 2016-07-22T09:30:15.053 回答