comp.lang.ada
 help / color / mirror / Atom feed
* Controlling endian-ness?
@ 2008-08-05  2:16 Peter C. Chapin
  2008-08-05  3:10 ` Steve
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Peter C. Chapin @ 2008-08-05  2:16 UTC (permalink / raw)


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



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

end of thread, other threads:[~2008-08-12 13:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-05  2:16 Controlling endian-ness? Peter C. Chapin
2008-08-05  3:10 ` Steve
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

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