Discussion:
Any examples of Byte Ordering Functions
(too old to reply)
Bill Sheehan
2003-10-15 17:42:58 UTC
Permalink
Hello Folks,

Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?

Would there be a site with these functions available for download?

Thanks.

BillS
Larry Kilgallen
2003-10-15 18:55:59 UTC
Permalink
Post by Bill Sheehan
Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?
Your question seems to me to indicate you are trying to program in C
using an Ada compiler. (No disrespect to C here, the original saying
was that you can program FORTRAN in any language.)
Hyman Rosen
2003-10-15 18:44:18 UTC
Permalink
Post by Larry Kilgallen
Post by Bill Sheehan
Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?
Your question seems to me to indicate you are trying to program in C
using an Ada compiler.
So what's the Ada way of writing portable code that
writes out and reads in 16-bit and 32-bit integers
for an external data source that has a defined byte
ordering?
James Rogers
2003-10-16 01:01:16 UTC
Permalink
Post by Hyman Rosen
Post by Larry Kilgallen
Post by Bill Sheehan
Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?
Your question seems to me to indicate you are trying to program in C
using an Ada compiler.
So what's the Ada way of writing portable code that
writes out and reads in 16-bit and 32-bit integers
for an external data source that has a defined byte
ordering?
To quote from the Ada Language Reference Manual section 13.5:

For every specific record subtype S, the following attribute is defined:

S’Bit_Order Denotes the bit ordering for the type of S. The value of this
attribute is of type System.Bit_Order. Bit_Order may be specified for
specific record types via an attribute_definition_clause; the expression of
such a clause shall be static.

A bit ordering is a method of interpreting the meaning of the storage place
attributes. High_Order_First (known in the vernacular as big endian) means
that the first bit of a storage element (bit 0) is the most significant bit
(interpreting the sequence of bits that represent a component as an
unsigned integer value). Low_Order_First (known in the vernacular as little
endian) means the opposite: the first bit is the least significant.

Jim Rogers
Hyman Rosen
2003-10-16 13:32:32 UTC
Permalink
S’Bit_Order
Won't setting the BIT_ORDER to the opposite of your
machine's default also reverse the bits of an octet?
That doesn't sound like what the OP wants, and it's
not what the [hn][ls]to[nh] functions do.
Martin Dowie
2003-10-16 14:59:27 UTC
Permalink
S'Bit_Order Denotes the bit ordering for the type of S. The value of this
[snip]

This has nothing to do with the underlying byte-endianness as the OP
needs but to do with record representation clauses mean.

It's this sort of thing that really puts me off using record reps - I
usually
just use a toolkit of generic routines that I instantiate for each type and
build to.from arrays of Unsigned_32.

You could write your own functions to do this - it is trivial, esp if you
are dealing with the predefined type Unsigned_32. Or pragma Import
the 'C' routines (yuck!).
t***@acm.org
2003-10-16 20:00:08 UTC
Permalink
Post by Martin Dowie
build to.from arrays of Unsigned_32.
You could write your own functions to do this - it is trivial, esp if you
How about raising the abstraction level and using Streams. ie, don't
read something as Unsigned_32, then byte swap (or not). Instead define
a 'Read for objects of the type and two implementation of that 'Read,
one just reading four bytes and the other reading four bytes and swapping.
Martin Dowie
2003-10-17 12:08:44 UTC
Permalink
Post by t***@acm.org
Post by Martin Dowie
build to.from arrays of Unsigned_32.
You could write your own functions to do this - it is trivial, esp if you
How about raising the abstraction level and using Streams. ie, don't
read something as Unsigned_32, then byte swap (or not). Instead define
a 'Read for objects of the type and two implementation of that 'Read,
one just reading four bytes and the other reading four bytes and swapping.
Yes, that sounds good but at the time I was working in an '83 shop,
so no streams.

Actually, the next time I used them I was working at a place that did
have an '95 compiler but prohibited the use of any '95 features! Sad
but true...
chris
2003-10-19 15:22:17 UTC
Permalink
Post by Martin Dowie
You could write your own functions to do this - it is trivial, esp if you
are dealing with the predefined type Unsigned_32.
Trivial? :( Can you tell me how to do it pls?

I have the following:

type byte is mod 256;
type word is mod 2**16;
type dword is mod 2**32;

for byte'size use 8;
for word'size use 16;
for dword'size use 32;


I can do stream -> word and back using multiplication/division for big
and little endian, but not dword.



Chris
(see below)
2003-10-19 17:25:28 UTC
Permalink
On 19/10/03 16:22, in article
Post by chris
Trivial? :( Can you tell me how to do it pls?
type byte is mod 256;
type word is mod 2**16;
type dword is mod 2**32;
for byte'size use 8;
for word'size use 16;
for dword'size use 32;
I can do stream -> word and back using multiplication/division for big
and little endian, but not dword.
You can use shifts, ands (for masking) and ors (for combining) bit patterns
in unsigned types as easily in Ada as in C. (gasp!) No need to rely on the
compiler sussing out your arithmetic.
--
Bill

P.S. Actually, it's better than C! As well as logical shifts, you have
circular (rotate) and arithmetic (sign-aware) shifts in Ada.
chris
2003-10-19 13:45:38 UTC
Permalink
Hi,

I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
and think the following implementation is independant of the actual
order of bytes in a word variable. Am I right? It'd be nice not to
have two versions of this code and have to take different cpu
architectures into account at compile time! Can I expect the compiler
(gnat say) to optimise multiplication of modular types by *powers of
two* to shift lefts (and divisions by powers of two to shift rights)?


type Byte is mod 2**8;
for Byte'Size use 8;

type Word is mod 2**16;
for Word'Size use 16;


bytes in stream: a b c d e f g h

Read Big Endian encoded Word:

W := a * 256 + b;

Read Little Endian encoded Word:

W := b * 256 + a;



Cheers,
Chris
Martin Dowie
2003-10-19 16:53:18 UTC
Permalink
Post by chris
architectures into account at compile time! Can I expect the compiler
(gnat say) to optimise multiplication of modular types by *powers of
two* to shift lefts (and divisions by powers of two to shift rights)?
You don't need to look up the RM (Annex B.2) wrt the
predefined modular types in package "Interfaces" and there
you will find Shift_Left/Shift_Right/etc routines. These are
defined as "Intrinsic", which means they are "built in" to the
compiler - i.e. it should have a blinking good idea of a good
representation of this on the target h/w.

If you want "shifts" and "adds", just be explicit to the compiler.

Cheers,
Martin
chris
2003-10-19 17:52:58 UTC
Permalink
Post by Martin Dowie
You don't need to look up the RM (Annex B.2) wrt the
predefined modular types in package "Interfaces" and there
you will find Shift_Left/Shift_Right/etc routines. These are
defined as "Intrinsic", which means they are "built in" to the
compiler - i.e. it should have a blinking good idea of a good
representation of this on the target h/w.
Didn't know about that, thanks! That means if we want to output any
word to a stream in big endian we can do:

procedure Write_Big_Endian
(Stream : access Root_Stream_Type'Class;
W : in Word) is
A, B : Byte;
begin
A := Byte (Shift_Right (Unsigned_32(W), 8));
B := Byte (W and 16#00FF#);

Byte'Write (Stream, A);
Byte'Write (Stream, B);
end Write_Big_Endian;


and for little endian we can do:

procedure Write_Little_Endian
(Stream : access Root_Stream_Type'Class;
W : in Word) is
A, B : Byte;
begin
A := Byte (W and 16#00FF#);
B := Byte (Shift_Right (Unsigned_32(W), 8));
Byte'Write (Stream, B);
Byte'Write (Stream, A);
end Write_Little_Endian;

and this will work whatever the platform we compile on?
Martin Dowie
2003-10-19 19:24:44 UTC
Permalink
Post by chris
Didn't know about that, thanks! That means if we want to output any
Your welcome :-)
Post by chris
A := Byte (Shift_Right (Unsigned_32(W), 8));
Make Word a subtype of Unsigned_16 and you don't need to
convert to Unsigned_32. If you don't want to do this then you
can convert to Unsigned_16 as you are shifting right not left
(value of smaller magnitude not larger).
Post by chris
and this will work whatever the platform we compile on?
yup
Jeffrey Carter
2003-10-19 20:47:20 UTC
Permalink
Post by chris
procedure Write_Little_Endian
(Stream : access Root_Stream_Type'Class;
W : in Word) is
A, B : Byte;
begin
A := Byte (W and 16#00FF#);
B := Byte (Shift_Right (Unsigned_32(W), 8));
Byte'Write (Stream, B);
Byte'Write (Stream, A);
end Write_Little_Endian;
B contains the MSB, so you should write A 1st for little endian.
Post by chris
and this will work whatever the platform we compile on?
With this correction, yes.
--
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14
t***@acm.org
2003-10-19 22:53:10 UTC
Permalink
You can also do
type source is record
a,b,c,d : bytes;
end record;
for source use record
a at 0 range 0 .. 7;
b at 1 range 0 .. 7;
c at 2 range 0 .. 7;
d at 3 range 0 .. 7;
end record;
type target is record
d,c,b,a : bytes;
end record;
for target use record
d at 0 range 0 .. 7;
c at 1 range 0 .. 7;
b at 2 range 0 .. 7;
a at 3 range 0 .. 7;
end record;

type dword is new interfaces.integer_32;
type swapped_dword is new interfaces.integer_32;

function split_dword is new ada.unchecked_conversion(dword, source);
function make_swapped is new ada.unchecked_conversion(target, swapped_dword);

function byte_swap(input : dword) return swapped_dword is
s : constant source := split_dword(input);
begin
return make_swapped(target'(a=>s.d, b=>s.c, c=>s.b, d=>s.a));
end byte_swap;
Jeffrey Carter
2003-10-20 04:14:30 UTC
Permalink
Post by t***@acm.org
type source is record
a,b,c,d : bytes;
end record;
for source use record
a at 0 range 0 .. 7;
b at 1 range 0 .. 7;
c at 2 range 0 .. 7;
d at 3 range 0 .. 7;
end record;
for Source'Size use 32;

is probably a good idea, too.
Post by t***@acm.org
type target is record
d,c,b,a : bytes;
end record;
Even better,

type Target is new Source;

This creates conversions named Source and Target that reorder your bytes
for you automatically.
Post by t***@acm.org
for target use record
d at 0 range 0 .. 7;
c at 1 range 0 .. 7;
b at 2 range 0 .. 7;
a at 3 range 0 .. 7;
end record;
A derived type may have a different representation than its parent.

A size clause here would be a good idea, too.
Post by t***@acm.org
type dword is new interfaces.integer_32;
type swapped_dword is new interfaces.integer_32;
function split_dword is new ada.unchecked_conversion(dword, source);
function make_swapped is new ada.unchecked_conversion(target, swapped_dword);
function byte_swap(input : dword) return swapped_dword is
s : constant source := split_dword(input);
begin
return make_swapped(target'(a=>s.d, b=>s.c, c=>s.b, d=>s.a));
end byte_swap;
return Make_Swapped (Target (S) );
--
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14
Laurent Pautet
2003-10-23 20:36:32 UTC
Permalink
Post by chris
I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
have a look at s-strxdr.adb in gnat.
--
-- Laurent
Simon Wright
2003-10-23 21:37:39 UTC
Permalink
Post by Laurent Pautet
Post by chris
I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
have a look at s-strxdr.adb in gnat.
This is only in supported versions, I think (3.16a1, 5.01a).

The same (or very similar) text is in the version of s-strattr.adb in
the public glade-3.15p sources.
--
Simon Wright 100% Ada, no bugs.
Simon Wright
2003-10-24 04:37:13 UTC
Permalink
Post by Simon Wright
Post by Laurent Pautet
Post by chris
I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
have a look at s-strxdr.adb in gnat.
This is only in supported versions, I think (3.16a1, 5.01a).
The same (or very similar) text is in the version of s-strattr.adb in
the public glade-3.15p sources.
Sorry, that should have been s-stratt.adb (System.Stream_Attributes)
--
Simon Wright 100% Ada, no bugs.
Georg Bauhaus
2003-10-26 15:05:18 UTC
Permalink
Simon Wright <***@pushface.org> wrote:
: ***@antigone.enst.fr (Laurent Pautet) writes:
:
:> >I'm trying to implement reading 16 bit words from a stream with a given
:> >endianess (that is the endianess of the items in the stream is known),
:>
:> have a look at s-strxdr.adb in gnat.
:
: This is only in supported versions, I think (3.16a1, 5.01a).

It seems as if it's also in GCC 3.4.




Georg

Laurent Pautet
2003-10-23 20:44:48 UTC
Permalink
Post by chris
I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
have a look at s-strxdr.adb in gnat.
--
-- Laurent
Laurent Pautet
2003-10-23 21:03:21 UTC
Permalink
Post by chris
I'm trying to implement reading 16 bit words from a stream with a given
endianess (that is the endianess of the items in the stream is known),
have a look at s-strxdr.adb in gnat.
--
-- Laurent
Frank J. Lhota
2003-10-15 19:58:26 UTC
Permalink
Post by Bill Sheehan
Hello Folks,
Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?
Would there be a site with these functions available for download?
Thanks.
BillS
For which platform? For Windows, the Win32Ada child package WinSock includes
these functions. Presumably, the Linux compilers probably have something
like this.
Stephen Leake
2003-10-16 16:28:01 UTC
Permalink
Post by Bill Sheehan
Hello Folks,
Do Byte ordering functions (htonl, htons, ntohl, ntohs) exist in Ada?
Not in the standard. But SAL has them:
http://www.toadmail.com/~ada_wizard/

See sal-endianness.ads, sal-word_order_convert*.ads

Hmm, that's only for 16-bit words (for 1750A processors and 1553/1773
buses). I also have a version for 8-bit words in another project, I'll
have to move that into SAL. Email me if you need it now :).
--
-- Stephe
Loading...