📄 rm_jclwidestrings.pas.~1~
字号:
end;
end;
function StrEndW(const Str: PWideChar): PWideChar;
begin
Result := Str;
if Result <> nil then
while Result^ <> #0 do
Inc(Result);
end;
function StrCopyW(Dest: PWideChar; const Source: PWideChar): PWideChar;
var
Src: PWideChar;
begin
Result := Dest;
if Dest <> nil then
begin
Src := Source;
if Src <> nil then
while Src^ <> #0 do
begin
Dest^ := Src^;
Inc(Src);
Inc(Dest);
end;
Dest^ := #0;
end;
end;
function StrECopyW(Dest: PWideChar; const Source: PWideChar): PWideChar;
var
Src: PWideChar;
begin
if Dest <> nil then
begin
Src := Source;
if Src <> nil then
while Src^ <> #0 do
begin
Dest^ := Src^;
Inc(Src);
Inc(Dest);
end;
Dest^ := #0;
end;
Result := Dest;
end;
function StrLCopyW(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar;
var
Src: PWideChar;
begin
Result := Dest;
if (Dest <> nil) and (MaxLen > 0) then
begin
Src := Source;
if Src <> nil then
while (MaxLen > 0) and (Src^ <> #0) do
begin
Dest^ := Src^;
Inc(Src);
Inc(Dest);
Dec(MaxLen);
end;
Dest^ := #0;
end;
end;
function StrCatW(Dest: PWideChar; const Source: PWideChar): PWideChar;
begin
Result := Dest;
StrCopyW(StrEndW(Dest), Source);
end;
function StrLCatW(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar;
begin
Result := Dest;
StrLCopyW(StrEndW(Dest), Source, MaxLen);
end;
function StrMoveW(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar;
begin
Result := Dest;
if Count > 0 then
Move(Source^, Dest^, Integer(Count) * SizeOf(WideChar));
end;
function StrPCopyWW(Dest: PWideChar; const Source: WideString): PWideChar;
begin
Result := StrLCopyW(Dest, PWideChar(Source), Length(Source));
end;
function StrPLCopyWW(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar;
begin
Result := StrLCopyW(Dest, PWideChar(Source), MaxLen);
end;
function StrRScanW(const Str: PWideChar; Chr: WideChar): PWideChar;
var
P: PWideChar;
begin
Result := nil;
if Str <> nil then
begin
P := Str;
repeat
if P^ = Chr then
Result := P;
Inc(P);
until P^ = #0;
end;
end;
// (rom) following functions copied from JclUnicode.pas
// exchanges in each character of the given string the low order and high order
// byte to go from LSB to MSB and vice versa.
// EAX contains address of string
procedure StrSwapByteOrder(Str: PWideChar);
asm
PUSH ESI
PUSH EDI
MOV ESI, EAX
MOV EDI, ESI
XOR EAX, EAX // clear high order byte to be able to use 32bit operand below
@@1:
LODSW
OR EAX, EAX
JZ @@2
XCHG AL, AH
STOSW
JMP @@1
@@2:
POP EDI
POP ESI
end;
function StrNScanW(const Str1, Str2: PWideChar): Integer;
// Determines where (in Str1) the first time one of the characters of Str2 appear.
// The result is the length of a string part of Str1 where none of the characters of
// Str2 do appear (not counting the trailing #0 and starting with position 0 in Str1).
var
Run: PWideChar;
begin
Result := -1;
if (Str1 <> nil) and (Str2 <> nil) then
begin
Run := Str1;
while Run^ <> #0 do
begin
if StrScanW(Str2, Run^) <> nil then
Break;
Inc(Run);
end;
Result := Run - Str1;
end;
end;
function StrRNScanW(const Str1, Str2: PWideChar): Integer;
// This function does the same as StrRNScanW but uses Str1 in reverse order. This
// means Str1 points to the last character of a string, is traversed reversely
// and terminates with a starting #0. This is useful for parsing strings stored
// in reversed macro buffers etc.
var
Run: PWideChar;
begin
Result := -1;
if (Str1 <> nil) and (Str2 <> nil) then
begin
Run := Str1;
while Run^ <> #0 do
begin
if StrScanW(Str2, Run^) <> nil then
Break;
Dec(Run);
end;
Result := Str1 - Run;
end;
end;
// Returns a pointer to first occurrence of a specified character in a string
// or nil if not found.
// Note: this is just a binary search for the specified character and there's no
// check for a terminating null. Instead at most StrLen characters are
// searched. This makes this function extremly fast.
//
// on enter EAX contains Str, EDX contains Chr and ECX StrLen
// on exit EAX contains result pointer or nil
function StrScanW(Str: PWideChar; Chr: WideChar; StrLen: Cardinal): PWideChar;
asm
TEST EAX, EAX
JZ @@Exit // get out if the string is nil or StrLen is 0
JCXZ @@Exit
@@Loop:
CMP [EAX], DX // this unrolled loop is actually faster on modern processors
JE @@Exit // than REP SCASW
ADD EAX, 2
DEC ECX
JNZ @@Loop
XOR EAX, EAX
@@Exit:
end;
function StrBufSizeW(const Str: PWideChar): Cardinal;
// Returns max number of wide characters that can be stored in a buffer
// allocated by StrAllocW.
var
P: PWideChar;
begin
if Str <> nil then
begin
P := Str;
Dec(P, SizeOf(Cardinal) div SizeOf(WideChar));
Result := (Cardinal(PInteger(P)^) - SizeOf(Cardinal)) div SizeOf(WideChar);
end
else
Result := 0;
end;
function StrPCopyW(Dest: PWideChar; const Source: string): PWideChar;
// copies a Pascal-style string to a null-terminated wide string
begin
Result := StrPLCopyW(Dest, Source, Cardinal(Length(Source)));
Result[Length(Source)] := WideNull;
end;
function StrPLCopyW(Dest: PWideChar; const Source: string; MaxLen: Cardinal): PWideChar;
// copies characters from a Pascal-style string into a null-terminated wide string
asm
PUSH EDI
PUSH ESI
MOV EDI, EAX
MOV ESI, EDX
MOV EDX, EAX
XOR AX, AX
@@1: LODSB
STOSW
DEC ECX
JNZ @@1
MOV EAX, EDX
POP ESI
POP EDI
end;
//=== WideString functions ===================================================
function WidePos(const SubStr, S: WideString): Integer;
var
P: PWideChar;
begin
P := StrPosW(PWideChar(S), PWideChar(SubStr));
if P <> nil then
Result := P - PWideChar(S) + 1
else
Result := 0;
end;
// original code by Mike Lischke (extracted from JclUnicode.pas)
function WideQuotedStr(const S: WideString; Quote: WideChar): WideString;
var
P, Src,
Dest: PWideChar;
AddCount: Integer;
begin
AddCount := 0;
P := StrScanW(PWideChar(S), Quote);
while P <> nil do
begin
Inc(P);
Inc(AddCount);
P := StrScanW(P, Quote);
end;
if AddCount = 0 then
Result := Quote + S + Quote
else
begin
SetLength(Result, Length(S) + AddCount + 2);
Dest := PWideChar(Result);
Dest^ := Quote;
Inc(Dest);
Src := PWideChar(S);
P := StrScanW(Src, Quote);
repeat
Inc(P);
MoveWideChar(Src^, Dest^, P - Src);
Inc(Dest, P - Src);
Dest^ := Quote;
Inc(Dest);
Src := P;
P := StrScanW(Src, Quote);
until P = nil;
P := StrEndW(Src);
MoveWideChar(Src^, Dest^, P - Src);
Inc(Dest, P - Src);
Dest^ := Quote;
end;
end;
// original code by Mike Lischke (extracted from JclUnicode.pas)
function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): WideString;
var
P, Dest: PWideChar;
DropCount: Integer;
begin
Result := '';
if (Src = nil) or (Src^ <> Quote) then
Exit;
Inc(Src);
DropCount := 1;
P := Src;
Src := StrScanW(Src, Quote);
while Src <> nil do // count adjacent pairs of quote chars
begin
Inc(Src);
if Src^ <> Quote then
Break;
Inc(Src);
Inc(DropCount);
Src := StrScanW(Src, Quote);
end;
if Src = nil then
Src := StrEndW(P);
if (Src - P) <= 1 then
Exit;
if DropCount = 1 then
SetString(Result, P, Src - P - 1)
else
begin
SetLength(Result, Src - P - DropCount);
Dest := PWideChar(Result);
Src := StrScanW(P, Quote);
while Src <> nil do
begin
Inc(Src);
if Src^ <> Quote then
Break;
MoveWideChar(P^, Dest^, Src - P);
Inc(Dest, Src - P);
Inc(Src);
P := Src;
Src := StrScanW(Src, Quote);
end;
if Src = nil then
Src := StrEndW(P);
MoveWideChar(P^, Dest^, Src - P - 1);
end;
end;
function TrimW(const S: WideString): WideString;
// available from Delphi 7 up
{$IFDEF RTL150_UP}
begin
Result := Trim(S);
end;
{$ELSE ~RTL150_UP}
var
I, L: Integer;
begin
L := Length(S);
I := 1;
while (I <= L) and (S[I] <= ' ') do
Inc(I);
if I > L then
Result := ''
else
begin
while S[L] <= ' ' do
Dec(L);
Result := Copy(S, I, L - I + 1);
end;
end;
{$ENDIF ~RTL150_UP}
function TrimLeftW(const S: WideString): WideString;
// available from Delphi 7 up
{$IFDEF RTL150_UP}
begin
Result := TrimLeft(S);
end;
{$ELSE ~RTL150_UP}
var
I, L: Integer;
begin
L := Length(S);
I := 1;
while (I <= L) and (S[I] <= ' ') do
Inc(I);
Result := Copy(S, I, Maxint);
end;
{$ENDIF ~RTL150_UP}
function TrimRightW(const S: WideString): WideString;
// available from Delphi 7 up
{$IFDEF RTL150_UP}
begin
Result := TrimRight(S);
end;
{$ELSE ~RTL150_UP}
var
I: Integer;
begin
I := Length(S);
while (I > 0) and (S[I] <= ' ') do
Dec(I);
Result := Copy(S, 1, I);
end;
{$ENDIF ~RTL150_UP}
// functions missing in Delphi 5 / FPC
{$IFNDEF RTL140_UP}
function WideCompareText(const S1, S2: WideString): Integer;
begin
{$IFDEF MSWINDOWS}
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
Result := AnsiCompareText(string(S1), string(S2))
else
Result := CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
PWideChar(S1), Length(S1), PWideChar(S2), Length(S2)) - 2;
{$ELSE ~MSWINDOWS}
{ TODO : Don't cheat here }
Result := CompareText(S1, S2);
{$ENDIF MSWINDOWS}
end;
function WideCompareStr(const S1, S2: WideString): Integer;
begin
{$IFDEF MSWINDOWS}
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
Result := AnsiCompareStr(string(S1), string(S2))
else
Result := CompareStringW(LOCALE_USER_DEFAULT, 0,
PWideChar(S1), Length(S1), PWideChar(S2), Length(S2)) - 2;
{$ELSE ~MSWINDOWS}
{ TODO : Don't cheat here }
Result := CompareString(S1, S2);
{$ENDIF ~MSWINDOWS}
end;
function WideUpperCase(const S: WideString): WideString;
begin
Result := S;
if Result <> '' then
{$IFDEF MSWINDOWS}
CharUpperBuffW(Pointer(Result), Length(Result));
{$ELSE ~MSWINDOWS}
{ TODO : Don't cheat here }
Result := UpperCase(Result);
{$ENDIF ~MSWINDOWS}
end;
function WideLowerCase(const S: WideString): WideString;
begin
Result := S;
if Result <> '' then
{$IFDEF MSWINDOWS}
CharLowerBuffW(Pointer(Result), Length(Result));
{$ELSE ~MSWINDOWS}
{ TODO : Don't cheat here }
Result := LowerCase(Result);
{$ENDIF ~MSWINDOWS}
end;
{$ENDIF ~RTL140_UP}
function TrimLeftLengthW(const S: WideString): Integer;
var
Len: Integer;
begin
Len := Length(S);
Result := 1;
while (Result <= Len) and (S[Result] <= #32) do
Inc(Result);
Result := Len - Result + 1;
end;
function TrimRightLengthW(const S: WideString): Integer;
begin
Result := Length(S);
while (Result > 0) and (S[Result] <= #32) do
Dec(Result);
end;
//=== { TWStrings } ==========================================================
constructor TWStrings.Create;
begin
inherited Create;
// FLineSeparator := WideChar($2028);
{$IFDEF MSWINDOWS}
FLineSeparator := WideChar(13) + '' + WideChar(10); // compiler wants it this way
{$ENDIF MSWINDOWS}
{$IFDEF UNIX}
FLineSeparator := WideChar(10);
{$ENDIF UNIX}
FNameValueSeparator := '=';
FDelimiter := ',';
FQuoteChar := '"';
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -