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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,865c3d125a8dbc3b X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!news3.google.com!feeder.news-service.com!newsfeed.straub-nv.de!noris.net!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Howto read line from a stream Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 8bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <83317a97-dae5-4c84-a1ac-88a87833cf3f@q14g2000vbn.googlegroups.com> <1a90e055-44a3-4d00-b4cd-64798c731a55@e24g2000vbe.googlegroups.com> Date: Sun, 31 May 2009 14:02:35 +0200 Message-ID: NNTP-Posting-Date: 31 May 2009 14:02:37 CEST NNTP-Posting-Host: 6e489efc.newsspool2.arcor-online.net X-Trace: DXC=lfA^F;RSJ>Lgj[ZPFj7ehOA9EHlD;3YcB4Fo<]lROoRA^YC2XCjHcbIhZ>f@UZj8bLDNcfSJ;bb[EIRnRBaCdKEJLQ]Q1CY1L3iB\6]gB X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:6133 Date: 2009-05-31T14:02:37+02:00 List-Id: 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