⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ststrms.pas

📁 条码控件: 一维条码控件 二维条码控件 PDF417Barcode MaxiCodeBarcode
💻 PAS
📖 第 1 页 / 共 4 页
字号:
procedure TStAnsiTextStream.atsSetLineEndCh(aValue : AnsiChar);
begin
  if ((FBufOfs + FBufPos) = 0) then begin
    FLineEndCh := aValue;
    atsResetLineIndex;
  end;
end;

{-----------------------------------------------------------------------------}

procedure TStAnsiTextStream.atsSetLineLen(aValue : integer);
begin
  if (aValue <> FixedLineLength) and ((FBufOfs + FBufPos) = 0) then begin
    {validate the new length first}
    if (aValue < 1) or (aValue > 1024) then
      RaiseStError(EStBufStreamError, stscBadLineLength);

    {set the new value; note that if there is no terminator we need to
     free the old line buffer, and then allocate a new one}
    if (LineTerminator = ltNone) then
      FreeMem(FFixedLine, FixedLineLength);
    FLineLen := aValue;
    if (LineTerminator = ltNone) then
      GetMem(FFixedLine, FixedLineLength);
    atsResetLineIndex;
  end;
end;

{-----------------------------------------------------------------------------}

procedure TStAnsiTextStream.bsInitForNewStream;
begin
  inherited bsInitForNewStream;
  atsResetLineIndex;
end;

{-----------------------------------------------------------------------------}

function TStAnsiTextStream.ReadLine : string;
var
  CurPos : longint;
  EndPos : longint;
  Len    : longint;
  StLen  : longint;
begin
  atsGetLine(CurPos, EndPos, Len);
  if (LineTerminator = ltNone) then begin
    {at this point, Len will either equal FixedLineLength, or it will
     be less than it because we read the last line of all and it was
     short}
    StLen := FixedLineLength;
    SetLength(Result, StLen);
    if (Len < StLen) then
      FillChar(Result[Len+1], StLen-Len, ' ');
  end
  else {LineTerminator is not ltNone} begin
    SetLength(Result, Len);
  end;
  {read the line}
  if Len > 0 then begin
    Seek(CurPos, soFromBeginning);
    Read(Result[1], Len);
  end
  else {it's a blank line }
    Result := '';
  Seek(EndPos, soFromBeginning);
end;

{-----------------------------------------------------------------------------}

function TStAnsiTextStream.ReadLineArray(aCharArray : PAnsiChar;
                                         aLen       : TStMemSize)
                                                    : TStMemSize;
var
  CurPos : longint;
  EndPos : longint;
  Len    : longint;
  StLen  : longint;
begin
  atsGetLine(CurPos, EndPos, Len);
  if (LineTerminator = ltNone) then begin
    {at this point, Len will either equal FixedLineLength, or it will
     be less than it because we read the last line of all and it was
     short}
    StLen := FixedLineLength;
    if (StLen > aLen) then
      StLen := aLen;
    if (Len < StLen) then
      FillChar(aCharArray[Len], StLen-Len, ' ');
    Result := StLen;
  end
  else {LineTerminator is not ltNone} begin
    if (Len > aLen) then
      Len := aLen;
    Result := Len;
  end;
  Seek(CurPos, soFromBeginning);
  Read(aCharArray[0], Len);
  Seek(EndPos, soFromBeginning);
end;

{-----------------------------------------------------------------------------}

function TStAnsiTextStream.ReadLineZ(aSt : PAnsiChar; aMaxLen : TStMemSize) : PAnsiChar;
var
  CurPos : longint;
  EndPos : longint;
  Len    : longint;
  StLen  : longint;
begin
  Result := aSt;
  atsGetLine(CurPos, EndPos, Len);
  if (LineTerminator = ltNone) then begin
    {at this point, Len will either equal FixedLineLength, or it will
     be less than it because we read the last line of all and it was
     short}
    StLen := FixedLineLength;
    if (StLen > aMaxLen) then
      StLen := aMaxLen;
    if (Len < StLen) then
      FillChar(Result[Len], StLen-Len, ' ');
    Result[StLen] := #0;
  end
  else {LineTerminator is not ltNone} begin
    if (Len > aMaxLen) then
      Len := aMaxLen;
    Result[Len] := #0;
  end;
  Seek(CurPos, soFromBeginning);
  Read(Result[0], Len);
  Seek(EndPos, soFromBeginning);
end;

{-----------------------------------------------------------------------------}

function TStAnsiTextStream.SeekNearestLine(aOffset : longint) : longint;
var
  CurLine : longint;
  CurOfs  : longint;
  CurPos  : longint;
  EndPos  : longint;
  Len     : longint;
  i       : longint;
  Done    : boolean;
  L, R, M : integer;
begin
  {if the offset we want is for the current line, reposition at the
   current line offset, return the current line number and exit}
  if (aOffset = FLineCurOfs) then begin
    Seek(FLineCurOfs, soFromBeginning);
    Result := FLineCurrent;
    Exit;
  end;
  {if the offset requested is less than or equal to zero, just
   position at line zero (ie, the start of the stream)}
  if (aOffset <= 0) then begin
    Seek(0, soFromBeginning);
    FLineCurrent := 0;
    FLineCurOfs := 0;
    Result := 0;
    Exit;
  end;
  {if the offset requested is greater than or equal to the size of the
   stream, position at the end of the stream (note that if we don't
   know the number of lines in the stream yet, FLineCount is set to
   -1 and we can't take this shortcut because we need to return the
   true value)}
  if (FLineCount >= 0) and (aOffset >= FSize) then begin
    Seek(0, soFromEnd);
    FLineCurrent := FLineCount;
    FLineCurOfs := FSize;
    Result := FLineCount;
    Exit;
  end;
  {if the offset requested is greater than the top item in the
   line index, we shall have to build up the index until we get to the
   line we require, or just beyond}
  if (aOffset > longint(FLineIndex[FLineInxTop+1])) then begin
    {position at the last known line offset}
    CurLine := longint(FLineIndex[FLineInxTop]);
    CurOfs := longint(FLineIndex[FLineInxTop+1]);
    Seek(CurOfs, soFromBeginning);
    Done := false;
    {continue reading lines in chunks of FLineInxStep and add an index
     entry for each chunk}
    while not Done do begin
      for i := 0 to pred(FLineInxStep) do begin
        atsGetLine(CurPos, EndPos, Len);
        inc(CurLine);
        CurOfs := EndPos;
        if (EndPos = FSize) then begin
          Done := true;
          Break;
        end;
      end;
      if Done then
        FLineCount := CurLine
      else begin
        inc(FLineInxTop, 2);
        if (FLineInxTop = (LineIndexCount * 2)) then begin
          {we've exhausted the space in the index: rescale}
          FLineInxTop := FLineInxTop div 2;
          for i := 0 to pred(FLineInxTop) do begin
            if Odd(i) then
              FLineIndex.Exchange((i*2)-1, i)
            else
              FLineIndex.Exchange(i*2, i);
          end;
          FLineInxStep := FLineInxStep * 2;
        end;
        FLineIndex[FLineInxTop] := pointer(CurLine);
        FLineIndex[FLineInxTop+1] := pointer(CurOfs);
        if (aOffset <= CurOfs) then
          Done := true;
      end;
    end;
  end;
  {we can now work out where the nearest item in the index is to the
   line we require}
  L := 1;
  R := FLineInxTop+1;
  while (L <= R) do begin
    M := (L + R) div 2;
    if not Odd(M) then
      inc(M);
    if (aOffset < longint(FLineIndex[M])) then
      R := M - 2
    else if (aOffset > longint(FLineIndex[M])) then
      L := M + 2
    else begin
      FLineCurrent := longint(FLineIndex[M-1]);
      FLineCurOfs := longint(FLineIndex[M]);
      Seek(FLineCurOfs, soFromBeginning);
      Result := FLineCurrent;
      Exit;
    end;
  end;
  {the item at L-2 will have the nearest smaller offset than the
   one we want, hence the nearest smaller line is at L-3; start here
   and read through the stream forwards}
  CurLine := longint(FLineIndex[L-3]);
  Seek(longint(FLineIndex[L-2]), soFromBeginning);
  while true do begin
    atsGetLine(CurPos, EndPos, Len);
    inc(CurLine);
    if (EndPos > aOffset) then begin
      FLineCurrent := CurLine - 1;
       FLineCurOfs := CurPos;
      Seek(CurPos, soFromBeginning);
      Result := CurLine - 1;
      Exit;
    end
    else if (CurLine = FLineCount) or (EndPos = aOffset) then begin
      FLineCurrent := CurLine;
      FLineCurOfs := EndPos;
      Seek(EndPos, soFromBeginning);
      Result := CurLine;
      Exit;
    end;
  end;
end;

{-----------------------------------------------------------------------------}

function TStAnsiTextStream.SeekLine(aLineNum : longint) : longint;
var
  CurLine : longint;
  CurOfs  : longint;
  CurPos  : longint;
  EndPos  : longint;
  Len     : longint;
  i       : longint;
  Done    : boolean;
  L, R, M : integer;
begin
  {if the line number we want is the current line, reposition at the
   current line offset, return the current line number and exit}
  if (aLineNum = FLineCurrent) then begin
    Seek(FLineCurOfs, soFromBeginning);
    Result := FLineCurrent;
    Exit;
  end;
  {if the line number requested is less than or equal to zero, just
   position at line zero (ie, the start of the stream)}
  if (aLineNum <= 0) then begin
    Seek(0, soFromBeginning);
    FLineCurrent := 0;
    FLineCurOfs := 0;
    Result := 0;
    Exit;
  end;
  {if the line number requested is greater than or equal to the line
   count, position at the end of the stream (note that if we don't
   know the number of lines in the stream yet, FLineCount is set to
   -1)}
  if (FLineCount >= 0) and (aLineNum > FLineCount) then begin
    Seek(0, soFromEnd);
    FLineCurrent := FLineCount;
    FLineCurOfs := FSize;
    Result := FLineCount;
    Exit;
  end;
  {if the line number requested is greater than the top item in the
   line index, we shall have to build up the index until we get to the
   line we require, or just beyond}
  if (aLineNum > longint(FLineIndex[FLineInxTop])) then begin
    {position at the last known line offset}
    CurLine := longint(FLineIndex[FLineInxTop]);
    CurOfs := longint(FLineIndex[FLineInxTop+1]);
    Seek(CurOfs, soFromBeginning);
    Done := false;
    {continue reading lines in chunks of FLineInxStep and add an index
     entry for each chunk}
    while not Done do begin
      for i := 0 to pred(FLineInxStep) do begin
        atsGetLine(CurPos, EndPos, Len);
        inc(CurLine);
        CurOfs := EndPos;
        if (EndPos = FSize) then begin
          Done := true;
          Break;
        end;
      end;
      if Done then
        FLineCount := CurLine
      else begin
        inc(FLineInxTop, 2);
        if (FLineInxTop = (LineIndexCount * 2)) then begin
          {we've exhausted the space in the index: rescale}
          FLineInxTop := FLineInxTop div 2;
          for i := 0 to pred(FLineInxTop) do begin
            if Odd(i) then
              FLineIndex.Exchange((i*2)-1, i)
            else
              FLineIndex.Exchange(i*2, i);
          end;
          FLineInxStep := FLineInxStep * 2;
        end;
        FLineIndex[FLineInxTop] := pointer(CurLine);
        FLineIndex[FLineInxTop+1] := pointer(CurOfs);
        if (aLineNum <= CurLine) then
          Done := true;
      end;
    end;
  end;
  {we can now work out where the nearest item in the index is to the
   line we require}
  L := 0;
  R := FLineInxTop;
  while (L <= R) do begin
    M := (L + R) div 2;
    if Odd(M) then
      dec(M);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -