awdorrin <
awdo...@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;