Hi,

following the advice of howardpc, I repost here my question from the forum (https://forum.lazarus.freepascal.org/index.php/topic,60287.0.html).

Recently I wanted to rewind a file to read again a previous line. After some search I came to the conclusion to modify the TStreamReader class. Do you think that would be a useful addition? Should it be an a modification to TStreamReader or a new class?

Ciao,

Gilles Marcou


Below is a sketch of the modifications.

1. Add a list of line start positions in the stream:

Code: Pascal [Select][+]

1.
   TListInt64 = specialize TFPGList<Int64>;
2.
   (...)
3.
     TStreamReader = class(TTextReader)
4.
   private
5.
         flPos: TListInt64;
6.
   function ReadPos(Idx: integer): Int64;
7.
   procedure WritePos(Idx: integer; AValue: Int64);
8.
   (...)
9.
   public
10.
   property lPos[Idx: integer]: Int64 read ReadPos write WritePos;
11.


2. Manage this list
Code: Pascal [Select][+]

1.
   function TStreamReader.ReadPos(Idx: integer): Int64;
2.
   begin
3.
      Result:=flPos[Idx];
4.
   end;
5.
6.
   procedure TStreamReader.WritePos(Idx: integer; AValue: Int64);
7.
   begin
8.
      flPos[idx]:=AValue;
9.
   end;
10.
11.
   constructor TStreamReader.Create(AStream: TStream; ABufferSize: Integer;
12.
   AOwnsStream: Boolean);
13.
   begin
14.
   (...)
15.
      flPos:=TListInt64.Create;
16.
   end;
17.
18.
   procedure TStreamReader.Close;
19.
   begin
20.
   (...)
21.
   FreeAndNil(flPos);
22.
   end;
23.


3. Store line start positions
Code: Pascal [Select][+]

1.
   procedure TStreamReader.ReadLine(out AString: string);
2.
   var
3.
      VPByte: PByte;
4.
      VPosition, VStrLength, VLength: Integer;
5.
   begin
6.
      flPos.Add(FBufferPosition);
7.


4. Add a procedure to jump to the desired line
Code: Pascal [Select][+]

1.
   procedure GoToLn(n: integer);
2.
   (...)
3.
   procedure TStreamReader.GoToLn(n: integer);
4.
   var
5.
      apos: Int64;
6.
   begin
7.
      apos:=flPos[n-1];//flPos is 0-based and lines are 1-based
8.
      Reset;
9.
      FStream.Seek(apos,soBeginning);
10.
   end;
11.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to