From: "Steve" <nospam_steved94@comcast.net>
Subject: Re: Controlling endian-ness?
Date: Mon, 4 Aug 2008 20:10:40 -0700
Date: 2008-08-04T20:10:40-07:00 [thread overview]
Message-ID: <JrOdnf4599ElWQrVnZ2dnUVZ_rmdnZ2d@comcast.com> (raw)
In-Reply-To: 4897b7f5$0$19705$4d3efbfe@news.sover.net
"Peter C. Chapin" <pcc482719@gmail.com> wrote in message
news:4897b7f5$0$19705$4d3efbfe@news.sover.net...
> I'm trying to read/write 32 bit quantities from/to a binary file. The file
> has a format defined by a specification that is outside my control. Some
> of the quantities are stored in the file in big endian order. However, my
> machine is a little endian machine. The file in question also contains
> various values that are most naturally represented with different data
> types. Thus I'm looking at Stream_IO as a way to deal with it.
>
> As an experiment I wrote a small program that defines a 32 bit unsigned
> integer type and then overrides the 'Write attribute to write the value in
> big endian form. Here is what I have:
>
> with Ada.Streams; use Ada.Streams;
> with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
> with Interfaces; use Interfaces;
>
> procedure Stream_Check is
> pragma Assert(Stream_Element'Size = 8);
>
> type Word is mod 2**32;
> procedure Word_Write
> (Stream : access Root_Stream_Type'Class; Item : in Word);
> for Word'Size use 32;
> for Word'Write use Word_Write;
>
> procedure Word_Write
> (Stream : access Root_Stream_Type'Class; Item : in Word) is
> Buffer : Stream_Element_Array(0..3);
> Workspace : Unsigned_32 := Unsigned_32(Word); -- ERROR HERE!
> begin
> Buffer(0) :=
> Stream_Element(Shift_Right((Workspace and 16#FF000000#), 24));
> Buffer(1) :=
> Stream_Element(Shift_Right((Workspace and 16#00FF0000#), 16));
> Buffer(2) :=
> Stream_Element(Shift_Right((Workspace and 16#0000FF00#), 8));
> Buffer(3) :=
> Stream_Element(Shift_Right((Workspace and 16#000000FF#), 0));
> Write(Stream.all, Buffer);
> end Word_Write;
>
> Output_File : File_Type;
> Stream_Pointer : Stream_Access;
>
> W : Word := 16#0000FFFF#;
> begin
> Create(Output_File, Out_File, "test.bin");
> Stream_Pointer := Stream(Output_File);
> Word'Write(Stream_Pointer, W);
> Close(Output_File);
> end Stream_Check;
>
> I'm using GNAT GPL 2008. It produces an error on the indicated line
> saying, "invalid use of subtype mark in expression or call." Apparently it
> doesn't like me trying to convert a Word to an Unsigned_32, but I don't
> understand why (am I doing that conversion right?).
>
> I want to use Unsigned_32 so that I can use Shift_Right. I can't override
> the 'Write attribute for Unsigned_32 directly because it's in a different
> package (right?).
>
> Overall I have a feeling that there is probably a much better way to do
> this.
>
> Peter
I don't know if this will be useful to you, but here is the technique I used
for reversing the byte order on a 32 bit integer. Actually I was going for
"network byte order" of a float (s_float is a 32 bit float, u_long is a
32bit unsigned integer).
TYPE aByte IS MOD 256;
FOR aByte'SIZE USE 8;
TYPE aByteArray IS ARRAY( Positive RANGE <> ) OF aByte;
FUNCTION nltohf( value : u_long ) RETURN s_float IS
TYPE aFourBytes IS NEW aByteArray(1..4);
FUNCTION Conv IS
NEW Ada.Unchecked_Conversion( aFourBytes, s_float );
FUNCTION Conv IS
NEW Ada.Unchecked_Conversion( u_long, aFourBytes );
temp : aFourBytes := Conv( value );
BEGIN
RETURN Conv( aFourBytes'( temp(4), temp(3), temp(2), temp(1) ) );
END nltohf;
It isn't endian neutral (or particularly pretty), but it got the job done.
Regards,
Steve
next prev parent reply other threads:[~2008-08-05 3:10 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-05 2:16 Controlling endian-ness? Peter C. Chapin
2008-08-05 3:10 ` Steve [this message]
2008-08-05 9:59 ` Peter C. Chapin
2008-08-05 5:23 ` christoph.grein
2008-08-05 9:59 ` Peter C. Chapin
2008-08-05 14:59 ` anon
2008-08-05 22:14 ` Peter C. Chapin
2008-08-06 0:16 ` Adam Beneschan
2008-08-06 13:44 ` Peter C. Chapin
2008-08-06 17:07 ` Controlling endian-ness? (Example: Attribute Overriding) anon
2008-08-12 13:42 ` Controlling endian-ness? 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