mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-28 10:02:14 +00:00
267 lines
6.8 KiB
ObjectPascal
267 lines
6.8 KiB
ObjectPascal
{
|
|
Double commander
|
|
-------------------------------------------------------------------------
|
|
This module contains classes with UTF8 file names support.
|
|
|
|
Copyright (C) 2008-2009 Koblov Alexander (Alexx2000@mail.ru)
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
}
|
|
|
|
unit uClassesEx;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils;
|
|
|
|
const
|
|
faInvalidAttributes: Cardinal = Cardinal(-1);
|
|
|
|
type
|
|
{ TFileStreamEx class }
|
|
|
|
TFileStreamEx = class(THandleStream)
|
|
private
|
|
FFileName: UTF8String;
|
|
public
|
|
constructor Create(const AFileName: UTF8String; Mode: Word);
|
|
destructor Destroy; override;
|
|
property FileName : UTF8String read FFileName;
|
|
end;
|
|
|
|
function mbFileCreate(const FileName: UTF8String): THandle;
|
|
function mbFileOpen(const FileName: UTF8String; Mode: Integer): THandle;
|
|
function mbFileExists(const FileName: UTF8String): Boolean;
|
|
function mbDeleteFile(const FileName: UTF8String): Boolean;
|
|
function mbFileGetAttr(const FileName: UTF8String): Cardinal;
|
|
function mbFileSetAttr(const FileName: UTF8String; Attr: Cardinal) : LongInt;
|
|
function mbCreateDir(const NewDir: UTF8String): Boolean;
|
|
function mbFileSize(const FileName: UTF8String): Int64;
|
|
|
|
implementation
|
|
|
|
uses
|
|
RtlConsts
|
|
{$IF DEFINED(MSWINDOWS)}
|
|
, Windows
|
|
{$ELSEIF DEFINED(UNIX)}
|
|
, BaseUnix
|
|
{$ENDIF}
|
|
;
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
const
|
|
AccessMode: array[0..2] of DWORD = (
|
|
GENERIC_READ,
|
|
GENERIC_WRITE,
|
|
GENERIC_READ or GENERIC_WRITE);
|
|
ShareMode: array[0..4] of DWORD = (
|
|
0,
|
|
0,
|
|
FILE_SHARE_READ,
|
|
FILE_SHARE_WRITE,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE);
|
|
{$ENDIF}
|
|
|
|
function mbFileOpen(const FileName: UTF8String; Mode: Integer): THandle;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wFileName: WideString;
|
|
begin
|
|
wFileName:= UTF8Decode(FileName);
|
|
Result:= CreateFileW(PWChar(wFileName), AccessMode[Mode and 3],
|
|
ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL, 0);
|
|
end;
|
|
{$ELSE}
|
|
const
|
|
AccessMode: array[0..2] of LongInt = (
|
|
O_RdOnly,
|
|
O_WrOnly,
|
|
O_RdWr);
|
|
begin
|
|
Result:= fpOpen(FileName, AccessMode[Mode and 3]);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbFileCreate(const FileName: UTF8String): THandle;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wFileName: WideString;
|
|
begin
|
|
wFileName:= UTF8Decode(FileName);
|
|
Result:= CreateFileW(PWChar(wFileName), GENERIC_READ or GENERIC_WRITE,
|
|
FILE_SHARE_READ, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
|
end;
|
|
{$ELSE}
|
|
begin
|
|
Result:= fpOpen(FileName, O_Creat or O_RdWr or O_Trunc);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ TFileStreamEx }
|
|
|
|
constructor TFileStreamEx.Create(const AFileName: UTF8String; Mode: Word);
|
|
var
|
|
H: System.THandle;
|
|
begin
|
|
{$IF (FPC_VERSION > 2) or ((FPC_VERSION=2) and (FPC_RELEASE >= 5))}
|
|
if (Mode and fmCreate) <> 0 then
|
|
{$ELSE}
|
|
if Mode = fmCreate then
|
|
{$ENDIF}
|
|
begin
|
|
H:= mbFileCreate(AFileName);
|
|
if H = feInvalidHandle then
|
|
raise EFCreateError.CreateFmt(SFCreateError, [AFileName])
|
|
else
|
|
inherited Create(H);
|
|
end
|
|
else
|
|
begin
|
|
H:= mbFileOpen(AFileName, Mode);
|
|
if H = feInvalidHandle then
|
|
raise EFOpenError.CreateFmt(SFOpenError, [AFilename])
|
|
else
|
|
inherited Create(H);
|
|
end;
|
|
FFileName:= AFileName;
|
|
end;
|
|
|
|
destructor TFileStreamEx.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
// Close handle after destroying the base object, because it may use Handle in Destroy.
|
|
if Handle >= 0 then
|
|
FileClose(Handle);
|
|
end;
|
|
|
|
function mbFileExists(const FileName: UTF8String) : Boolean;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
Attr: Dword;
|
|
wFileName: WideString;
|
|
begin
|
|
Result:=False;
|
|
wFileName:= UTF8Decode(FileName);
|
|
Attr:= GetFileAttributesW(PWChar(wFileName));
|
|
if Attr <> DWORD(-1) then
|
|
Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0;
|
|
end;
|
|
{$ELSE}
|
|
var
|
|
Info: BaseUnix.Stat;
|
|
begin
|
|
Result:= False;
|
|
// Can use fpStat, because link to an existing filename can be opened as if it were a real file.
|
|
if fpStat(FileName, Info) >= 0 then
|
|
Result:= fpS_ISREG(Info.st_mode);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbDeleteFile(const FileName: UTF8String): Boolean;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wFileName: WideString;
|
|
begin
|
|
wFileName:= UTF8Decode(FileName);
|
|
Result:= Windows.DeleteFileW(PWChar(wFileName));
|
|
end;
|
|
{$ELSE}
|
|
begin
|
|
Result:= fpUnLink(FileName) = 0;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbFileGetAttr(const FileName: UTF8String): Cardinal;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wFileName: WideString;
|
|
begin
|
|
wFileName:= UTF8Decode(FileName);
|
|
Result := GetFileAttributesW(PWChar(wFileName));
|
|
end;
|
|
{$ELSE}
|
|
var
|
|
Info: BaseUnix.Stat;
|
|
begin
|
|
Result:= faInvalidAttributes;
|
|
if fpLStat(FileName, @Info) >= 0 then
|
|
Result:= Info.st_mode;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbCreateDir(const NewDir: UTF8String): Boolean;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wNewDir: WideString;
|
|
begin
|
|
wNewDir:= UTF8Decode(NewDir);
|
|
Result:= CreateDirectoryW(PWChar(wNewDir), nil);
|
|
end;
|
|
{$ELSE}
|
|
begin
|
|
Result:= fpMkDir(PChar(NewDir), $1FF) = 0; // $1FF = &0777
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbFileSetAttr(const FileName: UTF8String; Attr: Cardinal): LongInt;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
wFileName: WideString;
|
|
begin
|
|
Result:= 0;
|
|
wFileName:= UTF8Decode(FileName);
|
|
if not SetFileAttributesW(PWChar(wFileName), Attr) then
|
|
Result:= GetLastError;
|
|
end;
|
|
{$ELSE}
|
|
begin
|
|
Result:= fpchmod(PChar(FileName), Attr);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function mbFileSize(const FileName: UTF8String): Int64;
|
|
{$IFDEF MSWINDOWS}
|
|
var
|
|
Handle: System.THandle;
|
|
FindData: TWin32FindDataW;
|
|
wFileName: WideString;
|
|
begin
|
|
Result:= 0;
|
|
wFileName:= UTF8Decode(FileName);
|
|
Handle := FindFirstFileW(PWChar(wFileName), FindData);
|
|
if Handle <> INVALID_HANDLE_VALUE then
|
|
begin
|
|
Windows.FindClose(Handle);
|
|
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
|
|
Result:= (Int64(FindData.nFileSizeHigh) * MAXDWORD)+FindData.nFileSizeLow;
|
|
end;
|
|
end;
|
|
{$ELSE}
|
|
var
|
|
Info: BaseUnix.Stat;
|
|
begin
|
|
Result:= 0;
|
|
if fpStat(FileName, Info) >= 0 then
|
|
Result:= Info.st_size;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
end.
|