[fpc-devel] FCL streamex question

MARCOU Gilles g.marcou at unistra.fr
Wed Aug 17 12:07:47 CEST 2022


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20220817/5edb5111/attachment-0001.htm>


More information about the fpc-devel mailing list