comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Record Elements and Endian Conversion
Date: Thu, 10 Jan 2013 19:32:19 +0100
Date: 2013-01-10T19:32:19+01:00	[thread overview]
Message-ID: <18uvrk2updt1l.1h7clt4i3bi9k.dlg@40tude.net> (raw)
In-Reply-To: fbb1f71f-67c0-4452-896a-35ceca29365e@googlegroups.com

On Thu, 10 Jan 2013 09:31:25 -0800 (PST), awdorrin wrote:

> Is there any mechanism within Ada that would provide a way to iterate
> across all components of a record, perhaps providing their data types?

Yes,

http://ada-programming.blogspot.de/2012/12/type-introspection-in-ada.html

though that unlikely would solve your problem.
 
> Problem I have is that this record is used (via a MEMCPY call) to populate
> a buffer used to transmit an message via Ethernet. While I have adjusted
> the record's representation clause to put the data fields of the record
> into the correct bit location, those fields larger than a byte are of the
> wrong Endianness within the buffer.

One should never program network protocols this way. Here are short guide
lines [unless you enjoy the problems you have]:

1. There should be a specification the packet encoding.

2. No layout representation clauses shall be used.

3. No compiler generated stream attributes shall be used, except maybe for
Unsigned_8 or Character, e.g. a data type directly corresponding to the
octet.

A short example, getting big endian 32-bit unsigned from stream elements
array:

   pragma Assert (Stream_Element'Size = 8);

   procedure Get
             (  Data    : in out Stream_Element_Array;
                Pointer : in out Stream_Element_Offset;
                Value   : out Unsigned_32
             )  is
   begin
      if (  Pointer < Data'First
         or else
            (  Pointer > Data'Last
            and then
               Pointer > Data'Last + 1
         )  )
      then
         Raise_Exception
         (  Layout_Error'Identity,
            "Pointer is out of bounds"
         );
      elsif Pointer + 3 > Data'Last then
         Raise_Exception (End_Error'Identity, "End of data");
      end if;
      Value :=
         (  Shift_Left (Unsigned_32 (Data (Pointer    )), 24)
         or Shift_Left (Unsigned_32 (Data (Pointer + 1)), 16)
         or Shift_Left (Unsigned_32 (Data (Pointer + 2)), 8)
         or             Unsigned_32 (Data (Pointer + 3))
         );
      Pointer := Pointer + 4;
   end Get;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2013-01-10 18:32 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
2013-01-10 18:32 ` Dmitry A. Kazakov [this message]
2013-01-10 18:47 ` Niklas Holsti
2013-01-10 19:40 ` awdorrin
2013-01-11 14:44 ` Marc C
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox