Я взял код из вашего ранее принятого ответа и немного изменил его, добавив две дополнительные переменные:
FPosInt: NativeUInt;
FSize: NativeUInt;
FSize
инициализируется с длиной строки в конструкторе (длина переменной строки хранится в то время как PChar нет).
FPosInt
- номер текущего символа в вашем файле. Дополнительный код в конструкторе:
FSize := Length(FData);
FPosInt := 0;
Соответствующая часть в функции GetNextToken
больше не останавливается на первом нулевом байте, но продолжается до тех пор, пока не будет достигнут последний символ строки:
// skip whitespace; this test could be converted to an unsigned int
// subtraction and compare for only a single branch
while (cp^ <= #32) and (FPosInt < FSize) do
begin
Inc(cp);
Inc(FPosInt);
end;
// end of file is reached if the position counter has reached the filesize
Result := FPosInt < FSize;
Я переключил два оператора в условии while, так как они оцениваются слева направо, и первый из них чаще всего оценивается как ложный.
Альтернативный подход не учитывает количество символов, но сохраняет начальную позицию указателя. В конструкторе:
FSize := Length(FData);
FStartPos := NativeUInt(FCurrPos);
А в GetNextToken
:
// skip whitespace; this test could be converted to an unsigned int
// subtraction and compare for only a single branch
while (cp^ <= #32) and ((NativeUInt(cp) - FStartPos) < FSize) do
Inc(cp);
// end of file is reached if the position counter has reached the filesize
Result := (NativeUInt(cp) - FStartPos) < FSize;