comp.lang.ada
 help / color / mirror / Atom feed
* Stream_Element_Array
@ 2011-09-14  3:13 Alexander Korolev
  2011-09-14  5:29 ` Stream_Element_Array Per Sandberg
                   ` (3 more replies)
  0 siblings, 4 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14  3:13 UTC (permalink / raw)


I have a Type

type Message_Header is
    record
       -- Components                  --   8 bit
       Length    : Unsigned_16;    -- 16 bit  (MSB)
       -- other components          --   8 bit
    end record;

How I could split the Lenght component on two subsequent
Stream_Element ( 8-bit)?

Command: Stream_Element_Array (1 .. 64);

Thanks



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  3:13 Stream_Element_Array Alexander Korolev
@ 2011-09-14  5:29 ` Per Sandberg
  2011-09-14  8:34   ` Stream_Element_Array Alexander Korolev
  2011-09-14  8:31 ` Stream_Element_Array Simon Wright
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 42+ messages in thread
From: Per Sandberg @ 2011-09-14  5:29 UTC (permalink / raw)


Why not just:
   Message_Header'Write(Output_Stream,My_Message_Header)
That would serialize the Data into the stream.

If the target stream is a blocked message why not do
   Message_Header'Write(Buffer_Stream,My_Message_Header)
   Buffer_Stream'Write(Output_Stream,Buffer_Stream)

And the Buffer_Stream is a stream of the kind found in:
    http://sourceforge.net/projects/ada-spread/
         spread-memory_streams.*
or

https://github.com/persan/zeromq-Ada
    zmq-utilities-memory_streams.ad

Which now is part of fedora15
/Per




On 09/14/2011 05:13 AM, Alexander Korolev wrote:
> I have a Type
>
> type Message_Header is
>      record
>         -- Components                  --   8 bit
>         Length    : Unsigned_16;    -- 16 bit  (MSB)
>         -- other components          --   8 bit
>      end record;
>
> How I could split the Lenght component on two subsequent
> Stream_Element ( 8-bit)?
>
> Command: Stream_Element_Array (1 .. 64);
>
> Thanks



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  3:13 Stream_Element_Array Alexander Korolev
  2011-09-14  5:29 ` Stream_Element_Array Per Sandberg
@ 2011-09-14  8:31 ` Simon Wright
  2011-09-14  9:09   ` Stream_Element_Array Alexander Korolev
  2011-09-14 12:19 ` Stream_Element_Array Gautier write-only
  2011-09-16 11:17 ` Stream_Element_Array anon
  3 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-14  8:31 UTC (permalink / raw)


Alexander Korolev <antonovkablog@gmail.com> writes:

> I have a Type
>
> type Message_Header is
>     record
>        -- Components                  --   8 bit
>        Length    : Unsigned_16;    -- 16 bit  (MSB)
>        -- other components          --   8 bit
>     end record;
>
> How I could split the Lenght component on two subsequent
> Stream_Element ( 8-bit)?
>
> Command: Stream_Element_Array (1 .. 64);

I think the best way is using unchecked conversion. Below adds the
complication of converting to network byte order if not already so:

   subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);


   Big_Endian : constant Boolean
     := System."=" (System.Default_Bit_Order, System.High_Order_First);


   function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
      function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
                                                        Two_Byte_Slice);
      Tmp : constant Two_Byte_Slice := Convert (S);
   begin
      if Big_Endian then
         return Tmp;
      else
         return (1 => Tmp (2),
                 2 => Tmp (1));
      end if;
   end To_Two_Byte_Slice;


   Command (11 .. 12) := To_Two_Byte_Slice (42);




^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  5:29 ` Stream_Element_Array Per Sandberg
@ 2011-09-14  8:34   ` Alexander Korolev
  0 siblings, 0 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14  8:34 UTC (permalink / raw)


On Sep 14, 9:29 am, Per Sandberg <per.sandb...@bredband.net> wrote:
> Why not just:
>    Message_Header'Write(Output_Stream,My_Message_Header)
> That would serialize the Data into the stream.
>
> If the target stream is a blocked message why not do
>    Message_Header'Write(Buffer_Stream,My_Message_Header)
>    Buffer_Stream'Write(Output_Stream,Buffer_Stream)
>
> And the Buffer_Stream is a stream of the kind found in:
>    http://sourceforge.net/projects/ada-spread/
>          spread-memory_streams.*
> or
>
> https://github.com/persan/zeromq-Ada
>     zmq-utilities-memory_streams.ad
>
> Which now is part of fedora15
> /Per
>
> On 09/14/2011 05:13 AM, Alexander Korolev wrote:
>
>
>
> > I have a Type
>
> > type Message_Header is
> >      record
> >         -- Components                  --   8 bit
> >         Length    : Unsigned_16;    -- 16 bit  (MSB)
> >         -- other components          --   8 bit
> >      end record;
>
> > How I could split the Lenght component on two subsequent
> > Stream_Element ( 8-bit)?
>
> > Command: Stream_Element_Array (1 .. 64);
>
> > Thanks

Thanks Per

I've just tried with GNAT a similar to your suggestion aproach

In_Memory_Stream:Volatile_Streams.Memory_Resident_Stream (Size =>
128);
Message_Length:Stream_Element_Array(1..2);
Last:Stream_Element_Count;
Msg_Header_Instance:Message_Header;

Begin

Message_Header'Write(In_Memory_Stream, Msg_Header_Instance);
--  writes to meomory
read (In_Memory_Stream,Message_Length,Last);
-- retreives Message_Length wich is Stream_Element_Array -- and the
Last
-- I left only one component in Message_Header - the Lengh, expected
-- the Last = 2, and Message_Length instance filled in after read
(...).
--
End;

Complaints on compilation: "expected access to
Ada.Streams.Root_Stream_Type'Access"



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  8:31 ` Stream_Element_Array Simon Wright
@ 2011-09-14  9:09   ` Alexander Korolev
  2011-09-14  9:40     ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14  9:09 UTC (permalink / raw)


On Sep 14, 12:31 pm, Simon Wright <si...@pushface.org> wrote:
> Alexander Korolev <antonovkab...@gmail.com> writes:
> > I have a Type
>
> > type Message_Header is
> >     record
> >        -- Components                  --   8 bit
> >        Length    : Unsigned_16;    -- 16 bit  (MSB)
> >        -- other components          --   8 bit
> >     end record;
>
> > How I could split the Lenght component on two subsequent
> > Stream_Element ( 8-bit)?
>
> > Command: Stream_Element_Array (1 .. 64);
>
> I think the best way is using unchecked conversion. Below adds the
> complication of converting to network byte order if not already so:
>
>    subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);
>
>    Big_Endian : constant Boolean
>      := System."=" (System.Default_Bit_Order, System.High_Order_First);
>
>    function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
>       function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
>                                                         Two_Byte_Slice);
>       Tmp : constant Two_Byte_Slice := Convert (S);
>    begin
>       if Big_Endian then
>          return Tmp;
>       else
>          return (1 => Tmp (2),
>                  2 => Tmp (1));
>       end if;
>    end To_Two_Byte_Slice;
>
>    Command (11 .. 12) := To_Two_Byte_Slice (42);

Thanks Simon
I'll try your code anyway.
-- I thought I might made the issue more complex
The Unsigned_16 came from transformation of the Header_Type component
by Interfaces.Unsigned_16 (Last).
It means I have Last: Stream_Element_Count (8 bit) set correctly.
-- (Note For Per: I can not send the lenth to target stream because
the whole
-- message (stream_element_array) assembled needs further computation
over + one transformation
-- (staffing - something like replace 111 with 444 + 555 if 111
occures in some components of the message including
-- the letgh ) after the computation as an external dev requirement




^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  9:09   ` Stream_Element_Array Alexander Korolev
@ 2011-09-14  9:40     ` Dmitry A. Kazakov
  2011-09-14  9:41       ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-14 10:53       ` Stream_Element_Array Simon Wright
  0 siblings, 2 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14  9:40 UTC (permalink / raw)


On Wed, 14 Sep 2011 02:09:15 -0700 (PDT), Alexander Korolev wrote:

> On Sep 14, 12:31�pm, Simon Wright <si...@pushface.org> wrote:
>> Alexander Korolev <antonovkab...@gmail.com> writes:
>>> I have a Type
>>
>>> type Message_Header is
>>> � � record
>>> � � � �-- Components � � � � � � � � �-- � 8 bit
>>> � � � �Length � �: Unsigned_16; � �-- 16 bit �(MSB)
>>> � � � �-- other components � � � � �-- � 8 bit
>>> � � end record;
>>
>>> How I could split the Lenght component on two subsequent
>>> Stream_Element ( 8-bit)?
>>
>>> Command: Stream_Element_Array (1 .. 64);
>>
>> I think the best way is using unchecked conversion. Below adds the
>> complication of converting to network byte order if not already so:
>>
>> � �subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);
>>
>> � �Big_Endian : constant Boolean
>> � � �:= System."=" (System.Default_Bit_Order, System.High_Order_First);
>>
>> � �function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
>> � � � function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
>> � � � � � � � � � � � � � � � � � � � � � � � � � � � � Two_Byte_Slice);
>> � � � Tmp : constant Two_Byte_Slice := Convert (S);
>> � �begin
>> � � � if Big_Endian then
>> � � � � �return Tmp;
>> � � � else
>> � � � � �return (1 => Tmp (2),
>> � � � � � � � � �2 => Tmp (1));
>> � � � end if;
>> � �end To_Two_Byte_Slice;
>>
>> � �Command (11 .. 12) := To_Two_Byte_Slice (42);
> 
> Thanks Simon
> I'll try your code anyway.
> -- I thought I might made the issue more complex
> The Unsigned_16 came from transformation of the Header_Type component
> by Interfaces.Unsigned_16 (Last).
> It means I have Last: Stream_Element_Count (8 bit) set correctly.
> -- (Note For Per: I can not send the lenth to target stream because
> the whole
> -- message (stream_element_array) assembled needs further computation
> over + one transformation
> -- (staffing - something like replace 111 with 444 + 555 if 111
> occures in some components of the message including
> -- the letgh ) after the computation as an external dev requirement

Here is the pattern I am using:

   Put (Destination : in out Stream_Element_Array;
      Index : in out Stream_Element_Offset;
      Data : <the data type>
   );

   Get (Source : Stream_Element_Array;
      Index : in out Stream_Element_Offset;
      Data : out <the data type>
   );

Index indicates the position to start at. It is advanced after the put/get
elements of the buffer.

You fill the output buffer using consequent calls to Put. Then send its
filled slice Buffer (Buffer'First..Index - 1) to the hardware.

The opposite direction works similarly. You take data from the input buffer
with consequent calls to Get.

Get and Put for composite types are implemented in terms of Get and Put of
integral types. Note that their representations need not to correspond to
the hardware layouts. You are free to use Ada types best suitable to the
application.

P.S. Do not use representation clauses or unchecked conversion, I *do* mean
it:
      -- Little endian implementation of Get for Unsigned_16
   procedure Get
             (  Source : Stream_Element_Array;
                Index  : in out Stream_Element_Offset;
                Data   : out Unsigned_16
             )  is
   begin
      Data := Stream_Element'Pos (Source (Index)) +
              Stream_Element'Pos (Source (Index + 1));
      Index := Index + 2;
   end Get;

P.P.S. Stream element might be not the best choice if you are communicating
with the external world. You could also consider taking Unsigned_8 and an
array built upon it, because in most cases the hardware talks in octets.
That does not change the pattern, of course.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  9:40     ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14  9:41       ` Dmitry A. Kazakov
  2011-09-14 10:18         ` Stream_Element_Array Simon Wright
  2011-09-14 10:53       ` Stream_Element_Array Simon Wright
  1 sibling, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14  9:41 UTC (permalink / raw)


On Wed, 14 Sep 2011 11:40:01 +0200, Dmitry A. Kazakov wrote:

>       -- Little endian implementation of Get for Unsigned_16
>    procedure Get
>              (  Source : Stream_Element_Array;
>                 Index  : in out Stream_Element_Offset;
>                 Data   : out Unsigned_16
>              )  is
>    begin
>       Data := Stream_Element'Pos (Source (Index)) +
>               Stream_Element'Pos (Source (Index + 1));

Rather:

       Stream_Element'Pos (Source (Index + 1)) * 256;
            
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  9:41       ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14 10:18         ` Simon Wright
  2011-09-14 12:42           ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-14 10:18 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Wed, 14 Sep 2011 11:40:01 +0200, Dmitry A. Kazakov wrote:
>
>>       -- Little endian implementation of Get for Unsigned_16
>>    procedure Get
>>              (  Source : Stream_Element_Array;
>>                 Index  : in out Stream_Element_Offset;
>>                 Data   : out Unsigned_16
>>              )  is
>>    begin
>>       Data := Stream_Element'Pos (Source (Index)) +
>>               Stream_Element'Pos (Source (Index + 1));
>
> Rather:
>
>        Stream_Element'Pos (Source (Index + 1)) * 256;

That's an implementation where both the stream and the processor are
little-endian.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  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:53       ` Simon Wright
  2011-09-14 12:48         ` Stream_Element_Array Dmitry A. Kazakov
  1 sibling, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-14 10:53 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> P.S. Do not use representation clauses or unchecked conversion, I *do*
> mean it:

I would of course agree if the data type didn't occupy the full width of
the buffer it was being converted into. I suppose that can happen quite
frequently? (I took OP's "Unsigned_16" to mean a 16-bit wide type).

Shouldn't be a similar problem with endianness conversions, though.

> P.P.S. Stream element might be not the best choice if you are
> communicating with the external world. You could also consider taking
> Unsigned_8 and an array built upon it, because in most cases the
> hardware talks in octets.  That does not change the pattern, of
> course.

I know the RM doesn't specify this, and goes out of its way to allow
9-bit bytes and 36-bit storage units. But how many real-life situations
are there where Stream_Element'Size isn't 8?

Of course, if your hardware registers are 16 or 32 bits wide, that's a
different ballgame.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  3:13 Stream_Element_Array Alexander Korolev
  2011-09-14  5:29 ` Stream_Element_Array Per Sandberg
  2011-09-14  8:31 ` Stream_Element_Array Simon Wright
@ 2011-09-14 12:19 ` Gautier write-only
  2011-09-16 11:17 ` Stream_Element_Array anon
  3 siblings, 0 replies; 42+ messages in thread
From: Gautier write-only @ 2011-09-14 12:19 UTC (permalink / raw)


> How I could split the Lenght component on two subsequent
> Stream_Element ( 8-bit)?

You can do like this:

http://unzip-ada.sourceforge.net/za_html/zip-headers__adb.htm

HTH
______________________________________________________________________________
Gautier's Ada programming -- http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 10:18         ` Stream_Element_Array Simon Wright
@ 2011-09-14 12:42           ` Dmitry A. Kazakov
  2011-09-14 16:20             ` Stream_Element_Array Simon Wright
  0 siblings, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14 12:42 UTC (permalink / raw)


On Wed, 14 Sep 2011 11:18:30 +0100, Simon Wright wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Wed, 14 Sep 2011 11:40:01 +0200, Dmitry A. Kazakov wrote:
>>
>>>       -- Little endian implementation of Get for Unsigned_16
>>>    procedure Get
>>>              (  Source : Stream_Element_Array;
>>>                 Index  : in out Stream_Element_Offset;
>>>                 Data   : out Unsigned_16
>>>              )  is
>>>    begin
>>>       Data := Stream_Element'Pos (Source (Index)) +
>>>               Stream_Element'Pos (Source (Index + 1));
>>
>> Rather:
>>
>>        Stream_Element'Pos (Source (Index + 1)) * 256;
> 
> That's an implementation where both the stream and the processor are
> little-endian.

It is an implementation when the format of unsigned 16 is little endian.
The processor endianness can be any, which is the point of doing it this
way.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 10:53       ` Stream_Element_Array Simon Wright
@ 2011-09-14 12:48         ` Dmitry A. Kazakov
  2011-09-14 14:48           ` Stream_Element_Array Alexander Korolev
  2011-09-19 23:11           ` Stream_Element_Array Randy Brukardt
  0 siblings, 2 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14 12:48 UTC (permalink / raw)


On Wed, 14 Sep 2011 11:53:13 +0100, Simon Wright wrote:

> I know the RM doesn't specify this, and goes out of its way to allow
> 9-bit bytes and 36-bit storage units. But how many real-life situations
> are there where Stream_Element'Size isn't 8?

Why not to mandate it 8-bit then? Even if the machine does not support
memory access to octets, I think it would be worth the efforts to have the
compiler doing packing/unpacking stuff, rather than the programmer.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 12:48         ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14 14:48           ` Alexander Korolev
  2011-09-14 15:08             ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-19 23:11           ` Stream_Element_Array Randy Brukardt
  1 sibling, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14 14:48 UTC (permalink / raw)


On Sep 14, 4:48 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 14 Sep 2011 11:53:13 +0100, Simon Wright wrote:
> > I know the RM doesn't specify this, and goes out of its way to allow
> > 9-bit bytes and 36-bit storage units. But how many real-life situations
> > are there where Stream_Element'Size isn't 8?
>
> Why not to mandate it 8-bit then? Even if the machine does not support
> memory access to octets, I think it would be worth the efforts to have the
> compiler doing packing/unpacking stuff, rather than the programmer.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks a lot Dmitry,
Just a note:
"Stream element might be not the best choice if you are communicating
with the external world"

I am talking to serial port via GNAT.Serial_Communication. The
Buffer it offers is Stream_Element_Array. And I need to do
computations (implemented assuming that the buffer is ok :) ) over the
buffer
before do the call.One of the formats receiving part expects is:
|Start(8bit|Length - 16 bit|Element1-8bit|Element-16bit|Checksum|
Write (S_Port,Buffer)





^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 14:48           ` Stream_Element_Array Alexander Korolev
@ 2011-09-14 15:08             ` Dmitry A. Kazakov
  2011-09-14 17:16               ` Stream_Element_Array Alexander Korolev
  0 siblings, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14 15:08 UTC (permalink / raw)


On Wed, 14 Sep 2011 07:48:47 -0700 (PDT), Alexander Korolev wrote:

> I am talking to serial port via GNAT.Serial_Communication. The
> Buffer it offers is Stream_Element_Array.

In that case it is OK to use Stream_Element.

> And I need to do
> computations (implemented assuming that the buffer is ok :) ) over the
> buffer
> before do the call.One of the formats receiving part expects is:
>|Start(8bit|Length - 16 bit|Element1-8bit|Element-16bit|Checksum|
> Write (S_Port,Buffer)

I usually allocate an output buffer in the "device object". The output
index as I described earlier is also stored there. The application level
fills the buffer and in the end call something like Device.Flush. Flush
calculates the checksum over 1..Index - 1, stores the result and finally
calls Write.

BTW, it is highly recommended to use asynchronous read, or a synchronous
one from an independent task. You should always be ready to read next byte
from the device. Otherwise you risk to run into a deadlock upon protocol
errors.

You might also wish to write asynchronously (to improve performance), but
beware that most serial devices, at least those I saw, are broken and just
crash when full duplex I/O attempted.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 12:42           ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14 16:20             ` Simon Wright
  2011-09-14 19:53               ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-14 16:20 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Wed, 14 Sep 2011 11:18:30 +0100, Simon Wright wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On Wed, 14 Sep 2011 11:40:01 +0200, Dmitry A. Kazakov wrote:
>>>
>>>>       -- Little endian implementation of Get for Unsigned_16
>>>>    procedure Get
>>>>              (  Source : Stream_Element_Array;
>>>>                 Index  : in out Stream_Element_Offset;
>>>>                 Data   : out Unsigned_16
>>>>              )  is
>>>>    begin
>>>>       Data := Stream_Element'Pos (Source (Index)) +
>>>>               Stream_Element'Pos (Source (Index + 1));
>>>
>>> Rather:
>>>
>>>        Stream_Element'Pos (Source (Index + 1)) * 256;
>> 
>> That's an implementation where both the stream and the processor are
>> little-endian.
>
> It is an implementation when the format of unsigned 16 is little
> endian.  The processor endianness can be any, which is the point of
> doing it this way.

I agree about the processor endianness, I was wrong. However, to call it
the "format of Unsigned_16" could be a little misleading, it's the
format of Unsigned_16 *on the wire* that's little-endian.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 15:08             ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14 17:16               ` Alexander Korolev
  2011-09-14 20:13                 ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14 17:16 UTC (permalink / raw)


On Sep 14, 7:08 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 14 Sep 2011 07:48:47 -0700 (PDT), Alexander Korolev wrote:
> > I am talking to serial port via GNAT.Serial_Communication. The
> > Buffer it offers is Stream_Element_Array.
>
> In that case it is OK to use Stream_Element.
>
> > And I need to do
> > computations (implemented assuming that the buffer is ok :) ) over the
> > buffer
> > before do the call.One of the formats receiving part expects is:
> >|Start(8bit|Length - 16 bit|Element1-8bit|Element-16bit|Checksum|
> > Write (S_Port,Buffer)
>
> I usually allocate an output buffer in the "device object". The output
> index as I described earlier is also stored there. The application level
> fills the buffer and in the end call something like Device.Flush. Flush
> calculates the checksum over 1..Index - 1, stores the result and finally
> calls Write.
>
> BTW, it is highly recommended to use asynchronous read, or a synchronous
> one from an independent task. You should always be ready to read next byte
> from the device. Otherwise you risk to run into a deadlock upon protocol
> errors.
>
> You might also wish to write asynchronously (to improve performance), but
> beware that most serial devices, at least those I saw, are broken and just
> crash when full duplex I/O attempted.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de
"I usually allocate an output buffer in the "device object"

I've been advised and that worked out for many in few cases to use
Volatile_Streams.Memory_Resident_Stream.
You may like to take a look (in GNAT Examples) if you have not
already did
before. I was getting a compilation error like I posted before (see my
second post)
but now it's gone and I hope I got what I wanted but further autopsy
will show ...
I will post the result if it will work this way.

" or a synchronous one from an independent task"
Sure. This is were I call the serial port






^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 16:20             ` Stream_Element_Array Simon Wright
@ 2011-09-14 19:53               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14 19:53 UTC (permalink / raw)


On Wed, 14 Sep 2011 17:20:11 +0100, Simon Wright wrote:

> However, to call it
> the "format of Unsigned_16" could be a little misleading, it's the
> format of Unsigned_16 *on the wire* that's little-endian.

Yes.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 17:16               ` Stream_Element_Array Alexander Korolev
@ 2011-09-14 20:13                 ` Dmitry A. Kazakov
  2011-09-14 21:29                   ` Stream_Element_Array Alexander Korolev
  2011-09-15  2:33                   ` Stream_Element_Array Alexander Korolev
  0 siblings, 2 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-14 20:13 UTC (permalink / raw)


On Wed, 14 Sep 2011 10:16:09 -0700 (PDT), Alexander Korolev wrote:

> I've been advised and that worked out for many in few cases to use
> Volatile_Streams.Memory_Resident_Stream.

This is not what you need. It is a stream backed by the memory. I also
implemented such, backed by a String object, that is when you write, you do
into the string, when you read then from the string.

In your case the other end is not the memory but the wire. This is what
Serial_Port of GNAT.Serial_Communications is, an implementation of stream. 

So you simply derive or aggregate a new type from/into it, place there an
output buffer of Stream_Element_Array of the maximal message size, and
Stream_Element_Array for the input, usually just one element length.

The pattern is:

   Root_Stream_Type -- abstract stream
     |
   Serial_Port -- concrete stream, transport layer
     |
   your type -- specific protocol implementation

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 20:13                 ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-14 21:29                   ` Alexander Korolev
  2011-09-15  8:20                     ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-15  2:33                   ` Stream_Element_Array Alexander Korolev
  1 sibling, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-14 21:29 UTC (permalink / raw)


On Sep 15, 12:13 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 14 Sep 2011 10:16:09 -0700 (PDT), Alexander Korolev wrote:
> > I've been advised and that worked out for many in few cases to use
> > Volatile_Streams.Memory_Resident_Stream.
>
> This is not what you need. It is a stream backed by the memory. I also
> implemented such, backed by a String object, that is when you write, you do
> into the string, when you read then from the string.
>
> In your case the other end is not the memory but the wire. This is what
> Serial_Port of GNAT.Serial_Communications is, an implementation of stream.
>
> So you simply derive or aggregate a new type from/into it, place there an
> output buffer of Stream_Element_Array of the maximal message size, and
> Stream_Element_Array for the input, usually just one element length.
>
> The pattern is:
>
>    Root_Stream_Type -- abstract stream
>      |
>    Serial_Port -- concrete stream, transport layer
>      |
>    your type -- specific protocol implementation
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

"It is a stream backed by the memory"
yes

"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.
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.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 20:13                 ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-14 21:29                   ` Stream_Element_Array Alexander Korolev
@ 2011-09-15  2:33                   ` Alexander Korolev
  1 sibling, 0 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-15  2:33 UTC (permalink / raw)


On Sep 15, 12:13 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 14 Sep 2011 10:16:09 -0700 (PDT), Alexander Korolev wrote:
> > I've been advised and that worked out for many in few cases to use
> > Volatile_Streams.Memory_Resident_Stream.
>
> This is not what you need. It is a stream backed by the memory. I also
> implemented such, backed by a String object, that is when you write, you do
> into the string, when you read then from the string.
>
> In your case the other end is not the memory but the wire. This is what
> Serial_Port of GNAT.Serial_Communications is, an implementation of stream.
>
> So you simply derive or aggregate a new type from/into it, place there an
> output buffer of Stream_Element_Array of the maximal message size, and
> Stream_Element_Array for the input, usually just one element length.
>
> The pattern is:
>
>    Root_Stream_Type -- abstract stream
>      |
>    Serial_Port -- concrete stream, transport layer
>      |
>    your type -- specific protocol implementation
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Dmitry, I've sent an email for your attention. Please review.
Thanks, Alexander.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 21:29                   ` Stream_Element_Array Alexander Korolev
@ 2011-09-15  8:20                     ` Dmitry A. Kazakov
  2011-09-15 18:58                       ` Stream_Element_Array Alexander Korolev
  2011-09-15 19:15                       ` Stream_Element_Array Alexander Korolev
  0 siblings, 2 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-15  8:20 UTC (permalink / raw)


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.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15  8:20                     ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-15 18:58                       ` Alexander Korolev
  2011-09-15 20:48                         ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-15 19:15                       ` Stream_Element_Array Alexander Korolev
  1 sibling, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-15 18:58 UTC (permalink / raw)


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.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

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.


type Message_Length is
      record
         Lenght:Interfaces.Unsigned_16 :=
Interfaces.Unsigned_16(256);
      end record;
-------------

procedure length_test is
   V1  : aliased Volatile_Streams.Memory_Resident_Stream (Size =>
1024);
   Temp_Stream_Element        :Stream_Element;
   Message_Length_Instance   :Message_Length;
   Message_Lenght_Elements :Stream_Element_Array(1..4);

   begin
   Message_Length'Write(V1'Access,Message_Length_Instance);
   -- Write into and serialize into in - memory stream
Message_Length_Instance
   read (V1, Message_Lenght_Elements, Last);
   -- Read  out in-memry stream. Assigns  Message_Lenght and Last
   for J in Message_Lenght_Elements'First .. Last loop
      Temp_Stream_Element   := Message_Lenght_Elements(J);
       Put_Line( Temp_Stream_Element'Img);
   end loop;
   Put_Line( "Last");
   Put_line (Last'Img);
   -- print out the Last
end;

with Lenght:Interfaces.Unsigned_16 :=    Interfaces.Unsigned_16(255);
-- output
../development/projects/length_test
 255
 0
 0
Last
 3
[2011-09-15 11:26:32] process terminated successfully (elapsed time:
00.13s)

with Lenght:Interfaces.Unsigned_16 :=    Interfaces.Unsigned_16(256);
--output
../development/projects/length_test
 0
 1
 0
Last
 3
[2011-09-15 11:43:12] process terminated successfully (elapsed time:
00.13s)



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15  8:20                     ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-15 18:58                       ` Stream_Element_Array Alexander Korolev
@ 2011-09-15 19:15                       ` Alexander Korolev
  2011-09-15 20:11                         ` Stream_Element_Array Simon Wright
  1 sibling, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-15 19:15 UTC (permalink / raw)


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.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

My confusion is about the order of the Stream_Element for the cases I
posted



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 19:15                       ` Stream_Element_Array Alexander Korolev
@ 2011-09-15 20:11                         ` Simon Wright
  2011-09-15 20:34                           ` Stream_Element_Array Alexander Korolev
  2011-09-15 21:28                           ` Stream_Element_Array Alexander Korolev
  0 siblings, 2 replies; 42+ messages in thread
From: Simon Wright @ 2011-09-15 20:11 UTC (permalink / raw)


Alexander Korolev <antonovkablog@gmail.com> writes:

> My confusion is about the order of the Stream_Element for the cases I
> posted

That has to depend on what the thing at the other end is expecting!

If there's no proper specification, do you maybe have some C code that
we could help to work it out from?



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 20:11                         ` Stream_Element_Array Simon Wright
@ 2011-09-15 20:34                           ` Alexander Korolev
  2011-09-15 21:42                             ` Stream_Element_Array Simon Wright
  2011-09-15 21:28                           ` Stream_Element_Array Alexander Korolev
  1 sibling, 1 reply; 42+ messages in thread
From: Alexander Korolev @ 2011-09-15 20:34 UTC (permalink / raw)


On Sep 16, 12:11 am, Simon Wright <si...@pushface.org> wrote:
> Alexander Korolev <antonovkab...@gmail.com> writes:
> > My confusion is about the order of the Stream_Element for the cases I
> > posted
>
> That has to depend on what the thing at the other end is expecting!
>
> If there's no proper specification, do you maybe have some C code that
> we could help to work it out from?

It expecting 2 byte Lenth: |192|lenght (MSB)|Lenth (LSB)|Data|
checksum|
" The message length is a 2-byte field (MSB) equal to the size of the
data field and checksum
before byte stuffing has been executed" - from the doc



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 18:58                       ` Stream_Element_Array Alexander Korolev
@ 2011-09-15 20:48                         ` Dmitry A. Kazakov
  2011-09-16  0:20                           ` Stream_Element_Array Alexander Korolev
  0 siblings, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-15 20:48 UTC (permalink / raw)


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. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 20:11                         ` Stream_Element_Array Simon Wright
  2011-09-15 20:34                           ` Stream_Element_Array Alexander Korolev
@ 2011-09-15 21:28                           ` Alexander Korolev
  1 sibling, 0 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-15 21:28 UTC (permalink / raw)


On Sep 16, 12:11 am, Simon Wright <si...@pushface.org> wrote:
> Alexander Korolev <antonovkab...@gmail.com> writes:
> > My confusion is about the order of the Stream_Element for the cases I
> > posted
>
> That has to depend on what the thing at the other end is expecting!
>
> If there's no proper specification, do you maybe have some C code that
> we could help to work it out from?
I've posted:
http://www.ex.ua/view_storage/111215662945



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 20:34                           ` Stream_Element_Array Alexander Korolev
@ 2011-09-15 21:42                             ` Simon Wright
  2011-09-15 21:50                               ` Stream_Element_Array Simon Wright
  2011-09-16  0:18                               ` Stream_Element_Array Adam Beneschan
  0 siblings, 2 replies; 42+ messages in thread
From: Simon Wright @ 2011-09-15 21:42 UTC (permalink / raw)


Alexander Korolev <antonovkablog@gmail.com> writes:

> On Sep 16, 12:11 am, Simon Wright <si...@pushface.org> wrote:
>> Alexander Korolev <antonovkab...@gmail.com> writes:
>> > My confusion is about the order of the Stream_Element for the cases I
>> > posted
>>
>> That has to depend on what the thing at the other end is expecting!
>>
>> If there's no proper specification, do you maybe have some C code that
>> we could help to work it out from?
>
> It expecting 2 byte Lenth: |192|lenght (MSB)|Lenth (LSB)|Data|
> checksum|
> " The message length is a 2-byte field (MSB) equal to the size of the
> data field and checksum
> before byte stuffing has been executed" - from the doc

I don't know what they mean by (MSB) in "a 2-byte field (MSB)".

That said, it seems pretty clear that the first byte on the wire is to
be the most significant byte of Length : Unsigned_16, so you want
somthing like

   Write (Length / 256);
   Write (Length and 255);

or maybe

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces;
procedure Streaming is

   procedure Write (B : Interfaces.Unsigned_8) is
   begin
      Put_Line ("b => " & Interfaces.Unsigned_8'Image (B));
   end Write;

   V : Interfaces.Unsigned_16;

   use type Interfaces.Unsigned_16;

begin

   V := 16#8180#;

   Write (Interfaces.Unsigned_8 (Interfaces.Shift_Right (V, 8)));
   Write (Interfaces.Unsigned_8 (V and 16#FF#));

end Streaming;

The output is

$ ./streaming 
b =>  129
b =>  128



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 21:42                             ` Stream_Element_Array Simon Wright
@ 2011-09-15 21:50                               ` Simon Wright
  2011-09-16  0:01                                 ` Stream_Element_Array Alexander Korolev
  2011-09-16  0:18                               ` Stream_Element_Array Adam Beneschan
  1 sibling, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-15 21:50 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

>    Write (Length / 256);
>    Write (Length and 255);

>    Write (Interfaces.Unsigned_8 (Interfaces.Shift_Right (V, 8)));
>    Write (Interfaces.Unsigned_8 (V and 16#FF#));

The C equivalent in rs232_tx() in rs232.c is

  /* stuff msg length, adding a byte for chksum */
  msg[0] = (uint8_t)((buf_len+1) >> 8);
  msg[1] = (uint8_t)(buf_len+1);

I must say that second line looks _very_ suspicious!



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 21:50                               ` Stream_Element_Array Simon Wright
@ 2011-09-16  0:01                                 ` Alexander Korolev
  0 siblings, 0 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-16  0:01 UTC (permalink / raw)


On Sep 16, 1:50 am, Simon Wright <si...@pushface.org> wrote:
> Simon Wright <si...@pushface.org> writes:
> >    Write (Length / 256);
> >    Write (Length and 255);
> >    Write (Interfaces.Unsigned_8 (Interfaces.Shift_Right (V, 8)));
> >    Write (Interfaces.Unsigned_8 (V and 16#FF#));
>
> The C equivalent in rs232_tx() in rs232.c is
>
>   /* stuff msg length, adding a byte for chksum */
>   msg[0] = (uint8_t)((buf_len+1) >> 8);
>   msg[1] = (uint8_t)(buf_len+1);
>
> I must say that second line looks _very_ suspicious!

1. I think they had to put in the frame desc just:
   |192|2-byte Length, MSB first|
2. They take into accout that checksum is a part of the Length

You code will solve my problem with Lengh and other 16 bit, MSB first.
I'll double check. Thanks Simon



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 21:42                             ` Stream_Element_Array Simon Wright
  2011-09-15 21:50                               ` Stream_Element_Array Simon Wright
@ 2011-09-16  0:18                               ` Adam Beneschan
  2011-09-16  7:22                                 ` Stream_Element_Array Dmitry A. Kazakov
  1 sibling, 1 reply; 42+ messages in thread
From: Adam Beneschan @ 2011-09-16  0:18 UTC (permalink / raw)


On Sep 15, 2:42 pm, Simon Wright <si...@pushface.org> wrote:
> Alexander Korolev <antonovkab...@gmail.com> writes:
> > On Sep 16, 12:11 am, Simon Wright <si...@pushface.org> wrote:
> >> Alexander Korolev <antonovkab...@gmail.com> writes:
> >> > My confusion is about the order of the Stream_Element for the cases I
> >> > posted
>
> >> That has to depend on what the thing at the other end is expecting!
>
> >> If there's no proper specification, do you maybe have some C code that
> >> we could help to work it out from?
>
> > It expecting 2 byte Lenth: |192|lenght (MSB)|Lenth (LSB)|Data|
> > checksum|
> > " The message length is a 2-byte field (MSB) equal to the size of the
> > data field and checksum
> > before byte stuffing has been executed" - from the doc
>
> I don't know what they mean by (MSB) in "a 2-byte field (MSB)".
>
> That said, it seems pretty clear that the first byte on the wire is to
> be the most significant byte of Length : Unsigned_16, so you want
> somthing like
>
>    Write (Length / 256);
>    Write (Length and 255);
>
> or maybe
>
> with Ada.Text_IO; use Ada.Text_IO;
> with Interfaces;
> procedure Streaming is
>
>    procedure Write (B : Interfaces.Unsigned_8) is
>    begin
>       Put_Line ("b => " & Interfaces.Unsigned_8'Image (B));
>    end Write;
>
>    V : Interfaces.Unsigned_16;
>
>    use type Interfaces.Unsigned_16;
>
> begin
>
>    V := 16#8180#;
>
>    Write (Interfaces.Unsigned_8 (Interfaces.Shift_Right (V, 8)));
>    Write (Interfaces.Unsigned_8 (V and 16#FF#));

Would it be useful to add a 'Stream_Element_Order attribute to the
language (somewhat analogous to 'Stream_Size) that would allow a
programmer to specify, via an aspect clause or attribute definition
clause, whether values of a given elementary type are read/written
with the most or least significant byte first?

                          -- Adam




^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-15 20:48                         ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-16  0:20                           ` Alexander Korolev
  0 siblings, 0 replies; 42+ messages in thread
From: Alexander Korolev @ 2011-09-16  0:20 UTC (permalink / raw)


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.




^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16  0:18                               ` Stream_Element_Array Adam Beneschan
@ 2011-09-16  7:22                                 ` Dmitry A. Kazakov
  2011-09-16 10:21                                   ` Stream_Element_Array Simon Wright
  2011-09-19 23:22                                   ` Stream_Element_Array Randy Brukardt
  0 siblings, 2 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-16  7:22 UTC (permalink / raw)


On Thu, 15 Sep 2011 17:18:28 -0700 (PDT), Adam Beneschan wrote:

> On Sep 15, 2:42�pm, Simon Wright <si...@pushface.org> wrote:
>> � �Write (Interfaces.Unsigned_8 (Interfaces.Shift_Right (V, 8)));
>> � �Write (Interfaces.Unsigned_8 (V and 16#FF#));
> 
> Would it be useful to add a 'Stream_Element_Order attribute to the
> language (somewhat analogous to 'Stream_Size) that would allow a
> programmer to specify, via an aspect clause or attribute definition
> clause, whether values of a given elementary type are read/written
> with the most or least significant byte first?

Not much. Apart from the point that S'Write is not a proper way to handle
protocols, a more pragmatic reason is that many protocols (I can remember
at least 2 or 3) don't have a fixed endianness. E.g. you, as a master,
establish a connection to the slave, the slave during handshaking or by
other means tells you which format it wishes to deploy, i.e. "Motorola" or
"Intel" etc. The master, you, have to adapt on the fly. This is admittedly
idiotic, but very common nevertheless.

As for S'Write, in particular note that most of the underlying transports,
upon which the stream would operate, are packet-oriented. RS232 is a dying
minority. So you would really wish to send outgoing logical packets whole,
in order to allow the lower levels to handle them as whole physical
packets. As an example, consider TCP/IP. If you wanted to make TCP_NO_DELAY
option working, you would have to respect packet boundaries. I.e. the right
way to handle stream protocols is to use Write (S, Packet) instead.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16  7:22                                 ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-16 10:21                                   ` Simon Wright
  2011-09-16 12:13                                     ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-19 23:22                                   ` Stream_Element_Array Randy Brukardt
  1 sibling, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-16 10:21 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> As an example, consider TCP/IP. If you wanted to make TCP_NO_DELAY
> option working, you would have to respect packet boundaries. I.e. the
> right way to handle stream protocols is to use Write (S, Packet)
> instead.

Even more so with UDP!



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14  3:13 Stream_Element_Array Alexander Korolev
                   ` (2 preceding siblings ...)
  2011-09-14 12:19 ` Stream_Element_Array Gautier write-only
@ 2011-09-16 11:17 ` anon
  3 siblings, 0 replies; 42+ messages in thread
From: anon @ 2011-09-16 11:17 UTC (permalink / raw)


One way is to use Ada Union, the other more flexible way is to use 
"Ada.Unchecked_Conversion".  

In using the ada.Unchecked_Conversion you can convert the record 
"Message_Header" to a array of Unsigned_8 or another record which 
defines length as 2 Unsigned_8 elements. Then use the new converted 
8-bit array or record in your Stream Element routine.


In <edfcce02-7d80-4186-a281-c8a4983a3efd@p25g2000pri.googlegroups.com>, Alexander Korolev <antonovkablog@gmail.com> writes:
>I have a Type
>
>type Message_Header is
>    record
>       -- Components                  --   8 bit
>       Length    : Unsigned_16;    -- 16 bit  (MSB)
>       -- other components          --   8 bit
>    end record;
>
>How I could split the Lenght component on two subsequent
>Stream_Element ( 8-bit)?
>
>Command: Stream_Element_Array (1 .. 64);
>
>Thanks




^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16 10:21                                   ` Stream_Element_Array Simon Wright
@ 2011-09-16 12:13                                     ` Dmitry A. Kazakov
  2011-09-16 17:20                                       ` Stream_Element_Array Simon Wright
  0 siblings, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-16 12:13 UTC (permalink / raw)


On Fri, 16 Sep 2011 11:21:20 +0100, Simon Wright wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> As an example, consider TCP/IP. If you wanted to make TCP_NO_DELAY
>> option working, you would have to respect packet boundaries. I.e. the
>> right way to handle stream protocols is to use Write (S, Packet)
>> instead.
> 
> Even more so with UDP!

Yes, but I hope that nobody would come to an idea to abstract UPD as a
stream of octets, because UDP is unreliable and does not ensure ordering.
(Many device designers we are working with have a strange love to UDP. It
is an ongoing fight to convince them that replacing UDP with TCP/IP would
make life much easier both for us and for them.)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16 12:13                                     ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-16 17:20                                       ` Simon Wright
  2011-09-16 19:32                                         ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-16 17:20 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 16 Sep 2011 11:21:20 +0100, Simon Wright wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> As an example, consider TCP/IP. If you wanted to make TCP_NO_DELAY
>>> option working, you would have to respect packet boundaries. I.e. the
>>> right way to handle stream protocols is to use Write (S, Packet)
>>> instead.
>> 
>> Even more so with UDP!
>
> Yes, but I hope that nobody would come to an idea to abstract UPD as a
> stream of octets, because UDP is unreliable and does not ensure ordering.
> (Many device designers we are working with have a strange love to UDP. It
> is an ongoing fight to convince them that replacing UDP with TCP/IP would
> make life much easier both for us and for them.)

I haven't checked recently; no, the bug I posted is still there,
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9535

I certainly wouldn't expect any significant performance difference
between UDP and TCP with no-delay. I suppose what's significant for you
may not be for me. But very few system engineers IME appreciate the
difference; and by the time you've eliminated out-of-order UDP packets
you may have eaten the difference anyway.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16 17:20                                       ` Stream_Element_Array Simon Wright
@ 2011-09-16 19:32                                         ` Dmitry A. Kazakov
  2011-09-16 22:18                                           ` Stream_Element_Array Simon Wright
  0 siblings, 1 reply; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-16 19:32 UTC (permalink / raw)


On Fri, 16 Sep 2011 18:20:09 +0100, Simon Wright wrote:

> I certainly wouldn't expect any significant performance difference
> between UDP and TCP with no-delay. I suppose what's significant for you
> may not be for me. But very few system engineers IME appreciate the
> difference; and by the time you've eliminated out-of-order UDP packets
> you may have eaten the difference anyway.

Exactly, whatever overhead TCP/IP might cause, it is one to pay anyway by
adding safety to UDP (sequence numbers, acknowledging, resending lost
packets, reordering packets etc).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16 19:32                                         ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-16 22:18                                           ` Simon Wright
  2011-09-17  8:18                                             ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2011-09-16 22:18 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 16 Sep 2011 18:20:09 +0100, Simon Wright wrote:
>
>> I certainly wouldn't expect any significant performance difference
>> between UDP and TCP with no-delay. I suppose what's significant for you
>> may not be for me. But very few system engineers IME appreciate the
>> difference; and by the time you've eliminated out-of-order UDP packets
>> you may have eaten the difference anyway.
>
> Exactly, whatever overhead TCP/IP might cause, it is one to pay anyway by
> adding safety to UDP (sequence numbers, acknowledging, resending lost
> packets, reordering packets etc).

We are of one mind here, indeed someone who thought that was a good idea
should also like the design of a project I worked on where heartbeat
(keep-alive) messages were not only application-generated but also sent
on a different socket from data messages. It took a lot of effort to
persuade TPTB that TCP/IP channels are bidirectional.

On the other hand, if you have a tracker radar reporting target
positions every 2 ms (I'm making that number up) it probably won't
matter if you miss one or two reports, so as long as you take care not
to use an out-of-order report UDP might not be inappropriate.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16 22:18                                           ` Stream_Element_Array Simon Wright
@ 2011-09-17  8:18                                             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2011-09-17  8:18 UTC (permalink / raw)


On Fri, 16 Sep 2011 23:18:21 +0100, Simon Wright wrote:

> On the other hand, if you have a tracker radar reporting target
> positions every 2 ms (I'm making that number up) it probably won't
> matter if you miss one or two reports, so as long as you take care not
> to use an out-of-order report UDP might not be inappropriate.

Theoretically yes, if you measuring a physical contiguous value, you can
live with losses. You cannot if you have discrete stuff: commands, impulses
etc.

But in reality even with physical values, if you have two, which are later
used in some sort of control loop, you have to ensure them coherent. You
could reconstruct missing points using time stamps, but then you would have
to add stamps, synchronize clocks etc. In the end something always emerges
on top of UDP.

Even for broadcasting purposes there exist stream-oriented protocols, which
are safe. We tested PGM, which showed quite decent latencies comparing to
TCP/IP + NO_DELAY.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-14 12:48         ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-14 14:48           ` Stream_Element_Array Alexander Korolev
@ 2011-09-19 23:11           ` Randy Brukardt
  1 sibling, 0 replies; 42+ messages in thread
From: Randy Brukardt @ 2011-09-19 23:11 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:b7yqos9wk4fn.15kuyzgqrkhge.dlg@40tude.net...
> On Wed, 14 Sep 2011 11:53:13 +0100, Simon Wright wrote:
>
>> I know the RM doesn't specify this, and goes out of its way to allow
>> 9-bit bytes and 36-bit storage units. But how many real-life situations
>> are there where Stream_Element'Size isn't 8?
>
> Why not to mandate it 8-bit then? Even if the machine does not support
> memory access to octets, I think it would be worth the efforts to have the
> compiler doing packing/unpacking stuff, rather than the programmer.

Mostly because of machines with odd word sizes, like the Unisys U2200 we 
worked on. For that, Stream_Element'Size = 9, and there is no "packing" or 
"unpacking" going on; the elements all had an extra bit compared to the 
"normal" (zero if converted from a text stream from some other processor).

There would be no way to map Stream_Element'Size = 8 on such an 
architechture. But I agree that on more conventional architectures, 
Stream_Element'Size should be 8. I'd consider it wrong (morally, not 
formally) for it to be anything else on any machine whose word size is a 
multiple of 8. (Probably there ought to be implementation advice to that 
effect.)

                                       Randy.





^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Stream_Element_Array
  2011-09-16  7:22                                 ` Stream_Element_Array Dmitry A. Kazakov
  2011-09-16 10:21                                   ` Stream_Element_Array Simon Wright
@ 2011-09-19 23:22                                   ` Randy Brukardt
  1 sibling, 0 replies; 42+ messages in thread
From: Randy Brukardt @ 2011-09-19 23:22 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1ha21cmm4ub0x.1x5tkefenjm53$.dlg@40tude.net...
...
> As for S'Write, in particular note that most of the underlying transports,
> upon which the stream would operate, are packet-oriented. RS232 is a dying
> minority. So you would really wish to send outgoing logical packets whole,
> in order to allow the lower levels to handle them as whole physical
> packets. As an example, consider TCP/IP. If you wanted to make 
> TCP_NO_DELAY
> option working, you would have to respect packet boundaries. I.e. the 
> right
> way to handle stream protocols is to use Write (S, Packet) instead.

I agree (I think). For Claw, we used a "marshalling" stream type; the stream 
attributes typically read/wrote directly from that. When the entire object 
was "marshalled", then the resulting array of stream elements was written at 
once to whatever. For things like sockets, that's a good idea; but for 
things like the clipboard and the registry, that was absolutely required. 
(By treating the clipboard and registry as a stream, we can easily support 
storing and reading anything at all in them, which would be hard to do 
preserving strong typing otherwise.)

                                            Randy.





^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2011-09-19 23:22 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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                           ` Stream_Element_Array Alexander Korolev
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

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