Re: Controlling endian-ness?



For using Unsigned_32. Why not just override the built-in Write attributes
routines for Unsigned_32 by re-writing the attributes routines. This may at
most require a new package with a few extra attributes routines that may
be needed. Also, this will also allow you to use "Shift_Left/Shift_Right"
directly with Unsigned_32.

So in your program you could use:

Data : Unsigned_32 ;
...
Unsigned_32'Write ( Stream_Pointer, Data ) ;


In GNAT you can not add new attributes, but you can override the built-in
versions with a new set of attributes routines.



In <4897b7f5$0$19705$4d3efbfe@xxxxxxxxxxxxxx>, "Peter C. Chapin" <pcc482719@xxxxxxxxx> writes:
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

.



Relevant Pages