From: lutz@iks-jena.de (Lutz Donnerhacke)
Subject: Ada.Streams.Read Length Paramenter is not IN?
Date: Tue, 7 Aug 2001 09:02:29 +0000 (UTC)
Date: 2001-08-07T09:02:29+00:00 [thread overview]
Message-ID: <slrn9mvbej.hs.lutz@taranis.iks-jena.de> (raw)
Writing a very small 'Filedescriptor_Stream' package (to eliminate the libc,
dealing with sockets, and---of course---learning), I run into semantic
problems with 'Ada.Streams.Read':
procedure Read(
Stream : in out XXX_Stream_Type;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset);
The RM says:
The Read operation transfers Item'Length stream elements from the
specified stream to fill the array Item. The index of the last stream
element transferred is returned in Last. Last is less than Item'Last only
if the end of the stream is reached.
I can not read an arbitary amount of data due to possible blocking or
confusing situation where the corresponding site has to close the transfer
in order to process the input. (Quite contrary to interactive)
I can not read each Storage_Element seperatly, due to massive system
performance decrease.
OTOH each T'Read or T'Input procedure exactly knows how many
Storage_Elements are needed to fullfill the request. Why is this information
not given to the Stream.Read procedure?
BTW: Do I understand the procedure semantics correctly, if I return Item and
Last := Item'Last generally. But in the case of EOF returning Item
larger than normally and set Item'Last to the last valid element.
Would it be not simpler to have the following procedure?
procedure Read(
Stream : in out XXX_Stream_Type;
Data : out Stream_Element_Array;
Needed : in Stream_Element_Offset;
EOT : out Boolean);
Please do not quote the source unless you really want to comment it.
\f
-------------------- filedescriptor_stream.ads --------------------
with Interfaces.C, Ada.Streams;
package Filedescriptor_Stream is
type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
type Filedescriptor_Stream_Type is new Ada.Streams.Root_Stream_Type
with private;
function Stream(fd : Interfaces.C.int) return Stream_Access;
Device_Error : exception;
procedure Read(
Stream : in out Filedescriptor_Stream_Type;
Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset);
procedure Write(
Stream : in out Filedescriptor_Stream_Type;
Item : in Ada.Streams.Stream_Element_Array);
private
type Filedescriptor_Stream_Type is new Ada.Streams.Root_Stream_Type
with record fd : Interfaces.C.int; end record;
end Filedescriptor_Stream;
-------------------- filedescriptor_stream.ads --------------------
\f
-------------------- filedescriptor_stream.adb --------------------
with Interfaces.C, Ada.Streams;
use Interfaces.C, Ada.Streams;
package body Filedescriptor_Stream is
function Stream(fd : int) return Stream_Access is
res : Stream_Access := new Filedescriptor_Stream_Type;
begin
Filedescriptor_Stream_Type(res.all).fd := fd;
return res;
end Stream;
function Read(Stream : in Filedescriptor_Stream_Type)
return Stream_Element_Array;
type void_p is access all Stream_Element;
for void_p'Size use 32;
function c_write(fd : int; buff : void_p; len : size_t) return int;
function c_read(fd : int; buff : void_p; len : size_t) return int;
pragma Import(C, c_write, "write");
pragma Import(C, c_read, "read");
function Read(Stream : in Filedescriptor_Stream_Type)
return Stream_Element_Array is
data : aliased Stream_Element_Array (0 .. 0);
begin
if 1 = c_read (Stream.fd, data(0)'Unrestricted_Access, 1) then
return data; -- & Read (Stream);
else
return data;
end if;
end Read;
procedure Read(
Stream : in out Filedescriptor_Stream_Type;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset) is
begin
Item := Read (Stream);
Last := Item'Last;
end Read;
procedure Write(
Stream : in out Filedescriptor_Stream_Type;
Item : in Stream_Element_Array) is
pos : Stream_Element_Offset := Item'First;
len : size_t := Item'Length;
res : int;
begin
while len > 0 loop
res := c_write(Stream.fd, Item(pos)'Unrestricted_Access, len);
if res = -1 then raise Device_Error; end if;
len := len - size_t(res);
pos := pos + Stream_Element_Offset(res);
end loop;
end Write;
end Filedescriptor_Stream;
-------------------- filedescriptor_stream.adb --------------------
\f
----------------------- test_fd_stream.adb ------------------------
with Filedescriptor_Stream;
use Filedescriptor_Stream;
procedure Test_Fd_Stream is
sout : Stream_Access := Stream (1);
begin
String'Write(sout, "a =" & Integer'Image(a) & ASCII.LF);
String'Write(sout, "b =" & Integer'Image(b) & ASCII.LF);
String'Write(sout, "c =" & Integer'Image(c) & ASCII.LF);
end Test_Fd_Stream;
----------------------- test_fd_stream.adb ------------------------
next reply other threads:[~2001-08-07 9:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-08-07 9:02 Lutz Donnerhacke [this message]
2001-08-07 18:39 ` Ada.Streams.Read Length Paramenter is not IN? Ted Dennison
2001-08-07 20:18 ` Lutz Donnerhacke
2001-08-07 19:48 ` tmoran
2001-08-07 20:21 ` Lutz Donnerhacke
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox