comp.lang.ada
 help / color / mirror / Atom feed
From: Dennis Hoppe <dennis.hoppe@hoppinet.de>
Subject: Re: Problems with Ada.Streams.Read (blocking)
Date: Fri, 08 Aug 2008 20:00:44 +0200
Date: 2008-08-08T20:00:44+02:00	[thread overview]
Message-ID: <g7i1kc$ujv$1@aioe.org> (raw)
In-Reply-To: 1c7gwe0hi3ew5$.1c9zms1qkzjel.dlg@40tude.net

Hi Dmitri,

thank you for your reply, but it does not solve my problem. You just 
encapsulate the challenge in a nicer way. The application stops
at runtime while invoking Ada.Streams.Read to often, again.

I corrected your snippet to be compatible with my test-framework.


with Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with GNAT.Sockets; use GNAT.Sockets;
use type Ada.Streams.Stream_Element_Count;
with System.Storage_Elements; use System.Storage_Elements;

procedure Test is
   Client: Socket_Type;
   Address: Sock_Addr_Type;
   Channel: Stream_Access;
   Data   : Ada.Streams.Stream_Element_Array (1 .. 2);
   Offset : Ada.Streams.Stream_Element_Count := 1;

   procedure Read_Record (
       Channel : in out Stream_Access;
       Buffer  : in out Stream_Element_Array;
       Last    : out Stream_Element_Offset)  is
     Index : Stream_Element_Offset := 1;
     Has_CR : Boolean := False;
   begin
     while Index in Buffer'Range loop
       Ada.Streams.Read (Channel.all, Buffer, Index);
       if Has_CR and then
	Stream_Element'Pos (Buffer (Index)) = Character'Pos (ASCII.LF)
       then
	Last := Index - 2;
         return;
       else
	Has_CR :=
          Stream_Element'Pos (Buffer (Index)) = Character'Pos (ASCII.CR);
       end if;
     end loop;
     raise Constraint_Error; -- Too large packet
   end Read_Record;

begin
    Initialize;
    Create_Socket(Client);
    Address.Addr := Inet_Addr("127.0.0.1");
    Address.Port := 21;
    Connect_Socket (Client, Address);
    Channel := Stream (Client);

    Read_Record (Channel, Data, Offset);

    for I in 1 .. Offset loop
      Ada.Text_IO.Put (Character'Val (Data(I)));
    end loop;
end Test;


The Ada specification mentions the following:

"The Read operation transfers stream elements from the specified stream 
to fill the array Item. Elements are transferred until Item'Length 
elements have been transferred, or until the end of the stream is 
reached. If any elements are transferred, the index of the last stream 
element transferred is returned in Last. Otherwise, Item'First - 1 is 
returned in Last. Last is less than Item'Last only if the end of the 
stream is reached."

(<http://www.adaic.org/standards/05aarm/html/AA-13-13-1.html>)


Actually, some invocation of Ada.Streams.Read (Channel.all, Buffer, 
Index) should lead to

   Index < Buffer'Last

if the end of the stream is reached. This is never the case, because 
"read" is blocking, if not all elements in Buffer could be filled up.
If Buffer is Buffer(1..1), Index went never to 0, for example.

I am now able to read line per line sent by the ftp server, but if
I only once invoke my read method to often, the whole program hangs up
due to the blocking behavior of Ada.Stream.Read.


Best regards,
   Dennis



  reply	other threads:[~2008-08-08 18:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-08 13:24 Problems with Ada.Streams.Read (blocking) Dennis Hoppe
2008-08-08 13:56 ` Dmitry A. Kazakov
2008-08-08 18:00   ` Dennis Hoppe [this message]
2008-08-08 18:51     ` Dmitry A. Kazakov
2008-08-08 19:37       ` Dennis Hoppe
2008-08-08 21:25       ` Maciej Sobczak
2008-08-09  7:30         ` Dmitry A. Kazakov
2008-08-08 14:48 ` Adam Beneschan
2008-08-08 18:08   ` Dennis Hoppe
2008-08-09  3:04 ` anon
2008-08-22 22:13 ` Paweł 'Nivertius' Płazieński
replies disabled

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