From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Howto read line from a stream
Date: Sun, 31 May 2009 14:02:35 +0200
Date: 2009-05-31T14:02:37+02:00 [thread overview]
Message-ID: <nbzc2bvk6qep$.e39390ifjqzw$.dlg@40tude.net> (raw)
In-Reply-To: 1a90e055-44a3-4d00-b4cd-64798c731a55@e24g2000vbe.googlegroups.com
On Sun, 31 May 2009 04:29:33 -0700 (PDT), Tomek Wa�kuski wrote:
> I have done so far:
>
> function Read_Line (Channel : in Stream_Access) return String is
> Buffer : String (1 .. 1);
> Result : Unbounded_String;
> begin
> loop
> String'Read (Channel, Buffer);
> Append (Result, Buffer);
> exit when Buffer (1) = ASCII.LF;
> end loop;
> return To_String(Result);
> end Read_Line;
>
> I know, this is completely NOT smart solution.
It is OK except for Unbounded_String, especially Append per each character.
That should be very slow.
I would do something like:
with Ada.Finalization;
with Ada.Streams; use Ada.Streams;
package Buffers is
-- Buffer to accumulate read lines
type Line_Buffer is tagged limited private;
-- Get the line in the buffer (longer than the line read)
function Get_Line (Buffer : Line_Buffer) return not null access String;
-- Get the length of the line in the buffer
function Get_Length (Buffer : Line_Buffer) return Natural;
-- Read new line into the buffer
procedure Read
( Buffer : in out Line_Buffer;
Stream : in out Root_Stream_Type'Class
);
private
type String_Ptr is access String;
type Line_Buffer is new Ada.Finalization.Limited_Controlled with record
Length : Natural := 0;
Line : String_Ptr; -- The line body, dynamically allocated
end record;
overriding procedure Finalize (Buffer : in out Line_Buffer);
end Buffers;
You would use it like:
loop
Read (Buffer, Stream); -- Read line
declare
Line : String renames Buffer.Get_Line (1..Buffer.Get_Length));
begin
... -- Process Line
end;
end loop;
The implementation could be like:
with Ada.Unchecked_Deallocation;
package body Buffers is
Increment : constant := 1024;
procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr);
function Get_Line (Buffer : Line_Buffer)
return not null access String is
begin
return Buffer.Line;
end Get_Line;
function Get_Length (Buffer : Line_Buffer) return Natural is
begin
return Buffer.Length;
end Get_Length;
procedure Read
( Buffer : in out Line_Buffer;
Stream : in out Root_Stream_Type'Class
) is
Data : Character;
begin
Buffer.Length := 0;
loop
Character'Read (Stream'Access, Data);
exit when Data = Character'Val (10);
if Buffer.Line = null then
Buffer.Line := new String (1..Increment);
end if;
if Buffer.Line'Length = Buffer.Length then
declare
Old : String_Ptr := Buffer.Line;
begin
Buffer.Line := new String (1..Old'Length + Increment);
Buffer.Line (1..Old'Length) := Old.all;
Free (Old);
end;
end if;
Buffer.Length := Buffer.Length + 1;
Buffer.Line (Buffer.Length) := Data;
end loop;
end Read;
procedure Finalize (Buffer : in out Line_Buffer) is
begin
Free (Buffer.Line);
end Finalize;
end Buffers;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2009-05-31 12:02 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-31 10:41 Howto read line from a stream Tomek Walkuski
2009-05-31 11:29 ` Tomek Wałkuski
2009-05-31 12:02 ` Dmitry A. Kazakov [this message]
2009-05-31 12:56 ` Tomek Wałkuski
2009-05-31 14:30 ` Tomek Wałkuski
2009-05-31 15:13 ` Dmitry A. Kazakov
2009-06-01 23:30 ` Randy Brukardt
2009-06-02 7:30 ` Dmitry A. Kazakov
2009-06-02 9:36 ` Georg Bauhaus
2009-06-02 10:24 ` Dmitry A. Kazakov
2009-06-02 21:15 ` Randy Brukardt
2009-06-01 6:34 ` Pascal Obry
2009-06-01 0:05 ` Jeffrey R. Carter
2009-06-03 15:49 ` Tomek Wałkuski
2009-06-03 18:04 ` Jeffrey R. Carter
2009-06-03 21:41 ` Maciej Sobczak
2009-06-04 8:56 ` Jean-Pierre Rosen
2009-06-04 9:05 ` Ludovic Brenta
2009-06-04 13:05 ` Maciej Sobczak
2009-06-04 14:16 ` Jean-Pierre Rosen
2009-06-04 19:48 ` Ludovic Brenta
2009-06-04 14:24 ` Dmitry A. Kazakov
2009-06-03 19:07 ` sjw
2009-06-03 19:26 ` Dmitry A. Kazakov
2009-06-03 19:43 ` Georg Bauhaus
2009-06-03 20:11 ` Dmitry A. Kazakov
2009-06-03 22:09 ` Georg Bauhaus
2009-06-04 8:19 ` Dmitry A. Kazakov
2009-06-04 9:41 ` Georg Bauhaus
2009-06-04 10:23 ` Dmitry A. Kazakov
2009-06-04 12:14 ` Georg Bauhaus
2009-06-04 14:54 ` Dmitry A. Kazakov
2009-06-04 16:33 ` Georg Bauhaus
2009-06-05 9:57 ` Dmitry A. Kazakov
2009-06-04 14:16 ` andrew
2009-06-01 19:12 ` björn lundin
2009-05-31 11:34 ` Dmitry A. Kazakov
2009-05-31 15:38 ` sjw
2009-05-31 16:07 ` Dmitry A. Kazakov
2009-05-31 20:39 ` Niklas Holsti
2009-05-31 22:00 ` sjw
2009-06-01 8:35 ` Dmitry A. Kazakov
2009-06-01 23:34 ` Randy Brukardt
2009-06-02 2:27 ` anon
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox