From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,4c06e1e4fc2bf2d1 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news1.google.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local02.nntp.dca.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Mon, 04 Aug 2008 22:10:47 -0500 From: "Steve" Newsgroups: comp.lang.ada References: <4897b7f5$0$19705$4d3efbfe@news.sover.net> Subject: Re: Controlling endian-ness? Date: Mon, 4 Aug 2008 20:10:40 -0700 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5512 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5512 X-RFC2646: Format=Flowed; Response Message-ID: X-Usenet-Provider: http://www.giganews.com NNTP-Posting-Host: 24.20.111.206 X-Trace: sv3-i9JeprW5CU5LP+pxc1ICezdWOlYAzPB5ZHzjNO+3uBDf5FesZ/fgdSXz15MPboe0maWG2q2PrXM97+j!guidiMCv96LfkTI+kqOZS5blh0kv59RncXzW282W8OTd1fuo9fHPVL5sWNmCI6guS69WnjV3uXgW!iroo6d6U4fnrrkt3VpLN/BNdcSy6ZA== X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.39 Xref: g2news2.google.com comp.lang.ada:7170 Date: 2008-08-04T20:10:40-07:00 List-Id: "Peter C. Chapin" 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