comp.lang.ada
 help / color / mirror / Atom feed
* Using GNAT.Sockets with Streams and Byte Swapping
@ 2005-05-25  9:48 markp
  2005-05-26  6:00 ` Simon Wright
  0 siblings, 1 reply; 10+ messages in thread
From: markp @ 2005-05-25  9:48 UTC (permalink / raw)


I am having a problem using GNAT.socket with streams. I can create a
stream easily and send data as follows:

Msg_Type'Write(
   My_Stream_Access,
   Msg);

This will work fine of both machines are the same "endian". However, if
I need to swap bytes on the variable Msg before I send, I get garbled
data on the other end.

Is there a problem with swapping bytes before the call to 'Write?

Thanks




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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-25  9:48 Using GNAT.Sockets with Streams and Byte Swapping markp
@ 2005-05-26  6:00 ` Simon Wright
  2005-05-26  9:28   ` markp
  0 siblings, 1 reply; 10+ messages in thread
From: Simon Wright @ 2005-05-26  6:00 UTC (permalink / raw)


"markp" <markwork66@yahoo.com> writes:

> I am having a problem using GNAT.socket with streams. I can create a
> stream easily and send data as follows:
>
> Msg_Type'Write(
>    My_Stream_Access,
>    Msg);
>
> This will work fine of both machines are the same "endian". However, if
> I need to swap bytes on the variable Msg before I send, I get garbled
> data on the other end.
>
> Is there a problem with swapping bytes before the call to 'Write?

Not as far as I know. Though it's a much better idea to swap bytes
_in_ 'Write (and 'Read).

You can write your own 'Read, 'Write attribute subprograms.

Or, you can rebuild the runtime on both sides using an XDR version of
System.Stream_Attributes (s-stratt.adb).

In recent (supported) GNATs and in GCC 3.4, 4.0 this has been supplied
in s-strxdr.adb (so copy s-strxdr.adb to s-stratt.adb and rebuild --
see Makefile.adalib in your .../adalib directory under the GCC
runtime, though Some Assembly Will [probably] Be Required).

If you are on a PowerPC the only difference between doing this and
doing nothing on the PPC (running natively big-endian -- who does
otherwise?) is that natively Wide_Character is 2 bytes, while the XDR
form is 4 bytes.

There is a problem with s-strxdr.adb, it raises the wrong exception
(an internal Data_Error rather than the standed End_Error, ISTR).

What we ended up doing was using the native PPC s-stratt.adb and
writing our own on the x86 side to match what the PPC was doing
(easier to argue the acceptability of a vendor-supplied runtime, and
our delivery platform is the PPC!)



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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26  6:00 ` Simon Wright
@ 2005-05-26  9:28   ` markp
  2005-05-26  9:50     ` Alex R. Mosteo
  2005-05-26 10:01     ` Duncan Sands
  0 siblings, 2 replies; 10+ messages in thread
From: markp @ 2005-05-26  9:28 UTC (permalink / raw)


Thanks for your reply. I have one question. In order to write my own
'Write and 'Read subprograms, would I have to change GNAT.Sockets and
rebuild the runtime? Or, is there an easier way?

Thanks again.




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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26  9:28   ` markp
@ 2005-05-26  9:50     ` Alex R. Mosteo
  2005-05-26 10:01     ` Duncan Sands
  1 sibling, 0 replies; 10+ messages in thread
From: Alex R. Mosteo @ 2005-05-26  9:50 UTC (permalink / raw)


markp wrote:
> Thanks for your reply. I have one question. In order to write my own
> 'Write and 'Read subprograms, would I have to change GNAT.Sockets and
> rebuild the runtime? Or, is there an easier way?

No, no :) You just write a conformant procedure and then:

for Your_Type'Write use <your procedure>;



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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26  9:28   ` markp
  2005-05-26  9:50     ` Alex R. Mosteo
@ 2005-05-26 10:01     ` Duncan Sands
  2005-05-26 11:35       ` markp
  1 sibling, 1 reply; 10+ messages in thread
From: Duncan Sands @ 2005-05-26 10:01 UTC (permalink / raw)
  To: markp; +Cc: comp.lang.ada

On Thu, 2005-05-26 at 02:28 -0700, markp wrote:
> Thanks for your reply. I have one question. In order to write my own
> 'Write and 'Read subprograms, would I have to change GNAT.Sockets and
> rebuild the runtime? Or, is there an easier way?

The usual answer is that you should write your own 'Read and 'Write
routines.  However recent versions of GNAT support the machine
independent XDR representation, which may be what you want.  The
GNAT reference manual says:

13.13.2(17): Stream Oriented Attributes

   If a stream element is the same size as a storage element, then the normal in-memory representation should be used by Read and Write for
   scalar objects. Otherwise, Read and Write should use the smallest number of stream elements needed to represent all values in the base range
   of the scalar type.

   Followed. By default, GNAT uses the interpretation suggested by AI-195, which specifies using the size of the first subtype. However, such an
   implementation is based on direct binary representations and is therefore target- and endianness-dependent. To address this issue, GNAT also
   supplies an alternate implementation of the stream attributes Read and Write, which uses the target-independent XDR standard representation
   for scalar types. The XDR implementation is provided as an alternative body of the System.Stream_Attributes package, in the file
   `s-strxdr.adb' in the GNAT library. There is no `s-strxdr.ads' file. In order to install the XDR implementation, do the following:
    1. Replace the default implementation of the System.Stream_Attributes package with the XDR implementation. For example on a Unix platform
       issue the commands:


$ mv s-stratt.adb s-strold.adb
$ mv s-strxdr.adb s-stratt.adb

    2. Rebuild the GNAT run-time library as documented in the GNAT User's Guide





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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26 10:01     ` Duncan Sands
@ 2005-05-26 11:35       ` markp
  2005-05-26 18:51         ` Pascal Obry
  2005-05-26 20:29         ` Simon Wright
  0 siblings, 2 replies; 10+ messages in thread
From: markp @ 2005-05-26 11:35 UTC (permalink / raw)


We found the answer to our problem. We have types such as

type x is range 1..5;

We then make records including these types. In the rep specs, we define
them to be 32 bits. Apparently, GNAT ignores the rep spec when doing
the 'Write, so we are not sending the correct number of bits. The fix
is:

type x is range 1..5;
for x'size use 32;

This fixes our problem.

Thanks very much for your help.




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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26 11:35       ` markp
@ 2005-05-26 18:51         ` Pascal Obry
  2005-05-26 20:29         ` Simon Wright
  1 sibling, 0 replies; 10+ messages in thread
From: Pascal Obry @ 2005-05-26 18:51 UTC (permalink / raw)



"markp" <markwork66@yahoo.com> writes:

> We found the answer to our problem. We have types such as
> 
> type x is range 1..5;
> 
> We then make records including these types. In the rep specs, we define
> them to be 32 bits. Apparently, GNAT ignores the rep spec when doing
> the 'Write, so we are not sending the correct number of bits. The fix
> is:

This can be solved with the new Ada 2006 Stream_Size attribute.

http://www.adaic.com/standards/rm-amend/html/RM-13-13-2.html

Pascal.


-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26 11:35       ` markp
  2005-05-26 18:51         ` Pascal Obry
@ 2005-05-26 20:29         ` Simon Wright
  2005-05-26 21:02           ` Florian Weimer
  1 sibling, 1 reply; 10+ messages in thread
From: Simon Wright @ 2005-05-26 20:29 UTC (permalink / raw)


"markp" <markwork66@yahoo.com> writes:

> We found the answer to our problem. We have types such as
>
> type x is range 1..5;
>
> We then make records including these types. In the rep specs, we define
> them to be 32 bits. Apparently, GNAT ignores the rep spec when doing
> the 'Write, so we are not sending the correct number of bits. The fix

The rep spec is about layout in memory, not on the stream.

> is:
>
> type x is range 1..5;
> for x'size use 32;
>
> This fixes our problem.
>
> Thanks very much for your help.

You're welcome (and I'm glad it didn't turn out to be so difficult
after all!)



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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26 20:29         ` Simon Wright
@ 2005-05-26 21:02           ` Florian Weimer
  2005-05-27  6:38             ` Vinzent 'Gadget' Hoefler
  0 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2005-05-26 21:02 UTC (permalink / raw)


* Simon Wright:

> You're welcome (and I'm glad it didn't turn out to be so difficult
> after all!)

Mark is not using an Ada 95 compiler, it seems.  It used to be more
difficult because the size of the base type determined the number of
stream elements used, and the representation clause doesn't change it.



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

* Re: Using GNAT.Sockets with Streams and Byte Swapping
  2005-05-26 21:02           ` Florian Weimer
@ 2005-05-27  6:38             ` Vinzent 'Gadget' Hoefler
  0 siblings, 0 replies; 10+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2005-05-27  6:38 UTC (permalink / raw)


Florian Weimer wrote:

> Mark is not using an Ada 95 compiler, it seems.  It used to be more
> difficult because the size of the base type determined the number of
> stream elements used, and the representation clause doesn't change it.

Read again. He _changed_ the size of the base type. (Universal_Integer
doesn't have a fixed size, does it?)


Vinzent.

-- 
worst case: The wrong assumption there actually is one.



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

end of thread, other threads:[~2005-05-27  6:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-25  9:48 Using GNAT.Sockets with Streams and Byte Swapping markp
2005-05-26  6:00 ` Simon Wright
2005-05-26  9:28   ` markp
2005-05-26  9:50     ` Alex R. Mosteo
2005-05-26 10:01     ` Duncan Sands
2005-05-26 11:35       ` markp
2005-05-26 18:51         ` Pascal Obry
2005-05-26 20:29         ` Simon Wright
2005-05-26 21:02           ` Florian Weimer
2005-05-27  6:38             ` Vinzent 'Gadget' Hoefler

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