comp.lang.ada
 help / color / mirror / Atom feed
From: Simon Wright <simon@pushface.org>
Subject: Re: Endianness and Record Specification
Date: Fri, 21 Sep 2012 23:18:57 +0100
Date: 2012-09-21T23:18:57+01:00	[thread overview]
Message-ID: <m2bogz81f2.fsf@pushface.org> (raw)
In-Reply-To: a0647230-14c8-4ece-8ed6-d23bdf130776@googlegroups.com

awdorrin <awdorrin@gmail.com> writes:

> At first I was thinking I could do:
>
> if Standard'Default_Bit_Order = 1 then
>   -- defined Little endian rec spec
> else
>   -- define Bit endian rec spec
> end if;
>
> But, the compiler doesn't let me do that... :-)
>
> I would think I should be able to somehow use the Default_Bit_Order to
> define some sort of relative byte position, depending on the system
> endianness, but I'm drawing a blank and hoping someone might have a
> quick example they could provide.

The way I've approached this is to declare an unrepresented type for the
main program to use, and then make a local, derived, represented type
inside a bit-order-dependent conditional.

Below, the type Local_Status is very local, but it works with a wider
scope, and may lead to improved performance by avoiding
packing/unpacking.

This assumes it's OK to have the conversion only at the edges of the
program.

   Big_Endian : constant Boolean
     := System."=" (System.Default_Bit_Order, System.High_Order_First);

   function To_Stream_Element (S : Status) return Ada.Streams.Stream_Element
   is
      type Local_Status is record
         LI : Leap_Indicator;
         VN : Version;
         M : Mode;
      end record;
      V : constant Local_Status := (LI => S.LI, VN => S.VN, M => S.M);
   begin
      if Big_Endian then
         declare
            type Host_Status is new Local_Status;
            for Host_Status use record
               LI at 0 range 0 .. 1;
               VN at 0 range 2 .. 4;
               M  at 0 range 5 .. 7;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Host_Status,
                                             Ada.Streams.Stream_Element);
         begin
            return Convert (Host_Status (V));
         end;
      else
         declare
            type Host_Status is new Local_Status;
            for Host_Status use record
               LI at 0 range 6 .. 7;
               VN at 0 range 3 .. 5;
               M  at 0 range 0 .. 2;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Host_Status,
                                             Ada.Streams.Stream_Element);
         begin
            return Convert (Host_Status (V));
         end;
      end if;
   end To_Stream_Element;

   function To_Status (S : Ada.Streams.Stream_Element) return Status
   is
   begin
      if Big_Endian then
         declare
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 0 .. 1;
               VN at 0 range 2 .. 4;
               M  at 0 range 5 .. 7;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      else
         declare
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 6 .. 7;
               VN at 0 range 3 .. 5;
               M  at 0 range 0 .. 2;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      end if;
   end To_Status;



  parent reply	other threads:[~2012-09-21 22:18 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-21 18:16 Endianness and Record Specification awdorrin
2012-09-21 19:21 ` awdorrin
2012-09-22  3:07   ` Stephen Leake
2012-09-21 22:18 ` Simon Wright [this message]
2012-09-22  7:43 ` Quentin Ochem
2012-10-23 21:08   ` awdorrin
2012-10-24 10:20     ` Stephen Leake
2012-11-02 13:13       ` awdorrin
2012-12-04 17:17         ` Anh Vo
2012-12-04 17:37           ` Niklas Holsti
2012-12-04 18:31             ` Anh Vo
2012-12-04 23:31               ` Randy Brukardt
2012-12-05  0:12                 ` Anh Vo
2012-12-05  2:00                   ` Jeffrey Carter
2012-12-05  3:40                     ` Anh Vo
2012-09-22  9:32 ` Robin Vowels
2012-09-22  9:59   ` Dmitry A. Kazakov
2012-09-24  2:44     ` Robin Vowels
2012-09-24  7:48       ` Simon Wright
replies disabled

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