From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Howto read line from a stream
Date: Sun, 31 May 2009 17:13:50 +0200
Date: 2009-05-31T17:13:52+02:00 [thread overview]
Message-ID: <18nn8atp3gdq1$.6g5cqv5h6u1c.dlg@40tude.net> (raw)
In-Reply-To: 16949835-6528-4a7a-a653-fd466b37bb45@s21g2000vbb.googlegroups.com
On Sun, 31 May 2009 05:56:41 -0700 (PDT), Tomek Wa�kuski wrote:
> Thank you Dimitry. I have implemented something like this:
>
> ---------- CODE -----------
> function Get_Line (Channel : in Stream_Access) return String is
> type String_Access is access String;
> Buffer : Character;
> Result : String_Access;
> Quit : Boolean := False;
> Line_Length : Natural := 0;
> procedure Free is new Ada.Unchecked_Deallocation (String,
> String_Access);
> begin
> loop
> Character'Read (Channel, Buffer);
> if Result = null then
> Result := new String (1 .. 1);
> end if;
> if Result'Length = Line_Length then
> declare
> Old : String_Access := Result;
> begin
> Result := new String (1 .. Old'Length +1);
> Result (1 .. Old'Length) := Old.all;
> Free (Old);
> end;
> end if;
> Line_Length := Line_Length + 1;
> Result (Line_Length) := Buffer;
> if Quit = True and then Buffer = ASCII.LF then
> exit;
> elsif Buffer = ASCII.CR then
> Quit := True;
> else
> Quit := False;
> end if;
> end loop;
> return Result.all;
> end Get_Line;
> ---------- CODE -----------
The problem with above is that it is at least as inefficient as
Unbounded_String:
1. You allocate a new string per each input byte;
2. You do not keep the allocated buffer between calls to Get_Line;
3. You copy the buffer content once read;
4. It leaks memory.
The idea I tried to convey by my solution was to address the issues 1-3:
1. The buffer is allocated in big pieces, so that it would adjust to the
maximal line length in few iterations.
2. The buffer is kept between calls. 1 & 2 mean that there would be only
one or two allocations per session.
3. The buffer content is not copied. Get_Line returns of an access to
String, of which slice is then renamed.
> My protocol says that every line ends with CR & LF, only length can
> vary.
The best practice of dealing with texts (streams or not) is to use LF as a
line terminator and remove training (or any) CR's from the buffer. This
makes it working under both Linux and Windows.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2009-05-31 15:13 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
2009-05-31 12:56 ` Tomek Wałkuski
2009-05-31 14:30 ` Tomek Wałkuski
2009-05-31 15:13 ` Dmitry A. Kazakov [this message]
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