stream - 当从 Ada 中的 Stream 读取数据时,如何调整/匹配记录组件的大小?

标签 stream embedded ada

非常具体的问题,但我们这里有一些优秀的 Ada 人员,所以我想听听想法。我正在从用于嵌入式系统的文件中读取数据。我正在使用的数据 block 始终具有可预测的 header 格式……但有一个问题……数据有效负载长度是在有效负载出现之前作为格式的一部分给出的。因此,在读取 header 中已知位置的某个字节之前,我不知道有效负载的大小。这些 block 一个接一个地出现。

字面上的格式是([]用于提高可读性):

[2 字节标记] [1 字节有效负载长度 (LSB)] [1 字节有效负载长度 (MSB)] [有效负载]

有效负载是人类可读的配置文本。下一个 TAG 将是前一个有效负载之后的接下来的两个字节,依此类推,直到我在最后一个有效负载之后没有看到任何匹配的已知标签。然后我知道我已经完成了。

我正在使用 direct_IO 流从文件中读取此内容,但我可能会切换到更通用的流并开始执行转换。

我想在一天结束时将所有这些存储在一个简单的记录中 我正在寻找一种技术,可以读取数据并读取第三个字节我现在知道有效负载大小,并且可以调整数组或字符串组件的大小以在记录已经充当读取时保存当时的数据缓冲。也就是说我需要读取标签和长度数据,所以我想立即将它们存储在记录中。如果可以的话,我想将有效负载存储在同一记录中。我可以考虑使用访问类型并动态创建有效负载存储,但这意味着我必须在 3 个字节后停止读取,完成工作,然后继续。另外,这意味着写入也会遇到同样的问题,因为对象的表示不再与期望的 block 格式匹配。

我正在考虑尝试使用一条记录来保存所有这些内容,并对有效负载大小进行判别式,并在该记录上使用表示子句来模仿上述格式。由于判别式是记录和数据 block 中的第三个字节,我也许能够进行对话并简单地将数据“放置”到对象中......但是当我实例化组件时,我没有办法调整组件的大小在尚未读取标签和长度的情况下进行记录。我假设我无法同时读取和创建对象,因此要创建对象,我需要一个长度。虽然我可以继续摆弄文件位置并读取我需要的内容,然后返回到开头,然后创建并使用整个 block ,但我知道必须有更好的“Ada”方式。

有没有一种方法可以使用表示子句将 header 填充到记录中,并且当判别式填充数据中的值时,将设置记录数组或字符串有效负载组件大小?

此外,这不仅仅是为了阅读,我需要找到一种在配置更改时将这种精确格式输出到文件中的好方法。因此,我希望使用表示子句来匹配底层格式,这样我就可以将对象“写入”到文件中,并且这将是正确的格式。我希望对读取也能做同样的事情。

到目前为止,我看到的所有 Ada 读取示例都具有已知长度(或已知最大长度)的记录,其中记录读取静态大小的数据 block 。

有人有一个例子或者可以为我指明如何使用这种方法来处理这种可变大小的有效负载的正确方向吗?

感谢您提供的任何帮助,

-乔什

最佳答案

本质上,完成此操作的方法是进行部分读取,足以获取字节数,然后将其余数据读入可区分的记录中。

伪 Ada 中类似以下内容:

type Payloads is array (Payload_Sizes range <>) of Your_One_Byte_Payload_Type;

type Data (Payload_Length : Payload_Sizes) is
   record
      Tag : Tag_Type;
      Payload : Payloads(1 .. Payload_Length);
   end record;

for Data use record
   Tag            at 0 range 0 .. 15;
   Payload_Length at 2 range 0 .. 15;
   -- Omit a rep spec for Payload
end record;

通常,编译器会在最后一个代表指定的字段之后立即找到有效负载数据,但您需要与供应商验证这一点,或者执行一些测试程序。 (可能有更明确的方法来指定这一点,如果有人提供可行的方法,我愿意更新此答案。)

并且不要为 Payload_Length 判别式提供默认值,否则会导致记录实例始终保留最大值所需的最大存储量。

然后,在您的数据读取代码中,类似以下内容:

loop
   Get(Data_File, Tag);
   Get(Data_File, Payload_Length)

   declare
      Data_Item : Data(Payload_Length);
   begin
      Data_Item.Tag := Tag;
      Get(Data_File, Data_Item.Payload);
      Process_Data(Data_Item);
   end;
   ...
   exit when Whatever;
end loop;

(您需要制定退出标准。)

然后,Data_Item 将根据 Payload_Length 动态调整大小。但要注意,如果该长度是奇数,因为可能会发生填充...

关于stream - 当从 Ada 中的 Stream 读取数据时,如何调整/匹配记录组件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7522785/

相关文章:

linux - ADA & GTK => 函数 Get_Text

ada - 成员值的静态引用 - Ada

c# - 逐帧播放mp3

FFMPEG:2x2 网格相机流到 Youtube

embedded - 充分利用糟糕的 "checksum"算法

c++ - 用于嵌入式设备的轻量级 smbclient 模拟

ubuntu - 从 GPS 链接到 Ubuntu .a 模块库?

java - Kafka 流应用程序将读取与写入分开

java - 如何使用多个条件从集合列表中过滤

c - ((Port *)0x41004400UL) 在这里是什么意思?