Posted: 30.07.2012, 14:16
EgonHugeist,
Tokenizer has to know what rules will be applied by the server and parse strings the same.
Look at my modified tokenizer.
It does what we just need. All we have to do is set FStandardComformingStrings to a valid value.
I'll do it.and could you please insert some much more complicated tests, with accedend chars like 'üöäü'? that would be great!
Look at test I gave you earlier (procedure TZTestPostgreSQLTokenizer.TestQuoteState;)Do we need now GetServerSetting(), FStandartConfirmingStrings, function EncodeString and so on?? What do you think?
Tokenizer has to know what rules will be applied by the server and parse strings the same.
Look at my modified tokenizer.
Code: Select all
{**
Checks whether escape syntax is used.
@return a True if escape syntax is used.
}
function TZPostgreSQLQuoteState.CheckEscapeSyntax(Stream: TStream): Boolean;
var
ReadChar: Char;
begin
Result := not FStandardConformingStrings;
if FStandardConformingStrings then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
if Stream.Position >= SizeOf(Char) then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
Stream.Read(ReadChar, SizeOf(Char));
Result := UpperCase(ReadChar) = 'E';
Stream.Seek(SizeOf(Char), soFromCurrent);
end;
end;
end;
{**
Return a quoted string token from a reader. This method
will collect characters until it sees a match to the
character that the tokenizer used to switch to this state.
@return a quoted string token from a reader
}
function TZPostgreSQLQuoteState.NextToken(Stream: TStream;
FirstChar: Char; Tokenizer: TZTokenizer): TZToken;
const BackSlash = Char('\');
var
ReadChar: Char;
LastChar: Char;
QuoteCount: Integer;
EscapeSyntax: Boolean;
begin
Result.Value := FirstChar;
QuoteCount := 1;
EscapeSyntax := False;
if FirstChar = '"' then
begin
Result.TokenType := ttWord;
end
else
begin
Result.TokenType := ttQuoted;
EscapeSyntax := CheckEscapeSyntax(Stream);
end;
LastChar := #0;
while Stream.Read(ReadChar, SizeOf(Char)) > 0 do
begin
if ReadChar = FirstChar then
Inc(QuoteCount);
if (LastChar = FirstChar) and (ReadChar <> FirstChar) then
begin
if QuoteCount mod 2 = 0 then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
Break;
end;
end;
Result.Value := Result.Value + ReadChar;
if (LastChar = BackSlash) and EscapeSyntax then
LastChar := #0
else if (LastChar = FirstChar) and (ReadChar = FirstChar) then
LastChar := #0
else LastChar := ReadChar;
end;
end;