![]() Home |
SmallUtils.pas Version 2 Utility function Unit |
![]() Home |
|
SmallUtils.pas is a subsitute for Delphi SysUtils, it Does Not have all of the functions and procedures in SysUtils, but does have many of the functions used in these examples. You can use this unit if a small file size for your Application is important to you, since it does not add the 20 Kb that SysUtils does when it initializes.
If you need more functions then you can just use SysUtils or copy the functions from SysUtils into this. If you need the string "Format" functions you may as well use SysUtils. The 20 Kb that SysUtils adds is NOT wasted Kb, adding error messages and string Format and many other good things. Download version 2 as a zipped file smallUtils.zip |
unit SmallUtils;
{version 2}
interface
uses Windows;
type
TdriveSize = record
FreeS:Int64;
TotalS:Int64;
end;
TWinVerRec = Record
WinPlatform: Integer;
WinMajorVersion: Integer;
WinMinorVersion: Integer;
WinBuildNumber: Integer;
WinCSDVersion: String;
end;
function AllocPadedMem(Size: Cardinal): Pointer;
procedure FreePadedMem(var P: Pointer); overload;
procedure FreePadedMem(var P: PChar); overload;
function CheckPadedMem(P: Pointer): Byte;
function GetPadMemSize(P: Pointer): Cardinal;
{padded memory functions}
function AllocMem(Size: Cardinal): Pointer;
function StrLen(const Str: PChar): Cardinal;
function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
function StrECopy(Dest:PChar; const Source: PChar): PChar;
function StrCopy(Dest: PChar; const Source: PChar): PChar;
function StrEnd(const Str: PChar): PChar; assembler;
function StrScan(const Str: PChar; Chr: Char): PChar;
function StrMove(Dest: PChar; const Source: PChar; Count: Cardinal): PChar; assembler;
function PCharLength(const Str: PChar): Cardinal;
function PCharUpper(Str: PChar): PChar; assembler;
function PCharLower(Str: PChar): PChar; assembler;
function StrCat(Dest: PChar; const Source: PChar): PChar;
{the functions above are like the SysUtils functions}
function LastDelimiter(const Delimiters, S: String): Integer;
function CopyTail(const S : String; Len : Integer) : String;
function Int2Thos(I : Int64) : String;
{puts commas into a string for thousands}
function UpperCase(const S: String): String;
function LowerCase(const S: string): String;
function CompareText(const S1, S2: string): Integer;
function SameText(const S1, S2: string): Boolean;
{4 functions above are like the SysUtils}
{Int2Str is like the IntToStr}
function Int2Str(Value : Int64) : String;
function Str2Int(const Value : String) : Int64;
function Str2IntDef(const S: string; Default: Int64): Int64;
// str2IntDef will return a default value if the string is not an integer
function GetFileExt(const FileName: String): String;
function GetFilePath(const FileName: String): String;
function GetFileName(const FileName: String): String;
{3 functions above are like the ExtractFileExt, ExtractFileName, etc.}
function ChangeExt(const FileName, Extension: String): String;
function AdjustLineBreaks(const S: string): string;
function GetWindowStr(WinHandle: HWND): String;
{function above return the text in the window Handle of WinHandle
as a String}
function DiskSpace(Drive: String): TdriveSize;
{DiskSpace is like the DiskFree and DiskSize in one function}
function FileExists(FileName : String) : Boolean;
function FileSize(FileName:String):Int64;
function DirectoryExists(const Name: string): Boolean;
function SysErrorMessage(ErrorCode: Integer): string;
{for API you get Error codes from GetLastError, this will convert
it to an Error string}
function ShortPathName(const LongName: string): string;
function GetWindowVer: TWinVerRec;
{you can use GetWindowVer to get Version Info
Win32Platform = VER_PLATFORM_WIN32_NT for NT and Win2000
Win32Platform = VER_PLATFORM_WIN32_WINDOWS for Win 95/98/Me}
var
GetDiskFreeSpaceEx: function (Directory: PChar; var FreeAvailable,
TotalSpace: Int64; TotalFree: PLargeInteger): Boolean stdcall = nil;
{FreePadedMem: procedure(var P: Pointer) = FreePadedMem1; overload;
FreePadedMem: procedure(var P: PChar) = FreePadedMem1; overload;}
implementation
uses
Messages;
function AllocMem(Size: Cardinal): Pointer;
begin
GetMem(Result, Size);
FillChar(Result^, Size, 0);
end;
function AllocPadedMem(Size: Cardinal): Pointer;
begin
if Size = 0 then
begin
Result := nil;
MessageBox(0,'Can not Create a 0 length memory block, Size must be One or more',
'Size must be larger than Zero',MB_OK);
Exit;
end;
Inc(Size,12);
GetMem(Result, Size);
Cardinal(Result^) := Size;
Cardinal(Pointer(Cardinal(Result)+4)^):= $FFFFFFFE;
Cardinal(pointer(Cardinal(Result)+Size-4)^) := $FFFFFFFD;
Result := Pointer(Cardinal(Result)+8);
FillChar(Result^, Size-12, 0);
end;
function CheckPadedMem(P: Pointer): Byte;
var
Size: Cardinal;
begin
if P = nil then
begin
Result := 1;
Exit;
end;
if Cardinal(pointer(Cardinal(P)-4)^) <> $FFFFFFFE then
begin
Result := 2;
Exit;
end;
Size := Cardinal(pointer(Cardinal(P)-8)^);
if Cardinal(pointer(Cardinal(P)+Size-12)^) <> $FFFFFFFD then
begin
Result := 3;
Exit;
end;
Result := 0;
end;
procedure FreePadedMem(var P: Pointer);
begin
if P = nil then Exit;
P := Pointer(Cardinal(P)-8);
ReallocMem(P,0);
end;
procedure FreePadedMem(var P: PChar);
begin
if P = nil then Exit;
P := Pointer(Cardinal(P)-8);
ReallocMem(P,0);
end;
function GetPadMemSize(P: Pointer): Cardinal;
begin
if CheckPadedMem(P) > 0 then
begin
Result := 0;
Exit;
end;
Result := Cardinal(pointer(Cardinal(P)-8)^);
if Result < 13 then
begin
Result := 0;
Exit;
end;
Result := Result -12;
end;
function StrLen(const Str: PChar): Cardinal; assembler;
asm
MOV EDX,EDI
MOV EDI,EAX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
MOV EAX,0FFFFFFFEH
SUB EAX,ECX
MOV EDI,EDX
end;
function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
MOV EBX,ECX
XOR AL,AL
TEST ECX,ECX
JZ @@1
REPNE SCASB
JNE @@1
INC ECX
@@1: SUB EBX,ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,EDI
MOV ECX,EBX
SHR ECX,2
REP MOVSD
MOV ECX,EBX
AND ECX,3
REP MOVSB
STOSB
MOV EAX,EDX
POP EBX
POP ESI
POP EDI
end;
function StrCopy(Dest: PChar; const Source: PChar): PChar; assembler;
asm
PUSH EDI
PUSH ESI
MOV ESI,EAX
MOV EDI,EDX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,ECX
MOV EAX,EDI
SHR ECX,2
REP MOVSD
MOV ECX,EDX
AND ECX,3
REP MOVSB
POP ESI
POP EDI
end;
function StrECopy(Dest: PChar; const Source: PChar): PChar; assembler;
asm
PUSH EDI
PUSH ESI
MOV ESI,EAX
MOV EDI,EDX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,ECX
SHR ECX,2
REP MOVSD
MOV ECX,EDX
AND ECX,3
REP MOVSB
LEA EAX,[EDI-1]
POP ESI
POP EDI
end;
function StrEnd(const Str: PChar): PChar; assembler;
asm
MOV EDX,EDI
MOV EDI,EAX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
LEA EAX,[EDI-1]
MOV EDI,EDX
end;
function StrScan(const Str: PChar; Chr: Char): PChar; assembler;
asm
PUSH EDI
PUSH EAX
MOV EDI,Str
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
POP EDI
MOV AL,Chr
REPNE SCASB
MOV EAX,0
JNE @@1
MOV EAX,EDI
DEC EAX
@@1: POP EDI
end;
function StrMove(Dest: PChar; const Source: PChar; Count: Cardinal): PChar; assembler;
asm
PUSH ESI
PUSH EDI
MOV ESI,EDX
MOV EDI,EAX
MOV EDX,ECX
CMP EDI,ESI
JA @@1
JE @@2
SHR ECX,2
REP MOVSD
MOV ECX,EDX
AND ECX,3
REP MOVSB
JMP @@2
@@1: LEA ESI,[ESI+ECX-1]
LEA EDI,[EDI+ECX-1]
AND ECX,3
STD
REP MOVSB
SUB ESI,3
SUB EDI,3
MOV ECX,EDX
SHR ECX,2
REP MOVSD
CLD
@@2: POP EDI
POP ESI
end;
function PCharLength(const Str: PChar): Cardinal; assembler;
asm
MOV EDX,EDI
MOV EDI,EAX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
MOV EAX,0FFFFFFFEH
SUB EAX,ECX
MOV EDI,EDX
end;
function PCharUpper(Str: PChar): PChar; assembler;
asm
PUSH ESI
MOV ESI,Str
MOV EDX,Str
@@1: LODSB
OR AL,AL
JE @@2
CMP AL,'a'
JB @@1
CMP AL,'z'
JA @@1
SUB AL,20H
MOV [ESI-1],AL
JMP @@1
@@2: XCHG EAX,EDX
POP ESI
end;
function PCharLower(Str: PChar): PChar; assembler;
asm
PUSH ESI
MOV ESI,Str
MOV EDX,Str
@@1: LODSB
OR AL,AL
JE @@2
CMP AL,'A'
JB @@1
CMP AL,'Z'
JA @@1
ADD AL,20H
MOV [ESI-1],AL
JMP @@1
@@2: XCHG EAX,EDX
POP ESI
end;
function StrCat(Dest: PChar; const Source: PChar): PChar;
begin
StrCopy(StrEnd(Dest), Source);
Result := Dest;
end;
function LastDelimiter(const Delimiters, S: string): Integer;
var
P: PChar;
begin
Result := Length(S);
P := PChar(Delimiters);
while Result > 0 do
begin
if (S[Result] <> #0) and (StrScan(P, S[Result]) <> nil) then
{if (ByteType(S, Result) = mbTrailByte) then
Dec(Result)
else}
Exit;
Dec(Result);
end;
end;
function CopyTail(const S : String; Len : Integer): String;
var L : Integer;
begin
L := Length( S );
if L < Len then
Len := L;
Result := '';
if Len = 0 then Exit;
Result := Copy( S, L - Len + 1, Len );
end;
function CompareText(const S1, S2: string): Integer; assembler;
asm
PUSH ESI
PUSH EDI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
OR EAX,EAX
JE @@0
MOV EAX,[EAX-4]
@@0: OR EDX,EDX
JE @@1
MOV EDX,[EDX-4]
@@1: MOV ECX,EAX
CMP ECX,EDX
JBE @@2
MOV ECX,EDX
@@2: CMP ECX,ECX
@@3: REPE CMPSB
JE @@6
MOV BL,BYTE PTR [ESI-1]
CMP BL,'a'
JB @@4
CMP BL,'z'
JA @@4
SUB BL,20H
@@4: MOV BH,BYTE PTR [EDI-1]
CMP BH,'a'
JB @@5
CMP BH,'z'
JA @@5
SUB BH,20H
@@5: CMP BL,BH
JE @@3
MOVZX EAX,BL
MOVZX EDX,BH
@@6: SUB EAX,EDX
POP EBX
POP EDI
POP ESI
end;
function SameText(const S1, S2: string): Boolean; assembler;
asm
CMP EAX,EDX
JZ @1
OR EAX,EAX
JZ @2
OR EDX,EDX
JZ @3
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JNE @3
CALL CompareText
TEST EAX,EAX
JNZ @3
@1: MOV AL,1
@2: RET
@3: XOR EAX,EAX
end;
function Int2Thos(I : Int64): String;
var S : String;
begin
S := Int2Str( I );
Result := '';
while S <> '' do
begin
if Result <> '' then
Result := ',' + Result;
Result := CopyTail( S, 3 ) + Result;
S := Copy( S, 1, Length( S ) - 3 );
end;
end;
function GetFileExt(const FileName: string): string;
var
I: Integer;
begin
I := LastDelimiter('.\:', FileName);
if (I > 0) and (FileName[I] = '.') then
Result := Copy(FileName, I, MaxInt) else
Result := '';
end;
function GetFilePath(const FileName: string): string;
var
I: Integer;
begin
I := LastDelimiter('\:', FileName);
Result := Copy(FileName, 1, I);
end;
function GetFileName(const FileName: string): string;
var
I: Integer;
begin
I := LastDelimiter('\:', FileName);
Result := Copy(FileName, I + 1, MaxInt);
end;
function ChangeExt(const FileName, Extension: string): string;
// Extention needs a period like '.exe'
var
I: Integer;
begin
I := LastDelimiter('.\:',Filename);
if (I = 0) or (FileName[I] <> '.') then I := MaxInt;
Result := Copy(FileName, 1, I - 1) + Extension;
end;
function UpperCase(const S: string): string;
var I : Integer;
begin
Result := S;
for I := 1 to Length( S ) do
if Result[ I ] in [ 'a'..'z' ] then
Dec( Result[ I ], 32 );
end;
function LowerCase(const S: string): string;
var
Ch: Char;
L: Integer;
Source, Dest: PChar;
begin
L := Length(S);
SetLength(Result, L);
Source := Pointer(S);
Dest := Pointer(Result);
while L <> 0 do
begin
Ch := Source^;
if (Ch >= 'A') and (Ch <= 'Z') then Inc(Ch, 32);
Dest^ := Ch;
Inc(Source);
Inc(Dest);
Dec(L);
end;
end;
function AdjustLineBreaks(const S: string): string;
var
Source, SourceEnd, Dest: PChar;
Extra: Integer;
begin
Source := Pointer(S);
SourceEnd := Source + Length(S);
Extra := 0;
while Source < SourceEnd do
begin
case Source^ of
#10:
Inc(Extra);
#13:
if Source[1] = #10 then Inc(Source) else Inc(Extra);
end;
Inc(Source);
end;
if Extra = 0 then Result := S else
begin
Source := Pointer(S);
SetString(Result, nil, SourceEnd - Source + Extra);
Dest := Pointer(Result);
while Source < SourceEnd do
case Source^ of
#10:
begin
Dest^ := #13;
Inc(Dest);
Dest^ := #10;
Inc(Dest);
Inc(Source);
end;
#13:
begin
Dest^ := #13;
Inc(Dest);
Dest^ := #10;
Inc(Dest);
Inc(Source);
if Source^ = #10 then Inc(Source);
end;
else
Dest^ := Source^;
Inc(Dest);
Inc(Source);
end;
end;
end;
function GetWindowStr(WinHandle: HWND): String;
var
ResultStr: String;
begin
SetLength(ResultStr, GetWindowTextLength(WinHandle));
GetWindowText(WinHandle,@ResultStr[1],Length(ResultStr)+1);
Result := ResultStr;
//UniqueString(Result);
ResultStr := '';
end;
function Int2Str( Value : Int64 ) : String;
var Minus : Boolean;
begin
Result := '';
if Value = 0 then
Result := '0';
Minus := Value < 0;
if Minus then
Value := -Value;
while Value > 0 do
begin
Result := Char( (Value mod 10) + Integer( '0' ) ) + Result;
Value := Value div 10;
end;
if Minus then
Result := '-' + Result;
end;
function Str2Int(const Value : String) : Int64;
var M, I : Integer;
begin
Result := 0;
if Value = '' then Exit;
M := 1;
I := 1;
if Value[ 1 ] = '-' then
begin
M := -1;
Inc( I );
end;
for I := I to Length( Value ) do
begin
if (Value[ I ] < '0') or (Value[ I ] > '9') then
break;
Result := Result * 10 + Integer( Value[ I ] ) - Integer( '0' );
end;
if M < 0 then
Result := -Result;
end;
function Str2IntDef(const S: string; Default: Int64): Int64;
var
E: Integer;
begin
Val(S, Result, E);
if E <> 0 then Result := Default;
end;
function BackfillGetDiskFreeSpaceEx(Directory: PChar; var FreeAvailable,
TotalSpace: Int64; TotalFree: PLargeInteger): Boolean; stdcall;
var
SectorsPerCluster, BytesPerSector, FreeClusters, TotalClusters: LongWord;
Temp: Int64;
Dir: PChar;
begin
if Directory <> nil then
Dir := Directory
else
Dir := nil;
Result := GetDiskFreeSpaceA(Dir, SectorsPerCluster, BytesPerSector,
FreeClusters, TotalClusters);
Temp := SectorsPerCluster * BytesPerSector;
FreeAvailable := Temp * FreeClusters;
TotalSpace := Temp * TotalClusters;
end;
procedure InitDriveSpacePtr;
var
Kernel: HWND;
begin
Kernel := GetModuleHandle(Windows.Kernel32);
if Kernel <> 0 then
@GetDiskFreeSpaceEx := GetProcAddress(Kernel, 'GetDiskFreeSpaceExA');
if not Assigned(GetDiskFreeSpaceEx) then
GetDiskFreeSpaceEx := @BackfillGetDiskFreeSpaceEx;
end;
function DiskSpace(Drive: String): TdriveSize;
var
TSpace,TotalS: Int64;
Sizes:TdriveSize;
ErrorMode: Word;
begin
Delete(Drive, 4, 600);
ErrorMode := SetErrorMode(SEM_FailCriticalErrors);
if GetDiskFreeSpaceEx(@Drive[1], TSpace, TotalS, nil) then
begin
Sizes.FreeS := TSpace;
Sizes.TotalS := TotalS;
Result := Sizes;
end else
begin
Sizes.FreeS := -1;
Sizes.TotalS := -1;
Result := Sizes;
end;
SetErrorMode(ErrorMode);
end;
function FileExists( FileName : String ) : Boolean;
var
FndData: TWin32FindData;
fndHandle: Integer;
ErrorMode: Word;
begin
Result := False;
ErrorMode := SetErrorMode(SEM_FailCriticalErrors);
fndHandle := FindFirstFile(PChar(FileName), FndData);
SetErrorMode(ErrorMode);
if fndHandle <> Integer( INVALID_HANDLE_VALUE ) then
begin
Windows.FindClose(fndHandle);
if (FndData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
Result := True;
end;
end;
function DirectoryExists(const Name: string): Boolean;
var
Code: Integer;
begin
Code := GetFileAttributes(PChar(Name));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;
function FileSize(FileName:String):Int64;
var
FindHandle:HWND;
FindData: TWin32FindData;
ErrorMode: Word;
begin
ErrorMode := SetErrorMode(SEM_FailCriticalErrors);
FindHandle := FindFirstFile(PChar(FileName), FindData);
SetErrorMode(ErrorMode);
if FindHandle <> INVALID_HANDLE_VALUE then
begin
Result := (FindData.nFileSizeHigh * MAXDWORD) + FindData.nFileSizeLow;
Windows.FindClose(findHandle);
end else Result := -1;
end;
function SysErrorMessage(ErrorCode: Integer): string;
var
Len: Integer;
Buffer: array[0..255] of Char;
begin
Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer,
SizeOf(Buffer), nil);
while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
SetString(Result, Buffer, Len);
end;
function ShortPathName(const LongName: string): string;
var
Buffer: array[0..MAX_PATH - 1] of Char;
begin
SetString(Result, Buffer,
GetShortPathName(PChar(LongName), Buffer, SizeOf(Buffer)));
end;
function GetWindowVer: TWinVerRec;
var
OSVersionInfo: TOSVersionInfo;
begin
with Result do
begin
WinPlatform := 0;
WinMajorVersion := 0;
WinMinorVersion := 0;
WinBuildNumber := 0;
WinCSDVersion := '';
end;
OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
if GetVersionEx(OSVersionInfo) then
with OSVersionInfo do
begin
with Result do
begin
WinPlatform := dwPlatformId;
WinMajorVersion := dwMajorVersion;
WinMinorVersion := dwMinorVersion;
WinBuildNumber := dwBuildNumber;
WinCSDVersion := szCSDVersion;
end;
end;
end;
initialization
InitDriveSpacePtr;
end.
|
H O M E 