From: "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com>
Subject: Re: Decoding an octet stream
Date: 1999/11/29
Date: 1999-11-29T14:20:55+00:00 [thread overview]
Message-ID: <81u247$kc3$1@hobbes2.crc.com> (raw)
In-Reply-To: 877lj2q36g.fsf@deneb.cygnus.argh.org
Florian Weimer <" "@deneb.cygnus.argh.org> wrote in message
news:877lj2q36g.fsf@deneb.cygnus.argh.org...
> What is the best way to decode an octet stream (i.e. a sequence of
> unsigned eight-bit values) with Ada? The octet stream consists of
> packet markes (single octets), two-octet integers (stored with the
> most significant octet first), strings (sequences of octets of a given
> length) and so on. I don't want to use Ada.Sequential_IO, because it
> would mean that only one octet can be read at a time, which seems to
> be quite inefficient.
>
> Streams seem to be nice, though. If I specify the necessary
> representation clauses, I think I'll only have to write a few 'Read
> and 'Write operations, and composed types will be handled correctly
> almost automatically. But is this really portable? Are there any
> targets (except supercomputers, mainframes, and embedded systems)
> where Stream_Element'Size isn't equal to 8?
>
> BTW: I'm currently reading the two-octet integers using a construct like
> `First_Octet * 2**8 + Second_Octet'. Is it possible to denote the octet
> ordering using a representation clause? For a target with a matching
> octet order, more efficient code could be generated.
Here's a package I use for just that purpose. All two- and four-byte
scalar types used in network packets have their 'read and 'write
attributes overridden by instances of these generic procedures.
------------------------------------------------------------------------
-- Byte_Ordering
-- Purpose:
-- Instantiations of the generic procedures provided by This package
-- are Read and Write procedures fully-conformant with the 'Read and
-- 'Write attributes of the type with which the procedure was
-- instantiated.
-- The procedures transform the stream to network order, according to
-- the endianness of the target host.
-- Thus, instantiations of these procedures may be used to override
-- the default stream-oriented attributes of scalar types, so that
-- their stream reads and writes are done in network order,
-- irrespective of host ordering (endianness).
------------------------------------------------------------------------
with Ada.Streams;
package Byte_Ordering is
generic
type Item_Type is private;
procedure Read
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Item_type);
generic
type Item_Type is private;
procedure Write
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : Item_type);
end Byte_Ordering;
with System;
package body Byte_Ordering is
type U8 is mod 2 ** 8;
for U8'Size use 8;
type U8_Array is array (Integer range <>) of U8;
--=======================
-- Private subprograms ==
--=======================
----------
-- Swap --
----------
procedure Swap
(The_Item : in out U8_Array)
is
The_Bytes : array (1 .. The_Item'Size / U8'Size) of U8;
for The_Bytes'Address use The_Item'Address;
Temp : U8;
begin
for B in 1 .. The_Bytes'Last / 2 loop
Temp := The_Bytes (B);
The_Bytes (B) := The_Bytes (The_Bytes'Last - B + 1);
The_Bytes (The_Bytes'Last - B + 1) := temp;
end loop;
end Swap;
--======================
-- Public subprograms ==
--======================
----------
-- Read --
----------
procedure Read
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Item_type)
is
The_Bytes : U8_Array (1 .. Item'Size / U8'Size);
for The_Bytes'Address use Item'Address;
use type System.Bit_Order;
begin
U8_Array'Read (Stream, The_Bytes);
if System.Default_Bit_Order = System.Low_Order_First then
Swap (The_Bytes);
end if;
end Read;
-----------
-- Write --
-----------
procedure Write
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : Item_Type)
is
Item_Copy : Item_type := Item;
The_Bytes : U8_Array (1 .. Item_Copy'Size / U8'Size);
for The_Bytes'Address use Item'Address;
use type System.Bit_Order;
begin
if System.Default_Bit_Order = System.Low_Order_First then
Swap (The_Bytes);
end if;
U8_Array'Write (Stream, The_Bytes);
end Write;
end Byte_Ordering;
next prev parent reply other threads:[~1999-11-29 0:00 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-11-28 0:00 Decoding an octet stream Florian Weimer
1999-11-29 0:00 ` David C. Hoos, Sr. [this message]
1999-11-30 0:00 ` Florian Weimer
1999-12-03 0:00 ` Robert Dewar
1999-12-01 0:00 ` Robert Dewar
1999-12-01 0:00 ` Geoff Bull
1999-12-01 0:00 ` Robert Dewar
1999-12-01 0:00 ` David C. Hoos, Sr.
1999-12-01 0:00 ` Robert Dewar
1999-12-07 0:00 ` Stefan Skoglund
1999-12-01 0:00 ` swhalen
1999-12-01 0:00 ` Larry Kilgallen
1999-12-01 0:00 ` Kenneth Almquist
1999-12-02 0:00 ` Geoff Bull
1999-12-02 0:00 ` Stupid patent tricks (was: Decoding an octet stream) Ted Dennison
1999-12-06 0:00 ` Decoding an octet stream Kenneth Almquist
1999-12-01 0:00 ` Florian Weimer
1999-12-02 0:00 ` Robert Dewar
1999-12-02 0:00 ` Geoff Bull
1999-12-02 0:00 ` Lutz Donnerhacke
1999-12-02 0:00 ` Ted Dennison
1999-12-02 0:00 ` tmoran
1999-12-02 0:00 ` Geoff Bull
1999-12-02 0:00 ` swhalen
1999-12-02 0:00 ` Larry Kilgallen
1999-12-03 0:00 ` Geoff Bull
1999-12-03 0:00 ` swhalen
1999-12-04 0:00 ` Robert Dewar
1999-12-04 0:00 ` Geoff Bull
1999-12-06 0:00 ` Robert Dewar
1999-12-06 0:00 ` Richard D Riehle
1999-12-06 0:00 ` Ed Falis
1999-12-07 0:00 ` Ted Dennison
1999-12-08 0:00 ` Robert Dewar
1999-12-08 0:00 ` Brian Rogoff
1999-12-02 0:00 ` Robert Dewar
1999-12-08 0:00 ` Numeric types Mario Amado Alves
1999-12-08 0:00 ` Tucker Taft
1999-12-01 0:00 ` Decoding an octet stream Robert Dewar
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox