saturncastle
saturncastle

Reputation: 31

Parsing opcodes with Kaitai Struct

Doing my first steps in Kaitai Struct, I've been trying to do BSON parser as an excercise. My .ksy code that parses BSON element now looks like that:

  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

As you might have noticed, there's lots of repetition. One just have go duplicate if block every time one wants to do additional element type. Even worse, you basically have to duplicate stuff 3 times in every such field, i.e.:

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

My target language is Java. Before Kaitai, I've only tried Preon, and there we had clauses such as:

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

There you automatically get these two elements based on value of "prefix". Is it possible to do it in Kaitai?

Upvotes: 3

Views: 778

Answers (1)

GreyCat
GreyCat

Reputation: 17104

Well, you're right, and this feature was requested like 3 or 4 times already ;) I've filed an issue for that.

I can't agree on Preon's implementation, though, it seems very limited to me. You can have only a single "prefix", it is always integer, and it always must immediately preceed your point of choice.

I want to implement a little more generic switch style statement, something like that:

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

What do you think of that?

Note that chances are that you won't be get the "proper" OOP object hierarchy, though, as you're getting with Preon. This is because Preon's classes are made by hand and you can actually do the common superclass and inherit both FloatNamedElement and UTF8NamedElement from it, but I can't think of a method to do so in current KS model now.

Upvotes: 2

Related Questions