繁体   English   中英

Ada:具有可变大小数组的打包记录

[英]Ada: packing record with variable sized array

我正在寻找创建一个压缩记录,该记录可以容纳长度在5到50个元素之间的数组。 是否可以以不浪费空间打包记录的方式进行操作? 我将创建记录时知道数组中将包含多少个元素。

-- the range of the array
type Array_Range_T is Integer range 5 .. 50;

-- the array type
type Array_Type_T is array range (Array_Range_T) of Integer;

-- the record
type My_Record_T (Array_Length : Integer := 5) is
  record
    -- OTHER DATA HERE
    The_Array : Array_Type_T(Array_Length);
  end record;
-- Pack the record
for My_Record_T use
  record
    -- OTHER DATA
    The_Array at 10 range 0 .. Array_Length * 16;
  end record;

for My_Record_T'Size use 80 + (Array_Length * 16);

这显然不会编译,但是显示了我正在尝试做的精神。 如果可能的话,我想将数组的长度保留在记录之外。

谢谢!

Ada中确实没有一种方法可以按照您的要求来表示唱片。 但是,由于您真正关心的不是记录在内存中的表示方式,而是记录如何传输到套接字,因此您可能不必担心记录表示子句。

相反,您可以定义自己的Write例程:

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T);
for My_Record_T'Write use Write;

或者,我相信这将在Ada 2012中起作用:

type My_Record_T is record
    ...
end record
with Write => Write;

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T);

然后身体看起来像

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T) is
begin
    -- Write out the record components, EXCEPT Array_Length and The_Array.
    T1'Write (Stream, Item.F1);  -- F1 is a record field, T1 is its type
    T2'Write (Stream, Item.F2);  -- F2 is a record field, T2 is its type
    ...

    -- Now write the desired data 
    declare
        Data_To_Write : Array_Type_T (1 .. Item.Array_Length)
            renames Item.The_Array (1 .. Item.Array_Length);
                -- I'm assuming the lower bound is 1, but if not, adjust your code
                -- accordingly
    begin
        Array_Type_T'Write (Stream, Data_To_Write);
            -- Note: using 'Write will write just the data, without any bound 
            -- information, which is what you want.
    end;
end Write;

但是,如果需要打包其他组件,这将无法工作,例如,如果您想向包含一个3位记录组件和一个5位记录组件的套接字写入一个字节。 如果有必要,我认为内置的'Write属性不会为您做到这一点; 您可能需要做一些自己的操作,否则可能会很棘手,并定义一个Stream_Elements数组,并使用Address子句或Stream_Elements来定义一个覆盖其余记录的数组。 但是除非我100%确信套接字另一端的阅读器是使用完全相同的类型定义的Ada程序,否则我不会使用overlay方法。

注意:我尚未对此进行测试。

不确定我是否完全理解您要实现的目标,但是您不能做这样的事情

-- the range of the array
type Array_Range_T is range 1 .. 50;

-- the array type
type Array_Type_T is array (Array_Range_T range <>) of Integer;

Array_Length : constant := 5; --5 elements in the array

-- the record
type My_Record_T is
 record
    -- OTHER DATA HERE
    The_Array : Array_Type_T (1 .. Array_Length);
  end record;

-- Pack the record
for My_Record_T use
 record
-- OTHER DATA
The_Array at 0 range 0 .. (Array_Length * Integer'Size) - 1 ;
end record;

for My_Record_T'Size use (Array_Length * Integer'Size);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM