LazUtils: move the more UTF8 file routines to LazFileUtils (and inline them in FileUtil):

FindFirstUTF8, FindNextUTF8, FindCloseUTF8, DeleteFileUTF8, RenameFileUTF8,
GetCurrentDirUTF8, SetCurrentDirUTF8, CreateDirUTF8, RemoveDirUTF8,
FilenameIsAbsolute, FilenameIsWinAbsolute and FilenameIsUnixAbsolute.

git-svn-id: trunk@41348 -
This commit is contained in:
bart 2013-05-22 10:24:41 +00:00
parent 37d130d8ed
commit b59ec93c89
7 changed files with 373 additions and 516 deletions

View File

@ -130,11 +130,58 @@ begin
Result := LazFileUtils.FileCreateUtf8(FileName, Rights);
end;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
begin
Result := LazFileUtils.FindFirstUtf8(Path, Attr, Rslt);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Result := LazFileUtils.FindNextUTF8(Rslt);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
LazFileUtils.FindCloseUtf8(F);
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result := LazFileUtils.DeleteFileUtf8(FileName);
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result := LazFileUtils.RenameFileUtf8(OldName, NewName);
end;
function GetCurrentDirUTF8: String;
begin
Result := LazFileUtils.GetCurrentDirUtf8();
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result := LazFileUtils.SetCurrentDirUtf8(NewDir);
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result := LazFileUtils.CreateDirUtf8(NewDir);
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result := LazFileUtils.RemoveDirUtf8(Dir);
end;
function ParamStrUTF8(Param: Integer): string;
begin
Result:=SysToUTF8(ObjPas.ParamStr(Param));
end;
function GetEnvironmentStringUTF8(Index: Integer): String;
begin
// on Windows SysUtils.GetEnvironmentString returns OEM encoded string
@ -293,17 +340,19 @@ begin
end;
end;
function FilenameIsAbsolute(const TheFilename: string):boolean;
begin
Result := LazFileUtils.FilenameIsAbsolute(TheFileName);
end;
function FilenameIsWinAbsolute(const TheFilename: string): boolean;
begin
Result:=((length(TheFilename)>=3) and
(TheFilename[1] in ['A'..'Z','a'..'z']) and (TheFilename[2]=':') and (TheFilename[3]='\'))
or ((length(TheFilename)>=2) and (TheFilename[1]='\') and (TheFilename[2]='\'))
;
Result := LazFileUtils.FilenameIsWinAbsolute(TheFileName);
end;
function FilenameIsUnixAbsolute(const TheFilename: string): boolean;
begin
Result:=(TheFilename<>'') and (TheFilename[1]='/');
Result := LazFileUtils.FilenameIsUnixAbsolute(TheFileName);
end;
function FilenameIsPascalUnit(const Filename: string): boolean;

View File

@ -74,9 +74,9 @@ function CompareFilenames(const Filename1, Filename2: string;
ResolveLinks: boolean): integer;
function CompareFilenames(Filename1: PChar; Len1: integer;
Filename2: PChar; Len2: integer; ResolveLinks: boolean): integer;
function FilenameIsAbsolute(const TheFilename: string):boolean;
function FilenameIsWinAbsolute(const TheFilename: string):boolean;
function FilenameIsUnixAbsolute(const TheFilename: string):boolean;
function FilenameIsAbsolute(const TheFilename: string):boolean; inline;
function FilenameIsWinAbsolute(const TheFilename: string):boolean; inline;
function FilenameIsUnixAbsolute(const TheFilename: string):boolean; inline;
procedure CheckIfFileIsExecutable(const AFilename: string);
procedure CheckIfFileIsSymlink(const AFilename: string);
function FileIsReadable(const AFilename: string): boolean;
@ -247,20 +247,20 @@ function DirectoryExistsUTF8(const Directory: string): Boolean; inline;
function ExpandFileNameUTF8(const FileName: string): string; inline;
function ExpandUNCFileNameUTF8(const FileName: string): string;
function ExtractShortPathNameUTF8(Const FileName : String) : String;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
procedure FindCloseUTF8(var F: TSearchrec);
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint; inline;
function FindNextUTF8(var Rslt: TSearchRec): Longint; inline;
procedure FindCloseUTF8(var F: TSearchrec); inline;
function FileSetDateUTF8(const FileName: String; Age: Longint): Longint; inline;
function FileGetAttrUTF8(const FileName: String): Longint; inline;
function FileSetAttrUTF8(const Filename: String; Attr: longint): Longint; inline;
function DeleteFileUTF8(const FileName: String): Boolean;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
function DeleteFileUTF8(const FileName: String): Boolean; inline;
function RenameFileUTF8(const OldName, NewName: String): Boolean; inline;
function FileSearchUTF8(const Name, DirList : String; ImplicitCurrentDir : Boolean = True): String;
function FileIsReadOnlyUTF8(const FileName: String): Boolean;
function GetCurrentDirUTF8: String;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
function CreateDirUTF8(const NewDir: String): Boolean;
function RemoveDirUTF8(const Dir: String): Boolean;
function GetCurrentDirUTF8: String; inline;
function SetCurrentDirUTF8(const NewDir: String): Boolean; inline;
function CreateDirUTF8(const NewDir: String): Boolean; inline;
function RemoveDirUTF8(const Dir: String): Boolean; inline;
function ForceDirectoriesUTF8(const Dir: string): Boolean;
function FileOpenUTF8(Const FileName : string; Mode : Integer) : THandle; inline;
function FileCreateUTF8(Const FileName : string) : THandle; overload; inline;
@ -296,7 +296,6 @@ uses
{$i unixfileutil.inc}
{$ENDIF}
initialization
InitFileUtils;
end.

View File

@ -1071,40 +1071,13 @@ end;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec
): Longint;
begin
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Rslt.Name:=UTF8ToSys(Rslt.Name);
Result:=SysUtils.FindNext(Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
if Result then
InvalidateFileStateCache;
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
if Result then
InvalidateFileStateCache;
end;
function FileSearchUTF8(const Name, DirList: String): String;
begin
@ -1116,20 +1089,11 @@ begin
Result:=SysUtils.FileIsReadOnly(UTF8ToSys(Filename));
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
end;
function ForceDirectoriesUTF8(const Dir: string): Boolean;
begin

View File

@ -267,14 +267,6 @@ begin
Result:='';
end;
{------------------------------------------------------------------------------
function FilenameIsAbsolute(const TheFilename: string):boolean;
------------------------------------------------------------------------------}
function FilenameIsAbsolute(const TheFilename: string):boolean;
begin
Result:=FilenameIsUnixAbsolute(TheFilename);
end;
function ConsoleToUTF8(const s: string): string;// converts UTF8 string to console encoding (used by Write, WriteLn)
begin
@ -287,65 +279,10 @@ begin
end;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec
): Longint;
begin
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Rslt.Name:=UTF8ToSys(Rslt.Name);
Result:=SysUtils.FindNext(Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
end;
function GetCurrentDirUTF8: String;
begin
Result:=SysToUTF8(SysUtils.GetCurrentDir);
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
end;
function ExtractShortPathNameUTF8(const FileName: String): String;
begin
Result:=SysToUTF8(SysUtils.ExtractShortPathName(UTF8ToSys(FileName)));
end;
procedure InitFileUtils;
begin
end;

View File

@ -68,6 +68,54 @@ begin
Result := st.st_size;
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
if Result then
InvalidateFileStateCache;
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
if Result then
InvalidateFileStateCache;
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
end;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec
): Longint;
begin
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Rslt.Name:=UTF8ToSys(Rslt.Name);
Result:=SysUtils.FindNext(Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
function ExpandFileNameUtf8(const FileName: string; {const} BaseDir: String = ''): String;
var
IsAbs: Boolean;

View File

@ -130,15 +130,6 @@ begin
Result:=Filename;
end;
{------------------------------------------------------------------------------
function FilenameIsAbsolute(const TheFilename: string):boolean;
------------------------------------------------------------------------------}
function FilenameIsAbsolute(const TheFilename: string):boolean;
begin
Result:=FilenameIsWinAbsolute(TheFilename);
end;
function ConsoleToUTF8(const s: string): string;// converts UTF8 string to console encoding (used by Write, WriteLn)
@ -174,346 +165,6 @@ begin
end;
function WinToDosTime (Var Wtime : TFileTime;var DTime:longint):longbool;
var
lft : TFileTime;
begin
WinToDosTime:=FileTimeToLocalFileTime(WTime,lft)
{$ifndef WinCE}
and FileTimeToDosDateTime(lft,Longrec(Dtime).Hi,LongRec(DTIME).lo)
{$endif}
;
end;
Function DosToWinTime (DosTime:longint;Var Wintime : TFileTime):longbool;
var
lft : TFileTime;
begin
DosToWinTime:=
{$ifndef wince}
DosDateTimeToFileTime(longrec(DosTime).hi,longrec(DosTime).lo,@lft) and
{$endif}
LocalFileTimeToFileTime(lft,Wintime); ;
end;
{------------------------------------------------------------------------------
FindFirstUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function FindFirstAnsi(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
begin
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
{$endif}
function FindMatch(var f: TSearchRec) : Longint;
begin
{ Find file with correct attribute }
While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
begin
if FindNextUTF8(F)<>0 then
begin
Result:=GetLastError;
exit;
end;
end;
{ Convert some attributes back }
WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
f.size:=F.FindData.NFileSizeLow+(qword(maxdword)+1)*F.FindData.NFileSizeHigh;
f.attr:=F.FindData.dwFileAttributes;
{ The structures are different at this point
in win32 it is the ansi structure with a utf-8 string
in wince it is a wide structure }
{$ifdef WinCE}
f.Name:=UTF8Encode(F.FindData.cFileName);
{$else}
f.Name:=F.FindData.cFileName;
{$endif}
Result:=0;
end;
{ This function does not really convert from wide to ansi, but from wide to
a utf-8 encoded ansi version of the data structures in win32 and does
nothing in wince
See FindMatch also }
procedure FindWideToAnsi(const wide: TWIN32FINDDATAW; var ansi: TWIN32FINDDATA);
var
ws: WideString;
an: AnsiString;
begin
{$ifdef WinCE}
ansi := wide;
{$else}
SetLength(ws, length(wide.cAlternateFileName));
Move(wide.cAlternateFileName[0], ws[1], length(ws)*2);
an := AnsiString(ws); // no need to utf8 for cAlternateFileName (it's always ansi encoded)
Move(an[1], ansi.cAlternateFileName, sizeof(ansi.cAlternateFileName));
ws := PWideChar(@wide.cFileName[0]);
an := UTF8Encode(ws);
ansi.cFileName := an;
if length(an)<length(ansi.cFileName) then ansi.cFileName[ length(an)]:=#0;
with ansi do
begin
dwFileAttributes := wide.dwFileAttributes;
ftCreationTime := wide.ftCreationTime;
ftLastAccessTime := wide.ftLastAccessTime;
ftLastWriteTime := wide.ftLastWriteTime;
nFileSizeHigh := wide.nFileSizeHigh;
nFileSizeLow := wide.nFileSizeLow;
dwReserved0 := wide.dwReserved0;
dwReserved1 := wide.dwReserved1;
end;
{$endif}
end;
function FindFirstWide(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
var
find : TWIN32FINDDATAW;
begin
Rslt.Name:=Path;
Rslt.Attr:=attr;
Rslt.ExcludeAttr:=(not Attr) and ($1e);
{ $1e = faHidden or faSysFile or faVolumeID or faDirectory }
{ FindFirstFile is a Win32 Call }
Rslt.FindHandle:=Windows.FindFirstFileW( PWideChar(UTF8Decode(Path)),find);
If Rslt.FindHandle=Invalid_Handle_value then
begin
Result:=GetLastError;
Exit;
end;
{ Find file with correct attribute }
FindWideToAnsi(find, Rslt.FindData);
Result:=FindMatch(Rslt);
end;
{------------------------------------------------------------------------------
FindNextUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function FindNextAnsi(var Rslt: TSearchRec): Longint;
begin
Rslt.Name:=UTF8ToSys(Rslt.Name);
Result:=SysUtils.FindNext(Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
{$endif}
function FindNextWide(var Rslt: TSearchRec): Longint;
var
wide : TWIN32FINDDATAW;
begin
if FindNextFileW(Rslt.FindHandle, wide) then
begin
FindWideToAnsi(wide, Rslt.FindData);
Result := FindMatch(Rslt);
end
else
Result := Integer(GetLastError);
end;
{------------------------------------------------------------------------------
FindNextUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
procedure FindCloseAnsi(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
{$endif}
procedure FindCloseWide(var F: TSearchrec);
begin
Windows.FindClose(f.FindHandle);
end;
{------------------------------------------------------------------------------
DeleteFileUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function DeleteFileAnsi(const FileName: String): Boolean;
begin
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
end;
{$endif}
function DeleteFileWide(const FileName: String): Boolean;
begin
Result:=Windows.DeleteFileW(PWideChar(UTF8Decode(FileName)));
end;
{------------------------------------------------------------------------------
RenameFileUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function RenameFileAnsi(const OldName, NewName: String): Boolean;
begin
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
end;
{$endif}
function RenameFileWide(const OldName, NewName: String): Boolean;
begin
Result:=MoveFileW(PWideChar(UTF8Decode(OldName)), PWideChar(UTF8Decode(NewName)));
end;
{------------------------------------------------------------------------------
GetCurrentDirUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function GetCurrentDirAnsi: String;
begin
Result:=SysToUTF8(SysUtils.GetCurrentDir);
end;
{$endif}
function GetCurrentDirWide: String;
var
w : WideString;
res : Integer;
begin
{$ifdef WinCE}
Result := '\';
// Previously we sent an exception here, which is correct, but this causes
// trouble with code which isnt tested for WinCE, so lets just send a dummy result instead
// Exception.Create('[GetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
{$else}
res:=GetCurrentDirectoryW(0, nil);
SetLength(w, res);
res:=Windows.GetCurrentDirectoryW(res, @w[1]);
SetLength(w, res);
Result:=UTF8Encode(w);
{$endif}
end;
{------------------------------------------------------------------------------
SetCurrentDirUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function SetCurrentDirAnsi(const NewDir: String): Boolean;
begin
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
end;
{$endif}
function SetCurrentDirWide(const NewDir: String): Boolean;
begin
{$ifdef WinCE}
raise Exception.Create('[SetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
{$else}
Result:=Windows.SetCurrentDirectoryW(PWidechar(UTF8Decode(NewDir)));
{$endif}
end;
{------------------------------------------------------------------------------
CreateDirUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function CreateDirAnsi(const NewDir: String): Boolean;
begin
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
end;
{$endif}
function CreateDirWide(const NewDir: String): Boolean;
begin
Result:=Windows.CreateDirectoryW(PWideChar(UTF8Decode(NewDir)), nil);
end;
{------------------------------------------------------------------------------
RemoveDirUTF8
------------------------------------------------------------------------------}
{$ifndef WinCE}
function RemoveDirAnsi(const Dir: String): Boolean;
begin
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
end;
{$endif}
function RemoveDirWide(const Dir: String): Boolean;
begin
Result:=Windows.RemoveDirectoryW(PWideChar(UTF8Decode(Dir)));
end;
var
FindFirst_ : function (const Path: string; Attr: Longint;
out Rslt: TSearchRec): Longint = @FindFirstWide;
FindNext_ : function (var Rslt: TSearchRec): Longint = @FindNextWide;
FindClose_ : procedure (var F: TSearchrec) = @FindCloseWide;
DeleteFile_ : function (const FileName: String): Boolean = @DeleteFileWide;
RenameFile_ : function (const OldName, NewName: String): Boolean = @RenameFileWide;
GetCurrentDir_ : function : String = @GetCurrentDirWide;
SetCurrentDir_ : function (const NewDir: String): Boolean = @SetCurrentDirWide;
CreateDir_ : function (const NewDir: String): Boolean = @CreateDirWide;
RemoveDir_ : function (const Dir: String): Boolean = @RemoveDirWide;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
begin
Result:=FindFirst_(Path, Attr, Rslt);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Result:=FindNext_(Rslt);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
FindClose_(F);
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result:=DeleteFile_(FileName);
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result:=RenameFile_(OldName, NewName);
end;
function GetCurrentDirUTF8: String;
begin
Result:=GetCurrentDir_();
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result:=SetCurrentDir_(NewDir);
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result:=CreateDir_(NewDir);
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result:=RemoveDir_(Dir);
end;
function ExtractShortPathNameUTF8(const FileName: String): String;
var
lPathSize: DWORD;
@ -536,20 +187,4 @@ begin
{$endif}
end;
procedure InitFileUtils;
begin
{$ifndef WinCE}
if Win32MajorVersion <= 4 then
begin
DeleteFile_:=@DeleteFileAnsi;
RenameFile_:=@RenameFileAnsi;
SetCurrentDir_:=@SetCurrentDirAnsi;
GetCurrentDir_:=@GetCurrentDirAnsi;
CreateDir_:=@CreateDirAnsi;
RemoveDir_:=@RemoveDirAnsi;
FindFirst_:=@FindFirstAnsi;
FindNext_:=@FindNextAnsi;
FindClose_:=@FindCloseAnsi;
end;
{$endif}
end;

View File

@ -7,21 +7,21 @@ var
_FileAgeUtf8 : function (const Filename:string):Longint;
_FileSizeUtf8 : function (const Filename: string): int64;
_FileSetDateUtf8 : function (const FileName: String; Age: Longint): Longint;
//FindFirst_ : function (const Path: string; Attr: Longint;
// out Rslt: TSearchRec): Longint;
//FindNext_ : function (var Rslt: TSearchRec): Longint;
//FindClose_ : procedure (var F: TSearchrec);
_FindFirstUtf8 : function (const Path: string; Attr: Longint;
out Rslt: TSearchRec): Longint;
_FindNextUtf8 : function (var Rslt: TSearchRec): Longint;
_FindCloseUtf8 : procedure (var F: TSearchrec);
_FileGetAttrUtf8 : function (const FileName: String): Longint;
_FileSetAttrUtf8 : function (const Filename: String; Attr: longint): Longint;
//DeleteFile_ : function (const FileName: String): Boolean;
//RenameFile_ : function (const OldName, NewName: String): Boolean;
_DeleteFileUtf8 : function (const FileName: String): Boolean;
_RenameFileUtf8 : function (const OldName, NewName: String): Boolean;
_GetCurrentDirUtf8 : function: String ;
_GetDirUtf8 : procedure(DriveNr: Byte; var Dir: String);
_FileOpenUtf8 : function(Const FileName : string; Mode : Integer) : THandle;
_FileCreateUtf8 : function(Const FileName : String; ShareMode : Integer; Rights: Integer) : THandle;
//SetCurrentDir_ : function (const NewDir: String): Boolean;
//CreateDir_ : function (const NewDir: String): Boolean;
//RemoveDir_ : function (const Dir: String): Boolean ;
_SetCurrentDirUtf8 : function (const NewDir: String): Boolean;
_CreateDirUtf8 : function (const NewDir: String): Boolean;
_RemoveDirUtf8 : function (const Dir: String): Boolean ;
function FilenameIsAbsolute(const TheFilename: string):boolean;
begin
@ -219,6 +219,51 @@ begin
Result := _FileSizeUtf8(FileName);
end;
function CreateDirUTF8(const NewDir: String): Boolean;
begin
Result := _CreateDirUTF8(NewDir);
end;
function RemoveDirUTF8(const Dir: String): Boolean;
begin
Result := _RemoveDirUtf8(Dir);
end;
function DeleteFileUTF8(const FileName: String): Boolean;
begin
Result := _DeleteFileUtf8(Filename);
if Result then
InvalidateFileStateCache;
end;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
begin
Result := _RenameFileUtf8(OldName,NewName);
if Result then
InvalidateFileStateCache;
end;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
begin
Result := _SetCurrentDirUtf8(NewDir);
end;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec
): Longint;
begin
Result := _FindFirstUtf8(Path, Attr, Rslt);
end;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
begin
Result := _FindNextUtf8(Rslt);
end;
procedure FindCloseUTF8(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
{******* ANSI functions *******}
@ -286,6 +331,53 @@ begin
Windows.FindClose(FindHandle);
end;
function CreateDirAnsi(const NewDir: String): Boolean;
begin
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
end;
function RemoveDirAnsi(const Dir: String): Boolean;
begin
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
end;
function DeleteFileAnsi(const FileName: String): Boolean;
begin
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
end;
function RenameFileAnsi(const OldName, NewName: String): Boolean;
begin
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
end;
function SetCurrentDirAnsi(const NewDir: String): Boolean;
begin
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
end;
function FindFirstAnsi(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
begin
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
function FindNextAnsi(var Rslt: TSearchRec): Longint;
begin
Rslt.Name:=UTF8ToSys(Rslt.Name);
Result:=SysUtils.FindNext(Rslt);
Rslt.Name:=SysToUTF8(Rslt.Name);
end;
procedure FindCloseAnsi(var F: TSearchrec);
begin
SysUtils.FindClose(F);
end;
{$endif WinCE}
@ -474,6 +566,139 @@ begin
Windows.FindClose(FindHandle);
end;
function CreateDirWide(const NewDir: String): Boolean;
begin
Result:=Windows.CreateDirectoryW(PWideChar(UTF8Decode(NewDir)), nil);
end;
function RemoveDirWide(const Dir: String): Boolean;
begin
Result:=Windows.RemoveDirectoryW(PWideChar(UTF8Decode(Dir)));
end;
function DeleteFileWide(const FileName: String): Boolean;
begin
Result:=Windows.DeleteFileW(PWideChar(UTF8Decode(FileName)));
end;
function RenameFileWide(const OldName, NewName: String): Boolean;
begin
Result:=MoveFileW(PWideChar(UTF8Decode(OldName)), PWideChar(UTF8Decode(NewName)));
end;
function SetCurrentDirWide(const NewDir: String): Boolean;
begin
{$ifdef WinCE}
raise Exception.Create('[SetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
{$else}
Result:=Windows.SetCurrentDirectoryW(PWidechar(UTF8Decode(NewDir)));
{$endif}
end;
function FindMatch(var f: TSearchRec) : Longint;
begin
{ Find file with correct attribute }
While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
begin
if FindNextUTF8(F)<>0 then
begin
Result:=GetLastError;
exit;
end;
end;
{ Convert some attributes back }
WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
f.size:=F.FindData.NFileSizeLow+(qword(maxdword)+1)*F.FindData.NFileSizeHigh;
f.attr:=F.FindData.dwFileAttributes;
{ The structures are different at this point
in win32 it is the ansi structure with a utf-8 string
in wince it is a wide structure }
{$ifdef WinCE}
f.Name:=UTF8Encode(F.FindData.cFileName);
{$else}
f.Name:=F.FindData.cFileName;
{$endif}
Result:=0;
end;
{ This function does not really convert from wide to ansi, but from wide to
a utf-8 encoded ansi version of the data structures in win32 and does
nothing in wince
See FindMatch also }
procedure FindWideToAnsi(const wide: TWIN32FINDDATAW; var ansi: TWIN32FINDDATA);
var
ws: WideString;
an: AnsiString;
begin
{$ifdef WinCE}
ansi := wide;
{$else}
SetLength(ws, length(wide.cAlternateFileName));
Move(wide.cAlternateFileName[0], ws[1], length(ws)*2);
an := AnsiString(ws); // no need to utf8 for cAlternateFileName (it's always ansi encoded)
Move(an[1], ansi.cAlternateFileName, sizeof(ansi.cAlternateFileName));
ws := PWideChar(@wide.cFileName[0]);
an := UTF8Encode(ws);
ansi.cFileName := an;
if length(an)<length(ansi.cFileName) then ansi.cFileName[ length(an)]:=#0;
with ansi do
begin
dwFileAttributes := wide.dwFileAttributes;
ftCreationTime := wide.ftCreationTime;
ftLastAccessTime := wide.ftLastAccessTime;
ftLastWriteTime := wide.ftLastWriteTime;
nFileSizeHigh := wide.nFileSizeHigh;
nFileSizeLow := wide.nFileSizeLow;
dwReserved0 := wide.dwReserved0;
dwReserved1 := wide.dwReserved1;
end;
{$endif}
end;
function FindFirstWide(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
var
find : TWIN32FINDDATAW;
begin
Rslt.Name:=Path;
Rslt.Attr:=attr;
Rslt.ExcludeAttr:=(not Attr) and ($1e);
{ $1e = faHidden or faSysFile or faVolumeID or faDirectory }
{ FindFirstFile is a Win32 Call }
Rslt.FindHandle:=Windows.FindFirstFileW( PWideChar(UTF8Decode(Path)),find);
If Rslt.FindHandle=Invalid_Handle_value then
begin
Result:=GetLastError;
Exit;
end;
{ Find file with correct attribute }
FindWideToAnsi(find, Rslt.FindData);
Result:=FindMatch(Rslt);
end;
function FindNextWide(var Rslt: TSearchRec): Longint;
var
wide : TWIN32FINDDATAW;
begin
if FindNextFileW(Rslt.FindHandle, wide) then
begin
FindWideToAnsi(wide, Rslt.FindData);
Result := FindMatch(Rslt);
end
else
Result := Integer(GetLastError);
end;
procedure FindCloseWide(var F: TSearchrec);
begin
Windows.FindClose(f.FindHandle);
end;
@ -487,18 +712,18 @@ begin
_FileSetDateUtf8 := @FileSetDateAnsi;
_FileGetAttrUtf8 := @FileGetAttrAnsi;
_FileSetAttrUtf8 := @FileSetAttrAnsi;
//DeleteFile_ := @DeleteFileAnsi;
//RenameFile_ := @RenameFileAnsi;
//SetCurrentDir_ := @SetCurrentDirAnsi;
_DeleteFileUtf8 := @DeleteFileAnsi;
_RenameFileUtf8 := @RenameFileAnsi;
_SetCurrentDirUtf8 := @SetCurrentDirAnsi;
_GetCurrentDirUtf8 := @GetCurrentDirAnsi;
_GetDirUtf8 := @GetDirAnsi;
_FileOpenUtf8 := @FileOpenAnsi;
_FileCreateUtf8 := @FileCreateAnsi;
//CreateDir_ := @CreateDirAnsi;
//RemoveDir_ := @RemoveDirAnsi;
//FindFirst_ := @FindFirstAnsi;
//FindNext_ := @FindNextAnsi;
//FindClose_ := @FindCloseAnsi;
_CreateDirUtf8 := @CreateDirAnsi;
_RemoveDirUtf8 := @RemoveDirAnsi;
_FindFirstUtf8 := @FindFirstAnsi;
_FindNextUtf8 := @FindNextAnsi;
_FindCloseUtf8 := @FindCloseAnsi;
end
else
{$endif}
@ -508,17 +733,17 @@ begin
_FileSetDateUtf8 := @FileSetDateWide;
_FileGetAttrUtf8 := @FileGetAttrWide;
_FileSetAttrUtf8 := @FileSetAttrWide;
//DeleteFile_ := @DeleteFileWide;
//RenameFile_ := @RenameFileWide;
//SetCurrentDir_ := @SetCurrentDirWide;
_DeleteFileUtf8 := @DeleteFileWide;
_RenameFileUtf8 := @RenameFileWide;
_SetCurrentDirUtf8 := @SetCurrentDirWide;
_GetCurrentDirUtf8 :=@ GetCurrentDirWide;
_GetDirUtf8 := @GetDirWide;
_FileOpenUtf8 := @FileOpenWide;
_FileCreateUtf8 := @FileCreateWide;
//CreateDir_ := @CreateDirWide;
//RemoveDir_ := @RemoveDirWide;
//FindFirst_ := @FindFirstWide;
//FindNext_ := @FindNextWide;
//FindClose_ := @FindCloseWide;
_CreateDirUtf8 := @CreateDirWide;
_RemoveDirUtf8 := @RemoveDirWide;
_FindFirstUtf8 := @FindFirstWide;
_FindNextUtf8 := @FindNextWide;
_FindCloseUtf8 := @FindCloseWide;
end;
end;