comp.lang.ada
 help / color / mirror / Atom feed
* Record Elements and Endian Conversion
@ 2013-01-10 17:31 awdorrin
  2013-01-10 18:32 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: awdorrin @ 2013-01-10 17:31 UTC (permalink / raw)


I am migrating legacy code written for the PowerPC platform to X86, and have been running into Endian issues throughout the code.

In the latest issue I've discovered, a section of code in which a record has been defined that has 111 components of various data types.

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

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.

Thanks,
-Al



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Record Elements and Endian Conversion
  2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
@ 2013-01-10 18:32 ` Dmitry A. Kazakov
  2013-01-10 18:47 ` Niklas Holsti
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Dmitry A. Kazakov @ 2013-01-10 18:32 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Record Elements and Endian Conversion
  2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
  2013-01-10 18:32 ` Dmitry A. Kazakov
@ 2013-01-10 18:47 ` Niklas Holsti
  2013-01-10 19:40 ` awdorrin
  2013-01-11 14:44 ` Marc C
  3 siblings, 0 replies; 5+ messages in thread
From: Niklas Holsti @ 2013-01-10 18:47 UTC (permalink / raw)


On 13-01-10 19:31 , awdorrin wrote:
> I am migrating legacy code written for the PowerPC platform to X86,
> and have been running into Endian issues throughout the code.
> 
> In the latest issue I've discovered, a section of code in which a
> record has been defined that has 111 components of various data
> types.
> 
> Is there any mechanism within Ada that would provide a way to iterate
> across all components of a record, perhaps providing their data
> types?

One way, sort of, is to use stream I/O. The default (compiler-defined)
'Read, 'Write etc. procedures for the record type traverse the record
components in declaration order and call the 'Read or 'Write, etc.,
procedure for the component type, on the component.

If you override the 'Read etc. for the component types, but use the
default 'Read for the record type, the result is rather like an
iteration over the components that calls your 'Read, etc., and then you
can do what you like with the component values.

> Problem I have is that this record is used (via a MEMCPY call) to
> populate a buffer used to transmit an message via Ethernet.

Argh.

> 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.

I would either swap bytes in the components, using for example bindings
to the libc functions htonl, htons, or build the buffer using stream
output, as above, with the 'Write procedure for the component types
written to produce network order. (Since stream 'Write does not depend
on the bit-wise representation of the record, you can remove the rep
spec for the record type if you use the 'Write method.)

I believe some new Gnat versions have a Gnat-specific attribute to set
the endianness of record representations -- and not only the
bit-numbering order -- which makes the compiler actually swap endianness
when a record component is assigned, if the component has the non-native
endianness.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Record Elements and Endian Conversion
  2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
  2013-01-10 18:32 ` Dmitry A. Kazakov
  2013-01-10 18:47 ` Niklas Holsti
@ 2013-01-10 19:40 ` awdorrin
  2013-01-11 14:44 ` Marc C
  3 siblings, 0 replies; 5+ messages in thread
From: awdorrin @ 2013-01-10 19:40 UTC (permalink / raw)


Dimitry and Niklas, thanks for your responses.

The Introspection/Stream approach is interesting, but I think it would result in a more complicated situation than I already have.

I completely agree that this code was implemented in the wrong way. Unfortunately, while I am tasked with 'fixing' the endian issues, I'm not being provided with enough time to rewrite the entire routine.

I have looked into the Scalar_Storage_Order feature that has been introduced, but I have not been able to investigate the latest compilers for my system yet. I probably should just download the source for the latest GCC/GNAT and see what happens. ;)

Thanks!



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Record Elements and Endian Conversion
  2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
                   ` (2 preceding siblings ...)
  2013-01-10 19:40 ` awdorrin
@ 2013-01-11 14:44 ` Marc C
  3 siblings, 0 replies; 5+ messages in thread
From: Marc C @ 2013-01-11 14:44 UTC (permalink / raw)


On Thursday, January 10, 2013 11:31:25 AM UTC-6, awdorrin wrote:
> I am migrating legacy code written for the PowerPC platform to X86, and have been running into Endian issues throughout the code.

AdaCore recently announced that "GNAT Pro Solves Data Endianness Portability Challenge" (http://www.adacore.com/press/endianness-portability-challenge), though they don't provide any detail about the specific approach, simply referring to it as "a natural extension to the existing Ada data representation model".

So, it should be available to those who are GNATPro customers, and given the lead time I'm pretty optimistic it would be available in GNAT GPL 2013 (which is typically released mid-year).

Marc A. Criley



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-11 14:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-10 17:31 Record Elements and Endian Conversion awdorrin
2013-01-10 18:32 ` Dmitry A. Kazakov
2013-01-10 18:47 ` Niklas Holsti
2013-01-10 19:40 ` awdorrin
2013-01-11 14:44 ` Marc C

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