mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 11:49:24 +02:00
lazutils: UTF8CompareStr: made 64bit safe, added fast PChar versions
git-svn-id: trunk@38103 -
This commit is contained in:
parent
ecfb0f4478
commit
b240df36a1
@ -271,9 +271,9 @@ type
|
|||||||
function CompareCTDirectoryCaches(Data1, Data2: Pointer): integer;
|
function CompareCTDirectoryCaches(Data1, Data2: Pointer): integer;
|
||||||
function CompareAnsiStringAndDirectoryCache(Dir, Cache: Pointer): integer;
|
function CompareAnsiStringAndDirectoryCache(Dir, Cache: Pointer): integer;
|
||||||
|
|
||||||
function ComparePCharFirstCaseInsAThenCase(Data1, Data2: Pointer): integer;
|
function ComparePCharFirstCaseInsAThenCase(Data1, Data2: Pointer): integer; // insensitive ASCII then byte wise
|
||||||
function ComparePCharCaseInsensitiveA(Data1, Data2: Pointer): integer;
|
function ComparePCharCaseInsensitiveA(Data1, Data2: Pointer): integer; // insensitive ASCII
|
||||||
function ComparePCharCaseSensitive(Data1, Data2: Pointer): integer;
|
function ComparePCharCaseSensitive(Data1, Data2: Pointer): integer; // byte wise
|
||||||
|
|
||||||
// unit links
|
// unit links
|
||||||
function SearchUnitInUnitLinks(const UnitLinks, TheUnitName: string;
|
function SearchUnitInUnitLinks(const UnitLinks, TheUnitName: string;
|
||||||
|
@ -25,6 +25,10 @@ function CompareFileExt(const Filename, Ext: string;
|
|||||||
function CompareFilenameStarts(const Filename1, Filename2: string): integer;
|
function CompareFilenameStarts(const Filename1, Filename2: string): integer;
|
||||||
function CompareFilenames(Filename1: PChar; Len1: integer;
|
function CompareFilenames(Filename1: PChar; Len1: integer;
|
||||||
Filename2: PChar; Len2: integer): integer;
|
Filename2: PChar; Len2: integer): integer;
|
||||||
|
function CompareFilenamesP(Filename1, Filename2: PChar;
|
||||||
|
IgnoreCase: boolean = false // false = use default
|
||||||
|
): integer;
|
||||||
|
|
||||||
function DirPathExists(DirectoryName: string): boolean;
|
function DirPathExists(DirectoryName: string): boolean;
|
||||||
function DirectoryIsWritable(const DirectoryName: string): boolean;
|
function DirectoryIsWritable(const DirectoryName: string): boolean;
|
||||||
function ExtractFileNameOnly(const AFilename: string): string;
|
function ExtractFileNameOnly(const AFilename: string): string;
|
||||||
@ -362,6 +366,65 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CompareFilenamesP(Filename1, Filename2: PChar;
|
||||||
|
IgnoreCase: boolean = false): integer;
|
||||||
|
var
|
||||||
|
{$IFDEF darwin}
|
||||||
|
F1: CFStringRef;
|
||||||
|
F2: CFStringRef;
|
||||||
|
Flags: CFStringCompareFlags;
|
||||||
|
{$ELSE}
|
||||||
|
File1, File2: string;
|
||||||
|
Len1: SizeInt;
|
||||||
|
Len2: SizeInt;
|
||||||
|
{$ENDIF}
|
||||||
|
begin
|
||||||
|
if (Filename1=nil) or (Filename1^=#0) then begin
|
||||||
|
if (Filename2=nil) or (Filename2^=#0) then begin
|
||||||
|
// both empty
|
||||||
|
exit(0);
|
||||||
|
end else begin
|
||||||
|
// filename1 empty, filename2 not empty
|
||||||
|
exit(-1);
|
||||||
|
end;
|
||||||
|
end else if (Filename2=nil) or (Filename2^=#0) then begin
|
||||||
|
// filename1 not empty, filename2 empty
|
||||||
|
exit(1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$IFDEF CaseInsensitiveFilenames}
|
||||||
|
// this platform is by default case insensitive
|
||||||
|
IgnoreCase:=true;
|
||||||
|
{$ENDIF}
|
||||||
|
{$IFDEF darwin}
|
||||||
|
F1:=CFStringCreateWithCString(nil,Pointer(Filename1),kCFStringEncodingUTF8);
|
||||||
|
F2:=CFStringCreateWithCString(nil,Pointer(Filename2),kCFStringEncodingUTF8);
|
||||||
|
Flags:=kCFCompareNonliteral;
|
||||||
|
if IgnoreCase then Flags+=kCFCompareCaseInsensitive;
|
||||||
|
Result:=CFStringCompare(F1,F2,Flags);
|
||||||
|
CFRelease(F1);
|
||||||
|
CFRelease(F2);
|
||||||
|
{$ELSE}
|
||||||
|
if IgnoreCase then begin
|
||||||
|
// compare case insensitive
|
||||||
|
Len1:=StrLen(Filename1);
|
||||||
|
SetLength(File1,Len1);
|
||||||
|
System.Move(Filename1^,File1[1],Len1);
|
||||||
|
Len2:=StrLen(Filename2);
|
||||||
|
SetLength(File2,Len2);
|
||||||
|
System.Move(Filename2^,File2[1],Len2);
|
||||||
|
Result:=UTF8CompareText(File1,File2);
|
||||||
|
end else begin
|
||||||
|
// compare literally
|
||||||
|
while (Filename1^=Filename2^) and (Filename1^<>#0) do begin
|
||||||
|
inc(Filename1);
|
||||||
|
Inc(Filename2);
|
||||||
|
end;
|
||||||
|
Result:=ord(Filename1^)-ord(Filename2^);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
function DirPathExists(DirectoryName: string): boolean;
|
function DirPathExists(DirectoryName: string): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=DirectoryExistsUTF8(ChompPathDelim(DirectoryName));
|
Result:=DirectoryExistsUTF8(ChompPathDelim(DirectoryName));
|
||||||
|
@ -88,6 +88,8 @@ procedure AssignUTF8ListToAnsi(UTF8List, AnsiList: TStrings);
|
|||||||
//compare functions
|
//compare functions
|
||||||
|
|
||||||
function UTF8CompareStr(const S1, S2: string): Integer; inline;
|
function UTF8CompareStr(const S1, S2: string): Integer; inline;
|
||||||
|
function UTF8CompareStrP(S1, S2: PChar): Integer;
|
||||||
|
function UTF8CompareStr(S1: PChar; Count1: SizeInt; S2: PChar; Count2: SizeInt): Integer;
|
||||||
function UTF8CompareText(const S1, S2: string): Integer;
|
function UTF8CompareText(const S1, S2: string): Integer;
|
||||||
function CompareStrListUTF8LowerCase(List: TStringList; Index1, Index2: Integer): Integer;
|
function CompareStrListUTF8LowerCase(List: TStringList; Index1, Index2: Integer): Integer;
|
||||||
|
|
||||||
@ -2500,12 +2502,36 @@ end;
|
|||||||
Params: S1, S2 - UTF8 encoded strings
|
Params: S1, S2 - UTF8 encoded strings
|
||||||
Returns: < 0 if S1 < S2, 0 if S1 = S2, > 0 if S2 > S1.
|
Returns: < 0 if S1 < S2, 0 if S1 = S2, > 0 if S2 > S1.
|
||||||
Compare 2 UTF8 encoded strings, case sensitive.
|
Compare 2 UTF8 encoded strings, case sensitive.
|
||||||
Note: Use this function instead of AnsiCompareStr.
|
|
||||||
This function guarantees proper collation on all supported platforms.
|
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function UTF8CompareStr(const S1, S2: string): Integer;
|
function UTF8CompareStr(const S1, S2: string): Integer;
|
||||||
begin
|
begin
|
||||||
Result := SysUtils.CompareStr(S1, S2);
|
Result := UTF8CompareStr(PChar(Pointer(S1)),length(S1),
|
||||||
|
PChar(Pointer(S2)),length(S2));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function UTF8CompareStrP(S1, S2: PChar): Integer;
|
||||||
|
begin
|
||||||
|
Result:=UTF8CompareStr(S1,StrLen(S1),S2,StrLen(S2));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function UTF8CompareStr(S1: PChar; Count1: SizeInt; S2: PChar; Count2: SizeInt
|
||||||
|
): Integer;
|
||||||
|
var
|
||||||
|
Count: SizeInt;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
if Count1>Count2 then
|
||||||
|
Count:=Count2
|
||||||
|
else
|
||||||
|
Count:=Count1;
|
||||||
|
Result := CompareMemRange(Pointer(S1),Pointer(S2), Count); // Note: CompareMemRange can handle nil if Count=0
|
||||||
|
if Result<>0 then exit;
|
||||||
|
if Count1>Count2 then
|
||||||
|
Result:=1
|
||||||
|
else if Count1<Count2 then
|
||||||
|
Result:=-1
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user