0

我的系统必须能够解析两种非常相似的输入数据。

  • 如果数据来自队列,则它具有以下结构:
record
record
...
record
  • 如果数据来自文件,则它具有以下结构:
header
record
record
...
record

我目前的代码如下:

seq:
  - id: file_header
    type: file_header

  - id: record
    type: record
    repeat: eos

types:
  file_header:
    seq:
      - id: main_version
        type: u1
      - id: sub_version
        type: u1
      - id: spare
        type: str
        size: 30
        encoding: UTF-8

  record:
    seq:
      - id: event_id
        type: u2
        # enum: event_types
      - id: event_length
        type: u4
      - id: enb_id
        type: u4
      - id: cell_id
        type: u1
      - id: call_id
        type: u4
      - id: date_time
        type: date_time_record
      - id: spare
        type: str
        size: 2
        encoding: UTF-8
      - id: crnti
        type: u2
      - id: body
        size: event_length - 21

我的想法是只创建一个适用于这两种方法的 .ksy 文件。我怎么才能得到它?它基本上是file_header可选的,但我没有办法做到这一点。有人可以帮我吗?

4

1 回答 1

0

附属免责声明:我是Kaitai Struct维护者(请参阅我的GitHub 个人资料)。

我的想法是只创建一个适用于这两种方法的 .ksy 文件。我怎么才能得到它?

is_file您可以在顶级类型上定义布尔参数,并true在数据来自文件时传递,否则false. 像这样:

params:
  - id: is_file
    type: bool
seq:
  - id: file_header
    type: file_header
    if: is_file

  - id: record
    type: record
    repeat: eos
types:
  # ...

请注意,is_file参数是强制性的,如果不向其中传递值,您将无法实例化该类。出于这个原因,fromFile(…​)辅助方法将不再可用,您需要正常使用new(或其在您的目标语言中最接近的等效项)创建解析器对象。

我不知道你的目标是什么语言,但在 C++、C#、Lua、PHP 和 Python 中,自定义params首先出现(之前_io_root_parent),而在 Java、JavaScript 和 Nim 中是第二个。例如,在 Python 中,你会这样做:

from kaitaistruct import KaitaiStream
from io import BytesIO

data = b"\x00\x01\x02..."
data_come_from_file = True
f = YourFormat(data_comes_from_file, KaitaiStream(BytesIO(data)))

例如,在 Java 中:

import io.kaitai.struct.ByteBufferKaitaiStream;

byte[] data = new byte[] { 0x00, 0x01, 0x02, ... };
boolean dataComeFromFile = true;
f = new YourFormat(new ByteBufferKaitaiStream(data), dataComesFromFile)

如果不确定,请检查生成的代码。

于 2021-01-25T22:42:38.880 回答