* Implemented StrictDelimiter without the delphi bugs (mantis #8910)

git-svn-id: trunk@11686 -
This commit is contained in:
michael 2008-09-01 16:06:28 +00:00
parent 42f8738003
commit 64e6d68a64
2 changed files with 99 additions and 45 deletions

View File

@ -503,6 +503,7 @@ type
FUpdateCount: Integer; FUpdateCount: Integer;
FAdapter: IStringsAdapter; FAdapter: IStringsAdapter;
FLBS : TTextLineBreakStyle; FLBS : TTextLineBreakStyle;
FStrictDelimiter : Boolean;
function GetCommaText: string; function GetCommaText: string;
function GetName(Index: Integer): string; function GetName(Index: Integer): string;
function GetValue(const Name: string): string; function GetValue(const Name: string): string;
@ -568,6 +569,7 @@ type
Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS; Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS;
property Delimiter: Char read FDelimiter write SetDelimiter; property Delimiter: Char read FDelimiter write SetDelimiter;
property DelimitedText: string read GetDelimitedText write SetDelimitedText; property DelimitedText: string read GetDelimitedText write SetDelimitedText;
Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
property QuoteChar: Char read FQuoteChar write SetQuoteChar; property QuoteChar: Char read FQuoteChar write SetQuoteChar;
Property NameValueSeparator : Char Read FNameValueSeparator Write SetNameValueSeparator; Property NameValueSeparator : Char Read FNameValueSeparator Write SetNameValueSeparator;
property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex; property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;

View File

@ -92,18 +92,22 @@ function TStrings.GetCommaText: string;
Var Var
C1,C2 : Char; C1,C2 : Char;
FSD : Boolean;
begin begin
CheckSpecialChars; CheckSpecialChars;
FSD:=StrictDelimiter;
C1:=Delimiter; C1:=Delimiter;
C2:=QuoteChar; C2:=QuoteChar;
Delimiter:=','; Delimiter:=',';
QuoteChar:='"'; QuoteChar:='"';
StrictDelimiter:=False;
Try Try
Result:=GetDelimitedText; Result:=GetDelimitedText;
Finally Finally
Delimiter:=C1; Delimiter:=C1;
QuoteChar:=C2; QuoteChar:=C2;
StrictDelimiter:=FSD;
end; end;
end; end;
@ -113,22 +117,31 @@ Function TStrings.GetDelimitedText: string;
Var Var
I : integer; I : integer;
p : pchar; p : pchar;
c : set of char;
S : String;
begin begin
CheckSpecialChars; CheckSpecialChars;
result:=''; result:='';
if StrictDelimiter then
c:=[#0,Delimiter]
else
c:=[#0..' ',QuoteChar,Delimiter];
For i:=0 to count-1 do For i:=0 to count-1 do
begin begin
p:=pchar(strings[i]); S:=Strings[i];
while not(p^ in [#0..' ',QuoteChar,Delimiter]) do p:=pchar(S);
while not(p^ in c) do
inc(p); inc(p);
// strings in list may contain #0 // strings in list may contain #0
if p<>pchar(strings[i])+length(strings[i]) then if (p<>pchar(S)+length(S)) and not StrictDelimiter then
Result:=Result+QuoteString (Strings[I],QuoteChar) Result:=Result+QuoteString(S,QuoteChar)
else else
result:=result+strings[i]; Result:=Result+S;
if I<Count-1 then Result:=Result+Delimiter; if I<Count-1 then
Result:=Result+Delimiter;
end; end;
If (Length(Result)=0)and(count=1) then If (Length(Result)=0) and (Count=1) then
Result:=QuoteChar+QuoteChar; Result:=QuoteChar+QuoteChar;
end; end;
@ -223,6 +236,26 @@ end;
Procedure TStrings.SetDelimitedText(const AValue: string); Procedure TStrings.SetDelimitedText(const AValue: string);
Procedure SetStrictDelimited;
Var
P,PL : Integer;
begin
PL:=1;
P:=1;
{
While Length(S)>0 do
begin
P:=Pos(FDelimiter,S);
If (P=0) then
P:=Length(S)+1;
Add(Copy(S,1,P-1));
System.Delete(S,1,P));
end;
} end;
var i,j:integer; var i,j:integer;
aNotFirst:boolean; aNotFirst:boolean;
begin begin
@ -230,52 +263,71 @@ begin
BeginUpdate; BeginUpdate;
i:=1; i:=1;
j:=1;
aNotFirst:=false; aNotFirst:=false;
try try
Clear; Clear;
while i<=length(AValue) do begin If StrictDelimiter then
// skip delimiter begin
if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i); // Easier, faster loop.
While I<=Length(AValue) do
begin
If (AValue[I] in [FDelimiter,#0]) then
begin
Add(Copy(AValue,J,I-J));
J:=I+1;
end;
Inc(i);
end;
If (Length(AValue)>0) then
Add(Copy(AValue,J,I-J));
end
else
begin
while i<=length(AValue) do begin
// skip delimiter
if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i);
// skip spaces // skip spaces
while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i); while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
// read next string // read next string
if i<=length(AValue) then begin if i<=length(AValue) then begin
if AValue[i]=FQuoteChar then begin if AValue[i]=FQuoteChar then begin
// next string is quoted // next string is quoted
j:=i+1; j:=i+1;
while (j<=length(AValue)) and while (j<=length(AValue)) and
( (AValue[j]<>FQuoteChar) or ( (AValue[j]<>FQuoteChar) or
( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin
if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2) if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2)
else inc(j); else inc(j);
end;
// j is position of closing quote
Add( StringReplace (Copy(AValue,i+1,j-i-1),
FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll]));
i:=j+1;
end else begin
// next string is not quoted
j:=i;
while (j<=length(AValue)) and
(Ord(AValue[j])>Ord(' ')) and
(AValue[j]<>FDelimiter) do inc(j);
Add( Copy(AValue,i,j-i));
i:=j;
end;
end else begin
if aNotFirst then Add('');
end; end;
// j is position of closing quote
Add( StringReplace (Copy(AValue,i+1,j-i-1), // skip spaces
FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll])); while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
i:=j+1;
end else begin aNotFirst:=true;
// next string is not quoted end;
j:=i;
while (j<=length(AValue)) and
(Ord(AValue[j])>Ord(' ')) and
(AValue[j]<>FDelimiter) do inc(j);
Add( Copy(AValue,i,j-i));
i:=j;
end; end;
end else begin
if aNotFirst then Add('');
end;
// skip spaces
while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
aNotFirst:=true;
end;
finally finally
EndUpdate; EndUpdate;
end; end;
end; end;