{$MODE FPC}
{$MODESWITCH RESULT}
{$MODESWITCH AUTODEREF}
{$MODESWITCH DEFAULTPARAMETERS}
unit dsv;

interface

uses
  darray;

type
PTextTable = ^TTextTable;
TTextTable = object
public type
  TFields = specialize TArray<PAnsiChar>;
private
  FFile: TextFile;
  FBuffer: AnsiString;
  FSeparator: AnsiChar;
public
  Fields: TFields;
  constructor Init(const FileName: String = ''; const Separator: AnsiChar = #9);
  destructor Done; virtual;
  function NextLine: Boolean;
  function GetValue(Index: Cardinal): PAnsiChar;
  property Values[Index: Cardinal]: PAnsiChar read GetValue; default;
end;

implementation

constructor TTextTable.Init(const FileName: String = ''; const Separator: AnsiChar = #9);
begin
  Assign(FFile, FileName);
  Reset(FFile);
  FSeparator := Separator;
end;

destructor TTextTable.Done;
begin
  Close(FFile);
end;

function TTextTable.NextLine: Boolean;
var
  I: Integer;
begin
  if Eof(FFile) then
    Exit(False);
  Readln(FFile, FBuffer);
  Fields.SetLength(0);
  if Length(FBuffer) = 0 then
    Exit(True);
  Fields.Insert(@FBuffer[1]);
  for I := 1 to Length(FBuffer) do begin
    if FBuffer[I] = FSeparator then begin
      FBuffer[I] := #0;
	  if I < Length(FBuffer) then
        Fields.Insert(@FBuffer[I + 1]);
    end;
  end;
end;

function TTextTable.GetValue(Index: Cardinal): PAnsiChar;
begin
  if Index > Fields.High then
    Exit(nil);
  Result := Fields.AsArray[Index];
end;

end.
