阿达:包装具有可变大小的数组记录 [英] Ada: packing record with variable sized array

查看:83
本文介绍了阿达:包装具有可变大小的数组记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待创造一个包装记录,可容纳一个数组的长度的变化从5 - 50元素。是有可能做到这一点在这样一种方式,该记录可以在没有浪费的空间被包装?我就知道有多少元素是数组中,当我去创造纪录。

I am looking to create a packed record that can hold an array the varies in length from 5 - 50 elements. Is it possible to do this in such a way that the record can be packed with no wasted space? I will know how many elements will be in the array when I go to create the record.

-- 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);

这显然不会编译,但显示的是什么,我试图做的精神。如果可能的话,我想保持数组的长度出来的纪录。

This obviously won't compile, but shows the spirit of what I am trying to do. If possible I would like to keep the length of the array out of the record.

感谢您!

推荐答案

有真的不是一个阿达的方式来重新present记录你问了道路。然而,由于你的关心真的不是跟唱片是如何重新在内存presented,而是它是如何传输到插座,你也许并不需要担心创纪录的再presentation条款。

There really isn't a way in Ada to represent the record the way you're asking for. However, since your concern really isn't with how the record is represented in memory, but rather with how it's transmitted to a socket, you probably don't need to worry about record representation clauses.

相反,你可以定义自己的常规:

Instead, you can define your own Write routine:

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

或者,我相信这将在2012年阿达工作:

or, I believe this will work in 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);

然后身体看起来像

and then the body will look like

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位记录组成部分插座。如果这是必要的,我不认为内置写入属性会为你做的;你可能需要做自己的位变换,或者你可以变得棘手,并定义 Stream_Elements 的数组,并使用地址条款或方面定义覆盖在记录的其余部分的数组。但是,除非我是100%肯定,在插座的另一端的读者都使用完全相同的类型定义的阿达程序我不会用叠加的方法。

This won't work if the other components need to be packed, though, e.g. if you want to write a byte to the socket that contains one 3-bit record component and one 5-bit record component. If that's necessary, I don't think the built-in 'Write attributes will do that for you; you may need to do your own bit-twiddling, or you could get tricky and define an array of Stream_Elements and use an Address clause or aspect to define an array that overlays the rest of the record. But I wouldn't use the overlay method unless I were 100% certain that the reader at the other end of the socket were an Ada program that uses the exact same type definition.

注:我没有测试过这种

这篇关于阿达:包装具有可变大小的数组记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆