comp.lang.ada
 help / color / mirror / Atom feed
From: Alexander Korolev <antonovkablog@gmail.com>
Subject: Re: Stream_Element_Array
Date: Thu, 15 Sep 2011 17:20:00 -0700 (PDT)
Date: 2011-09-15T17:20:00-07:00	[thread overview]
Message-ID: <d08e78f3-e697-4e93-b377-0729807d48fc@f41g2000yqh.googlegroups.com> (raw)
In-Reply-To: vd7r3qy6mkdn.1hap5hmaa0pkx$.dlg@40tude.net

On Sep 16, 12:48 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 15 Sep 2011 11:58:21 -0700 (PDT), Alexander Korolev wrote:
> > On Sep 15, 12:20 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> On Wed, 14 Sep 2011 14:29:41 -0700 (PDT), Alexander Korolev wrote:
> >>> "In your case the other end is not the memory but the wire"
> >>> I am not sure I undestand you complitly. What's wrong, at least for
> >>> now, to build \ construct in memory the Buffer (Stream_Element_Array)
> >>> with full command (according the format I posted) inside and after
> >>> that send it over any stream (including GNAT.Serial, Socket etc)
> >>> derived from Root_Stream_Type. Basicly, I don't need even a Type -
> >>> I am using it just get Unsigned_16 serialized into Stream Elements.
>
> >> Yes, but in most cases it does not work so straightforwardly. You usually
> >> need headers, checksums etc. The point is that you have more layers of the
> >> protocol than just raw values over stream of octets. This is why you use
> >> stream rather as a transport for packets/messages and often more upper
> >> levels too (state machine etc). The idea is to always encapsulate each
> >> level into a data type. It saves much time later.
>
> >>> That's it. It's kind of hadcrafting. I also can override My_Type'Write
> >>> attribute and send to Serial port ... Your approach is to create a new
> >>> stream actully, which will take into account the PROTOCOL specifics.
> >>> Absolutly agree with that. But what is wrong with manual approach I am
> >>> implementing.
>
> >> It is not wrong, it is just might not work because protocols are more
> >> complex (layered) than this simple model.
>
> > 1. Can not disagree again - layers, state machines is "must" part.
> > 2. So far got some interim results with serialization of the Type
> >    in Volatile Stream. The Last set to 3? It looks I am getting
> >    there but no confidence so far.
>
> Volatile Stream has a bug in its implementation. Last is actually "Next".
>
> Anyway, here is how I do such stuff:
>
>    with Volatile_Streams;  use Volatile_Streams;
>    with Ada.Streams;       use Ada.Streams;
>    with Interfaces;        use Interfaces;
>
>    package Frame_Streams is
>       Protocol_Error : exception;
>       --
>       -- Implements frame I/O layer over the stream transport.
>       -- In this case the transport is memory-resident stream.
>       --
>       type Frame_Stream (Size : Stream_Element_Count) is
>          tagged limited private;
>          -- Send frame, Data is the frame body
>       procedure Send
>                 (  Stream : in out Frame_Stream;
>                    Data   : Stream_Element_Array
>                 );
>          -- Receive frame, Data is the frame body, Last its last item
>          -- Protocol_Error is propagated upon protocol errors
>       procedure Receive
>                 (  Stream : in out Frame_Stream;
>                    Data   : out Stream_Element_Array;
>                    Last   : out Stream_Element_Offset
>                 );
>    private
>       Max_Frame_Size : constant := 256;
>       type Frame_Stream  (Size : Stream_Element_Count) is
>          new Memory_Resident_Stream (Size) with
>       record
>          Output : Stream_Element_Array (1..Max_Frame_Size);
>       end record;
>    end Frame_Streams;
>
>    package body Frame_Streams is
>       procedure Send
>                 (  Stream : in out Frame_Stream;
>                    Data   : Stream_Element_Array
>                 )  is
>          Sum : Unsigned_8 := 0;
>       begin
>          if Data'Length + 4 > Stream.Output'Length then
>             raise Constraint_Error with "Packet is too large";
>          end if;
>          Stream.Output (1) := 0;
>          Stream.Output (2) := Stream_Element'Val (Data'Length / 256);
>          Stream.Output (3) := Stream_Element'Val (Data'Length mod 256);
>          Stream.Output (4..3 + Data'Length) := Data;
>          for Index in Stream_Element_Offset
>              range 2..3 + Data'Length
>          loop
>             Sum := Sum + Stream_Element'Pos (Stream.Output (Index));
>          end loop;
>          Stream.Output (4 + Data'Length) := Stream_Element'Val (Sum);
>          Stream.Write (Stream.Output (1..4 + Data'Length));
>       end Send;
>
>       procedure Receive
>                 (  Stream : in out Frame_Stream;
>                    Data   : out Stream_Element_Array;
>                    Last   : out Stream_Element_Offset
>                 )  is
>          Length : Stream_Element_Offset;
>          Sum    : Unsigned_8;
>          Input  : Stream_Element_Array (1..2);
>       begin
>          Stream.Read (Input (1..1), Last);
>          if Last /= 2 then
>             raise Protocol_Error with "Frame header expected";
>          elsif Input (1) /= 0 then
>             raise Protocol_Error with "Wrong leading byte";
>          end if;
>          Stream.Read (Input (1..2), Last);
>          Length := Stream_Element'Pos (Input (1)) * 256
>                  + Stream_Element'Pos (Input (2));
>          if Last /= 3 then
>             raise Protocol_Error with "Unexpected end of stream";            
>          elsif Length > Data'Length then
>             raise Protocol_Error with "Frame is too large";
>          end if;
>          Sum := Stream_Element'Pos (Input (1))
>               + Stream_Element'Pos (Input (2));
>          Stream.Read (Data (Data'First..Data'First + Length - 1), Last);
>          if Last /= Data'First + Length then
>             raise Protocol_Error with "Unexpected end of stream";
>          end if;
>          Stream.Read (Input (1..1), Last);
>          if Last /= 2 then
>             raise Protocol_Error with "Unexpected end of stream";
>          end if;
>          Last := Data'First + Length - 1;
>          for Index in Data'First..Last loop
>             Sum := Sum + Stream_Element'Pos (Data (Index));
>          end loop;
>          if Sum /= Stream_Element'Pos (Input (1)) then
>             raise Protocol_Error with "Checksum error";
>          end if;
>       end Receive;
>    end Frame_Streams;
>
> To be used as follows:
>
>    with Ada.Text_IO;     use Ada.Text_IO;
>    with Frame_Streams;  use Frame_Streams;
>
>    procedure Put (Data : Stream_Element_Array) is
>    begin
>       for Index in Data'Range loop
>          Put (Stream_Element'Image (Data (Index)));
>          Put (' ');
>       end loop;
>    end Put;
>
>    S : aliased Frame_Stream (1024);
>    Buffer : Stream_Element_Array (1..4);
>    Last   : Stream_Element_Offset;
> begin
>    S.Send ((1, 2, 3, 4));
>    Put_Line ("Written:" & Stream_Element_Count'Image (S.Extent));
>    S.Receive (Buffer, Last);
>    Put_Line ("Read:");
>    Put (Buffer (1..Last));
> end;
>
> Note that is in its turn is frame I/O layer. Upon it you will have another
> layer and so on up to the application layer.
>
> P.S. It is a bit simplified, if there are many transports layers, the frame
> layer would take the actual transport as a discriminant (access to
> Root_Stream'Class) or a generic parameter. In your case it would be an
> overkill.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks. Will help.




  reply	other threads:[~2011-09-16  0:26 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-14  3:13 Stream_Element_Array Alexander Korolev
2011-09-14  5:29 ` Stream_Element_Array Per Sandberg
2011-09-14  8:34   ` Stream_Element_Array Alexander Korolev
2011-09-14  8:31 ` Stream_Element_Array Simon Wright
2011-09-14  9:09   ` Stream_Element_Array Alexander Korolev
2011-09-14  9:40     ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14  9:41       ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 10:18         ` Stream_Element_Array Simon Wright
2011-09-14 12:42           ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 16:20             ` Stream_Element_Array Simon Wright
2011-09-14 19:53               ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 10:53       ` Stream_Element_Array Simon Wright
2011-09-14 12:48         ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 14:48           ` Stream_Element_Array Alexander Korolev
2011-09-14 15:08             ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 17:16               ` Stream_Element_Array Alexander Korolev
2011-09-14 20:13                 ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 21:29                   ` Stream_Element_Array Alexander Korolev
2011-09-15  8:20                     ` Stream_Element_Array Dmitry A. Kazakov
2011-09-15 18:58                       ` Stream_Element_Array Alexander Korolev
2011-09-15 20:48                         ` Stream_Element_Array Dmitry A. Kazakov
2011-09-16  0:20                           ` Alexander Korolev [this message]
2011-09-15 19:15                       ` Stream_Element_Array Alexander Korolev
2011-09-15 20:11                         ` Stream_Element_Array Simon Wright
2011-09-15 20:34                           ` Stream_Element_Array Alexander Korolev
2011-09-15 21:42                             ` Stream_Element_Array Simon Wright
2011-09-15 21:50                               ` Stream_Element_Array Simon Wright
2011-09-16  0:01                                 ` Stream_Element_Array Alexander Korolev
2011-09-16  0:18                               ` Stream_Element_Array Adam Beneschan
2011-09-16  7:22                                 ` Stream_Element_Array Dmitry A. Kazakov
2011-09-16 10:21                                   ` Stream_Element_Array Simon Wright
2011-09-16 12:13                                     ` Stream_Element_Array Dmitry A. Kazakov
2011-09-16 17:20                                       ` Stream_Element_Array Simon Wright
2011-09-16 19:32                                         ` Stream_Element_Array Dmitry A. Kazakov
2011-09-16 22:18                                           ` Stream_Element_Array Simon Wright
2011-09-17  8:18                                             ` Stream_Element_Array Dmitry A. Kazakov
2011-09-19 23:22                                   ` Stream_Element_Array Randy Brukardt
2011-09-15 21:28                           ` Stream_Element_Array Alexander Korolev
2011-09-15  2:33                   ` Stream_Element_Array Alexander Korolev
2011-09-19 23:11           ` Stream_Element_Array Randy Brukardt
2011-09-14 12:19 ` Stream_Element_Array Gautier write-only
2011-09-16 11:17 ` Stream_Element_Array anon
replies disabled

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