kaitai_struct icon indicating copy to clipboard operation
kaitai_struct copied to clipboard

switch-on for enum

Open tannewt opened this issue 1 year ago • 5 comments

USB device and interface descriptors have class, subclass and protocol fields where the meaning of subclass depends on the value of class and the meaning of protocol depends on subclass. It'd be great if you could:

- id: class
  type: u1
  enum: interface_class
- id: subclass
  type: u1
  enum:
    switch-on: class
    cases:
      'interface_class::human_interface_device': hid_subclass

It'd work just like switch-on under type but for enums instead.

Thanks!

tannewt avatar Jul 06 '23 22:07 tannewt

Can you elaborate a little bit more — e.g. what output do you expect from a compiler in such cases? Looks like all class-dependent subclasses effectively form their own separate types (enum)?

GreyCat avatar Jul 06 '23 22:07 GreyCat

I'm only using the web ide at the moment so I'm only looking to have the values annotate appropriately there. (Right now I cheated and only used the hid_subclass enum type.)

In code, I'd expect a separate enum type that was unioned for the original value.

tannewt avatar Jul 06 '23 22:07 tannewt

Full ksy I have so far is here: https://gist.github.com/tannewt/4c03dfe354c5d979720c7167730554b3

sample_usb_descriptors.zip

tannewt avatar Jul 06 '23 22:07 tannewt

As a work-around, I tried to switch-on types instead, but I encountered the following issue:

meta:
  id: test_id
  bit-endian: be
seq:
  - id: header
    type: header
    doc: This is header
types:
  header:
    seq:
      - id: cmd_class
        type: u1
        enum: enum_cmd_class
      - id: cmd_id
        size: 1
        type: cmd_id
  cmd_id:
    seq:
      - id: direction
        type: b1be
        enum: enum_direction
      - id: id
        type:
          switch-on: _parent.cmd_class
          cases:
            enum_cmd_class::a: cmd_id_a
            enum_cmd_class::b: cmd_id_b
  cmd_id_a:
    seq:
      - id: id
        type: b7be
        enum: enum_a
  cmd_id_b:
    seq:
      - id: id
        type: b7be
        enum: enum_b
enums:
  enum_direction:
    0: left
    1: right
  enum_cmd_class:
    0: a
    1: b
  enum_a:
    2: a
  enum_b:
    3: b

When ran with javascript, message shows "requested 1 bytes, but only 0 bytes available" cmd_id is 1 byte and both cmd_id.direction and cmd_id.id reads different bits from cmd_id. But currently cmd_id_a and cmd_id_b types which are switched-on from cmd_id.id reads from the next byte.

If the type of a field is a bit-sized integer (bXX), when we use a switch-on type, the underlying matched case uses the next byte in the stream. Can we reuse the same byte?

darkdread avatar May 29 '24 06:05 darkdread

@darkdread:

If the type of a field is a bit-sized integer (bXX), when we use a switch-on type, the underlying matched case uses the next byte in the stream. Can we reuse the same byte?

See https://github.com/kaitai-io/kaitai_struct/issues/1070

generalmimon avatar May 29 '24 07:05 generalmimon