📄 jclwidestrings.pas
字号:
{$IFDEF RTL140_UP}
FQuoteChar := CharToWideChar(TStrings(Source).QuoteChar);
FDelimiter := CharToWideChar(TStrings(Source).Delimiter);
{$ENDIF RTL140_UP}
AddStrings(TStrings(Source));
finally
EndUpdate;
end;
end
else
inherited Assign(Source);
end;
procedure TWStrings.AssignTo(Dest: TPersistent);
var
I: Integer;
begin
if Dest is TStrings then
begin
TStrings(Dest).BeginUpdate;
try
TStrings(Dest).Clear;
{$IFDEF RTL150_UP}
TStrings(Dest).NameValueSeparator := WideCharToChar(NameValueSeparator);
{$ENDIF RTL150_UP}
{$IFDEF RTL140_UP}
TStrings(Dest).QuoteChar := WideCharToChar(QuoteChar);
TStrings(Dest).Delimiter := WideCharToChar(Delimiter);
{$ENDIF RTL140_UP}
for I := 0 to Count - 1 do
TStrings(Dest).AddObject(GetP(I)^, Objects[I]);
finally
TStrings(Dest).EndUpdate;
end;
end
else
inherited AssignTo(Dest);
end;
procedure TWStrings.BeginUpdate;
begin
if FUpdateCount = 0 then
SetUpdateState(True);
Inc(FUpdateCount);
end;
function TWStrings.CompareStrings(const S1, S2: WideString): Integer;
begin
Result := WideCompareText(S1, S2);
end;
function TWStrings.CreateAnsiStringList: TStrings;
var
I: Integer;
begin
Result := TStringList.Create;
try
Result.BeginUpdate;
for I := 0 to Count - 1 do
Result.AddObject(GetP(I)^, Objects[I]);
Result.EndUpdate;
except
Result.Free;
raise;
end;
end;
procedure TWStrings.DefineProperties(Filer: TFiler);
function DoWrite: Boolean;
begin
if Filer.Ancestor <> nil then
begin
Result := True;
if Filer.Ancestor is TWStrings then
Result := not Equals(TWStrings(Filer.Ancestor))
end
else
Result := Count > 0;
end;
begin
Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite);
end;
procedure TWStrings.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then
SetUpdateState(False);
end;
function TWStrings.Equals(Strings: TStrings): Boolean;
var
I: Integer;
begin
Result := False;
if Strings.Count = Count then
begin
for I := 0 to Count - 1 do
if Strings[I] <> PStrings[I]^ then
Exit;
Result := True;
end;
end;
function TWStrings.Equals(Strings: TWStrings): Boolean;
var
I: Integer;
begin
Result := False;
if Strings.Count = Count then
begin
for I := 0 to Count - 1 do
if Strings[I] <> PStrings[I]^ then
Exit;
Result := True;
end;
end;
procedure TWStrings.Exchange(Index1, Index2: Integer);
var
TempObject: TObject;
TempString: WideString;
begin
BeginUpdate;
try
TempString := PStrings[Index1]^;
TempObject := Objects[Index1];
PStrings[Index1]^ := PStrings[Index2]^;
Objects[Index1] := Objects[Index2];
PStrings[Index2]^ := TempString;
Objects[Index2] := TempObject;
finally
EndUpdate;
end;
end;
function TWStrings.ExtractName(const S: WideString): WideString;
var
Index: Integer;
begin
Result := S;
Index := WidePos(NameValueSeparator, Result);
if Index <> 0 then
SetLength(Result, Index - 1)
else
SetLength(Result, 0);
end;
function TWStrings.Get(Index: Integer): WideString;
begin
Result := GetP(Index)^;
end;
function TWStrings.GetCapacity: Integer;
begin
Result := Count;
end;
function TWStrings.GetCommaText: WideString;
begin
Result := GetDelimitedTextEx(',', '"');
end;
function TWStrings.GetDelimitedText: WideString;
begin
Result := GetDelimitedTextEx(FDelimiter, FQuoteChar);
end;
function TWStrings.GetDelimitedTextEx(ADelimiter, AQuoteChar: WideChar): WideString;
var
S: WideString;
P: PWideChar;
I, Num: Integer;
begin
Num := GetCount;
if (Num = 1) and (GetP(0)^ = '') then
Result := AQuoteChar + '' + AQuoteChar // Compiler wants it this way
else
begin
Result := '';
for I := 0 to Count - 1 do
begin
S := GetP(I)^;
P := PWideChar(S);
while True do
begin
case P[0] of
WideChar(0)..WideChar(32):
Inc(P);
else
if (P[0] = AQuoteChar) or (P[0] = ADelimiter) then
Inc(P)
else
Break;
end;
end;
if P[0] <> WideChar(0) then
S := WideQuotedStr(S, AQuoteChar);
Result := Result + S + ADelimiter;
end;
System.Delete(Result, Length(Result), 1);
end;
end;
function TWStrings.GetName(Index: Integer): WideString;
var
I: Integer;
begin
Result := GetP(Index)^;
I := WidePos(FNameValueSeparator, Result);
if I > 0 then
SetLength(Result, I - 1);
end;
function TWStrings.GetObject(Index: Integer): TObject;
begin
Result := nil;
end;
function TWStrings.GetText: PWideChar;
begin
Result := StrNewW(GetTextStr);
end;
function TWStrings.GetTextStr: WideString;
var
I: Integer;
Len, LL: Integer;
P: PWideChar;
W: PWideString;
begin
Len := 0;
LL := Length(LineSeparator);
for I := 0 to Count - 1 do
Inc(Len, Length(GetP(I)^) + LL);
SetLength(Result, Len);
P := PWideChar(Result);
for I := 0 to Count - 1 do
begin
W := GetP(I);
Len := Length(W^);
if Len > 0 then
begin
MoveWideChar(W^[1], P[0], Len);
Inc(P, Len);
end;
if LL > 0 then
begin
MoveWideChar(FLineSeparator[1], P[0], LL);
Inc(P, LL);
end;
end;
end;
function TWStrings.GetValue(const Name: WideString): WideString;
var
Idx: Integer;
begin
Idx := IndexOfName(Name);
if Idx >= 0 then
Result := GetValueFromIndex(Idx)
else
Result := '';
end;
function TWStrings.GetValueFromIndex(Index: Integer): WideString;
var
I: Integer;
begin
Result := GetP(Index)^;
I := WidePos(FNameValueSeparator, Result);
if I > 0 then
System.Delete(Result, 1, I)
else
Result := '';
end;
function TWStrings.IndexOf(const S: WideString): Integer;
begin
for Result := 0 to Count - 1 do
if CompareStrings(GetP(Result)^, S) = 0 then
Exit;
Result := -1;
end;
function TWStrings.IndexOfName(const Name: WideString): Integer;
begin
for Result := 0 to Count - 1 do
if CompareStrings(Names[Result], Name) = 0 then
Exit;
Result := -1;
end;
function TWStrings.IndexOfObject(AObject: TObject): Integer;
begin
for Result := 0 to Count - 1 do
if Objects[Result] = AObject then
Exit;
Result := -1;
end;
procedure TWStrings.Insert(Index: Integer; const S: WideString);
begin
InsertObject(Index, S, nil);
end;
procedure TWStrings.InsertObject(Index: Integer; const S: WideString;
AObject: TObject);
begin
end;
procedure TWStrings.LoadFromFile(const FileName: AnsiString;
WideFileOptions: TWideFileOptions = []);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream, WideFileOptions);
finally
Stream.Free;
end;
end;
procedure TWStrings.LoadFromStream(Stream: TStream;
WideFileOptions: TWideFileOptions = []);
var
AnsiS: AnsiString;
WideS: WideString;
WC: WideChar;
begin
BeginUpdate;
try
Clear;
if foAnsiFile in WideFileOptions then
begin
Stream.Read(WC, SizeOf(WC));
Stream.Seek(-SizeOf(WC), soFromCurrent);
if (Hi(Word(WC)) <> 0) and (WC <> BOM_LSB_FIRST) and (WC <> BOM_MSB_FIRST) then
begin
SetLength(AnsiS, Stream.Size - Stream.Position);
Stream.Read(AnsiS[1], Length(AnsiS));
SetTextStr(AnsiS);
Exit;
end;
end;
Stream.Read(WC, SizeOf(WC));
if (WC <> BOM_LSB_FIRST) and (WC <> BOM_MSB_FIRST) then
Stream.Seek(-SizeOf(WC), soFromCurrent);
SetLength(WideS, Stream.Size - Stream.Position);
Stream.Read(WideS[1], Length(WideS) * SizeOf(WideChar));
if WC = BOM_MSB_FIRST then
SwapWordByteOrder(Pointer(WideS), Length(WideS));
SetTextStr(WideS);
finally
EndUpdate;
end;
end;
procedure TWStrings.Move(CurIndex, NewIndex: Integer);
var
TempObject: TObject;
TempString: WideString;
begin
if CurIndex <> NewIndex then
begin
BeginUpdate;
try
TempString := GetP(CurIndex)^;
TempObject := GetObject(CurIndex);
Delete(CurIndex);
InsertObject(NewIndex, TempString, TempObject);
finally
EndUpdate;
end;
end;
end;
procedure TWStrings.ReadData(Reader: TReader);
begin
BeginUpdate;
try
Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
if Reader.NextValue in [vaLString, vaString] then
Add(Reader.ReadString)
else
Add(Reader.ReadWideString);
Reader.ReadListEnd;
finally
EndUpdate;
end;
end;
procedure TWStrings.SaveToFile(const FileName: AnsiString;
WideFileOptions: TWideFileOptions = []);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
SaveToStream(Stream, WideFileOptions);
finally
Stream.Free;
end;
end;
procedure TWStrings.SaveToStream(Stream: TStream;
WideFileOptions: TWideFileOptions = []);
var
AnsiS: AnsiString;
WideS: WideString;
WC: WideChar;
begin
if foAnsiFile in WideFileOptions then
begin
AnsiS := GetTextStr;
Stream.Write(AnsiS[1], Length(AnsiS));
end
else
begin
if foUnicodeLB in WideFileOptions then
begin
WC := BOM_LSB_FIRST;
Stream.Write(WC, SizeOf(WC));
end;
WideS := GetTextStr;
Stream.Write(WideS[1], Length(WideS) * SizeOf(WideChar));
end;
end;
procedure TWStrings.SetCapacity(NewCapacity: Integer);
begin
end;
procedure TWStrings.SetCommaText(const Value: WideString);
begin
SetDelimitedTextEx(',', '"', Value);
end;
procedure TWStrings.SetDelimitedText(const Value: WideString);
begin
SetDelimitedTextEx(Delimiter, QuoteChar, Value);
end;
procedure TWStrings.SetDelimitedTextEx(ADelimiter, AQuoteChar: WideChar;
const Value: WideString);
var
P, P1: PWideChar;
S: WideString;
procedure IgnoreWhiteSpace(var P: PWideChar);
begin
while True do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -