comp.lang.ada
 help / color / mirror / Atom feed
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;







  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