【问题标题】:Kaitai Struct - Optional block or attributeKaitai Struct - 可选块或属性
【发布时间】:2020-08-21 11:14:20
【问题描述】:

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

  • 如果数据来自队列,则其结构如下:
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 成为可选的,但我看不到这样做的方法。 有人可以帮我解决这个问题吗?

【问题讨论】:

  • 嗨,可能为时已晚,但我想问一下标题与记录有何不同。某处可能有一个神奇的值,或者你可以使用 io 大小?

标签: kaitai-struct


【解决方案1】:

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

我的想法是只创建一个适用于两者的 .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)

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

【讨论】:

  • 如果我们需要处理 10 种不同的变体格式,而不是像 OP 中的 2 个不同的变体,该怎么办?对于这种情况有不同的方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多