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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6b7d31ee31aa032,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-08-07 02:04:46 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!newsfeed.gamma.ru!Gamma.RU!news-FFM2.ecrc.net!news.iks-jena.de!lutz From: lutz@iks-jena.de (Lutz Donnerhacke) Newsgroups: comp.lang.ada Subject: Ada.Streams.Read Length Paramenter is not IN? Date: Tue, 7 Aug 2001 09:02:29 +0000 (UTC) Organization: IKS GmbH Jena Message-ID: NNTP-Posting-Host: taranis.iks-jena.de X-Trace: branwen.iks-jena.de 997174949 9101 217.17.192.37 (7 Aug 2001 09:02:29 GMT) X-Complaints-To: usenet@iks-jena.de NNTP-Posting-Date: Tue, 7 Aug 2001 09:02:29 +0000 (UTC) User-Agent: slrn/0.9.6.3 (Linux) Xref: archiver1.google.com comp.lang.ada:11469 Date: 2001-08-07T09:02:29+00:00 List-Id: 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. -------------------- 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 -------------------- -------------------- 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 -------------------- ----------------------- 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 ------------------------