From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,7e490a18b9688bd9 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Received: by 10.68.21.67 with SMTP id t3mr1402498pbe.26.1316132819734; Thu, 15 Sep 2011 17:26:59 -0700 (PDT) Path: m9ni7129pbd.0!nntp.google.com!news1.google.com!postnews.google.com!f41g2000yqh.googlegroups.com!not-for-mail From: Alexander Korolev Newsgroups: comp.lang.ada Subject: Re: Stream_Element_Array Date: Thu, 15 Sep 2011 17:20:00 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: <1e6rw4vto3ldb.i8d7fxixapx4.dlg@40tude.net> <28u4e86fk8gn$.ialexttobgr0$.dlg@40tude.net> <276b8d0a-5b3c-4559-a275-98620657cc2f@s30g2000pri.googlegroups.com> <01c12338-e9f8-49ab-863d-c8282be3875e@g31g2000yqh.googlegroups.com> <1esmml9qftomp.vihelaijmcar$.dlg@40tude.net> NNTP-Posting-Host: 96.49.119.210 Mime-Version: 1.0 X-Trace: posting.google.com 1316132819 7932 127.0.0.1 (16 Sep 2011 00:26:59 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 16 Sep 2011 00:26:59 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: f41g2000yqh.googlegroups.com; posting-host=96.49.119.210; posting-account=9aAl4woAAACPkuvNJOQxyBXxG_5lfu_0 User-Agent: G2/1.0 X-Google-Web-Client: true X-Google-Header-Order: HUARLECNK X-HTTP-UserAgent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ru-ru) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5,gzip(gfe) Xref: news1.google.com comp.lang.ada:17986 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2011-09-15T17:20:00-07:00 List-Id: On Sep 16, 12:48=A0am, "Dmitry A. Kazakov" wrote: > On Thu, 15 Sep 2011 11:58:21 -0700 (PDT), Alexander Korolev wrote: > > On Sep 15, 12:20 pm, "Dmitry A. Kazakov" > > 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 usua= lly > >> 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 u= se > >> 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'Writ= e > >>> attribute and send to Serial port ... Your approach is to create a ne= w > >>> stream actully, which will take into account the PROTOCOL specifics. > >>> Absolutly agree with that. But what is wrong with manual approach I a= m > >>> 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 > > =A0 =A0in Volatile Stream. The Last set to 3? It looks I am getting > > =A0 =A0there 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: > > =A0 =A0with Volatile_Streams; =A0use Volatile_Streams; > =A0 =A0with Ada.Streams; =A0 =A0 =A0 use Ada.Streams; > =A0 =A0with Interfaces; =A0 =A0 =A0 =A0use Interfaces; > > =A0 =A0package Frame_Streams is > =A0 =A0 =A0 Protocol_Error : exception; > =A0 =A0 =A0 -- > =A0 =A0 =A0 -- Implements frame I/O layer over the stream transport. > =A0 =A0 =A0 -- In this case the transport is memory-resident stream. > =A0 =A0 =A0 -- > =A0 =A0 =A0 type Frame_Stream (Size : Stream_Element_Count) is > =A0 =A0 =A0 =A0 =A0tagged limited private; > =A0 =A0 =A0 =A0 =A0-- Send frame, Data is the frame body > =A0 =A0 =A0 procedure Send > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ( =A0Stream : in out Frame_Stream; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Data =A0 : Stream_Element_Array > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ); > =A0 =A0 =A0 =A0 =A0-- Receive frame, Data is the frame body, Last its las= t item > =A0 =A0 =A0 =A0 =A0-- Protocol_Error is propagated upon protocol errors > =A0 =A0 =A0 procedure Receive > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ( =A0Stream : in out Frame_Stream; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Data =A0 : out Stream_Element_Arra= y; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Last =A0 : out Stream_Element_Offs= et > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ); > =A0 =A0private > =A0 =A0 =A0 Max_Frame_Size : constant :=3D 256; > =A0 =A0 =A0 type Frame_Stream =A0(Size : Stream_Element_Count) is > =A0 =A0 =A0 =A0 =A0new Memory_Resident_Stream (Size) with > =A0 =A0 =A0 record > =A0 =A0 =A0 =A0 =A0Output : Stream_Element_Array (1..Max_Frame_Size); > =A0 =A0 =A0 end record; > =A0 =A0end Frame_Streams; > > =A0 =A0package body Frame_Streams is > =A0 =A0 =A0 procedure Send > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ( =A0Stream : in out Frame_Stream; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Data =A0 : Stream_Element_Array > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ) =A0is > =A0 =A0 =A0 =A0 =A0Sum : Unsigned_8 :=3D 0; > =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0if Data'Length + 4 > Stream.Output'Length then > =A0 =A0 =A0 =A0 =A0 =A0 raise Constraint_Error with "Packet is too large"= ; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0Stream.Output (1) :=3D 0; > =A0 =A0 =A0 =A0 =A0Stream.Output (2) :=3D Stream_Element'Val (Data'Length= / 256); > =A0 =A0 =A0 =A0 =A0Stream.Output (3) :=3D Stream_Element'Val (Data'Length= mod 256); > =A0 =A0 =A0 =A0 =A0Stream.Output (4..3 + Data'Length) :=3D Data; > =A0 =A0 =A0 =A0 =A0for Index in Stream_Element_Offset > =A0 =A0 =A0 =A0 =A0 =A0 =A0range 2..3 + Data'Length > =A0 =A0 =A0 =A0 =A0loop > =A0 =A0 =A0 =A0 =A0 =A0 Sum :=3D Sum + Stream_Element'Pos (Stream.Output = (Index)); > =A0 =A0 =A0 =A0 =A0end loop; > =A0 =A0 =A0 =A0 =A0Stream.Output (4 + Data'Length) :=3D Stream_Element'Va= l (Sum); > =A0 =A0 =A0 =A0 =A0Stream.Write (Stream.Output (1..4 + Data'Length)); > =A0 =A0 =A0 end Send; > > =A0 =A0 =A0 procedure Receive > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ( =A0Stream : in out Frame_Stream; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Data =A0 : out Stream_Element_Arra= y; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Last =A0 : out Stream_Element_Offs= et > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ) =A0is > =A0 =A0 =A0 =A0 =A0Length : Stream_Element_Offset; > =A0 =A0 =A0 =A0 =A0Sum =A0 =A0: Unsigned_8; > =A0 =A0 =A0 =A0 =A0Input =A0: Stream_Element_Array (1..2); > =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0Stream.Read (Input (1..1), Last); > =A0 =A0 =A0 =A0 =A0if Last /=3D 2 then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Frame header expected"= ; > =A0 =A0 =A0 =A0 =A0elsif Input (1) /=3D 0 then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Wrong leading byte"; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0Stream.Read (Input (1..2), Last); > =A0 =A0 =A0 =A0 =A0Length :=3D Stream_Element'Pos (Input (1)) * 256 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0+ Stream_Element'Pos (Input (2)); > =A0 =A0 =A0 =A0 =A0if Last /=3D 3 then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Unexpected end of stre= am"; =A0 =A0 =A0 =A0 =A0 =A0 > =A0 =A0 =A0 =A0 =A0elsif Length > Data'Length then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Frame is too large"; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0Sum :=3D Stream_Element'Pos (Input (1)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 + Stream_Element'Pos (Input (2)); > =A0 =A0 =A0 =A0 =A0Stream.Read (Data (Data'First..Data'First + Length - 1= ), Last); > =A0 =A0 =A0 =A0 =A0if Last /=3D Data'First + Length then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Unexpected end of stre= am"; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0Stream.Read (Input (1..1), Last); > =A0 =A0 =A0 =A0 =A0if Last /=3D 2 then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Unexpected end of stre= am"; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0Last :=3D Data'First + Length - 1; > =A0 =A0 =A0 =A0 =A0for Index in Data'First..Last loop > =A0 =A0 =A0 =A0 =A0 =A0 Sum :=3D Sum + Stream_Element'Pos (Data (Index)); > =A0 =A0 =A0 =A0 =A0end loop; > =A0 =A0 =A0 =A0 =A0if Sum /=3D Stream_Element'Pos (Input (1)) then > =A0 =A0 =A0 =A0 =A0 =A0 raise Protocol_Error with "Checksum error"; > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 end Receive; > =A0 =A0end Frame_Streams; > > To be used as follows: > > =A0 =A0with Ada.Text_IO; =A0 =A0 use Ada.Text_IO; > =A0 =A0with Frame_Streams; =A0use Frame_Streams; > > =A0 =A0procedure Put (Data : Stream_Element_Array) is > =A0 =A0begin > =A0 =A0 =A0 for Index in Data'Range loop > =A0 =A0 =A0 =A0 =A0Put (Stream_Element'Image (Data (Index))); > =A0 =A0 =A0 =A0 =A0Put (' '); > =A0 =A0 =A0 end loop; > =A0 =A0end Put; > > =A0 =A0S : aliased Frame_Stream (1024); > =A0 =A0Buffer : Stream_Element_Array (1..4); > =A0 =A0Last =A0 : Stream_Element_Offset; > begin > =A0 =A0S.Send ((1, 2, 3, 4)); > =A0 =A0Put_Line ("Written:" & Stream_Element_Count'Image (S.Extent)); > =A0 =A0S.Receive (Buffer, Last); > =A0 =A0Put_Line ("Read:"); > =A0 =A0Put (Buffer (1..Last)); > end; > > Note that is in its turn is frame I/O layer. Upon it you will have anothe= r > layer and so on up to the application layer. > > P.S. It is a bit simplified, if there are many transports layers, the fra= me > 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.