123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- {**************************************************************************************************}
- { }
- { Project JEDI Code Library (JCL) }
- { }
- { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
- { you may not use this file except in compliance with the License. You may obtain a copy of the }
- { License at http://www.mozilla.org/MPL/ }
- { }
- { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
- { ANY KIND, either express or implied. See the License for the specific language governing rights }
- { and limitations under the License. }
- { }
- { The Original Code is JclBase.pas. }
- { }
- { The Initial Developer of the Original Code is Marcel van Brakel. }
- { Portions created by Marcel van Brakel are Copyright Marcel van Brakel. All rights reserved. }
- { }
- { Contributors: }
- { Marcel van Brakel, }
- { Peter Friese, }
- { Robert Marquardt (marquardt) }
- { Robert Rossmair (rrossmair) }
- { Petr Vones (pvones) }
- { Florent Ouchet (outchy) }
- { }
- {**************************************************************************************************}
- { }
- { This unit contains generic JCL base classes and routines to support earlier }
- { versions of Delphi as well as FPC. }
- { }
- {**************************************************************************************************}
- { }
- { Last modified: $Date:: $ }
- { Revision: $Rev:: $ }
- { Author: $Author:: $ }
- { }
- {**************************************************************************************************}
- unit JclBase;
- {$I jcl.inc}
- interface
- uses
- {$IFDEF UNITVERSIONING}
- JclUnitVersioning,
- {$ENDIF UNITVERSIONING}
- {$IFDEF HAS_UNITSCOPE}
- {$IFDEF MSWINDOWS}
- Winapi.Windows,
- {$ENDIF MSWINDOWS}
- System.SysUtils;
- {$ELSE ~HAS_UNITSCOPE}
- {$IFDEF MSWINDOWS}
- Windows,
- {$ENDIF MSWINDOWS}
- SysUtils;
- {$ENDIF ~HAS_UNITSCOPE}
- // Version
- const
- JclVersionMajor = 2; // 0=pre-release|beta/1, 2, ...=final
- JclVersionMinor = 8; // Fifth minor release since JCL 1.90
- JclVersionRelease = 1; // 0: pre-release|beta/ 1: release
- JclVersionBuild = 9330; // build number, days since march 1, 2000
- JclCommit = '6380ce72';
- JclVersion = (JclVersionMajor shl 24) or (JclVersionMinor shl 16) or
- (JclVersionRelease shl 15) or (JclVersionBuild shl 0);
- // EJclError
- type
- EJclError = class(Exception);
- // EJclInternalError
- type
- EJclInternalError = class(EJclError);
- // Types
- type
- {$IFDEF MATH_EXTENDED_PRECISION}
- Float = Extended;
- {$ENDIF MATH_EXTENDED_PRECISION}
- {$IFDEF MATH_DOUBLE_PRECISION}
- Float = Double;
- {$ENDIF MATH_DOUBLE_PRECISION}
- {$IFDEF MATH_SINGLE_PRECISION}
- Float = Single;
- {$ENDIF MATH_SINGLE_PRECISION}
- PFloat = ^Float;
- type
- {$IFDEF FPC}
- Largeint = Int64;
- {$ELSE ~FPC}
- {$IFDEF CPU32}
- SizeInt = Integer;
- {$ENDIF CPU32}
- {$IFDEF CPU64}
- SizeInt = NativeInt;
- {$ENDIF CPU64}
- PSizeInt = ^SizeInt;
- PPointer = ^Pointer;
- PByte = System.PByte;
- Int8 = ShortInt;
- Int16 = Smallint;
- Int32 = Integer;
- UInt8 = Byte;
- UInt16 = Word;
- UInt32 = LongWord;
- PCardinal = ^Cardinal;
- {$IFNDEF COMPILER7_UP}
- UInt64 = Int64;
- {$ENDIF ~COMPILER7_UP}
- PWideChar = System.PWideChar;
- PPWideChar = ^PWideChar;
- PPAnsiChar = ^PAnsiChar;
- PInt64 = type System.PInt64;
- {$ENDIF ~FPC}
- PPInt64 = ^PInt64;
- PPPAnsiChar = ^PPAnsiChar;
- // Int64 support
- procedure I64ToCardinals(I: Int64; out LowPart, HighPart: Cardinal);
- procedure CardinalsToI64(out I: Int64; const LowPart, HighPart: Cardinal);
- // Redefinition of TLargeInteger to relieve dependency on Windows.pas
- {$IFNDEF FPC}
- type
- PLargeInteger = ^TLargeInteger;
- TLargeInteger = Int64;
- {$ENDIF ~FPC}
- {$IFNDEF COMPILER11_UP}
- type
- TBytes = array of Byte;
- {$ENDIF ~COMPILER11_UP}
- type
- {$IFDEF RTL360_UP}
- TJclListSize = NativeInt;
- {$ELSE}
- TJclListSize = Integer;
- {$ENDIF ~RTL360_UP}
- // Redefinition of PByteArray to avoid range check exceptions.
- type
- TJclByteArray = array [0..MaxInt div SizeOf(Byte) - 1] of Byte;
- PJclByteArray = ^TJclByteArray;
- TJclBytes = Pointer; // under .NET System.pas: TBytes = array of Byte;
- // Redefinition of ULARGE_INTEGER to relieve dependency on Windows.pas
- type
- {$IFNDEF FPC}
- PULARGE_INTEGER = ^ULARGE_INTEGER;
- {$EXTERNALSYM PULARGE_INTEGER}
- ULARGE_INTEGER = record
- case Integer of
- 0:
- (LowPart: LongWord;
- HighPart: LongWord);
- 1:
- (QuadPart: Int64);
- end;
- {$EXTERNALSYM ULARGE_INTEGER}
- {$ENDIF ~FPC}
- TJclULargeInteger = ULARGE_INTEGER;
- PJclULargeInteger = PULARGE_INTEGER;
- {$IFNDEF COMPILER16_UP}
- LONG = Longint;
- {$EXTERNALSYM LONG}
- {$ENDIF ~COMPILER16_UP}
- // Dynamic Array support
- type
- TDynByteArray = array of Byte;
- TDynShortIntArray = array of Shortint;
- TDynWordArray = array of Word;
- TDynSmallIntArray = array of Smallint;
- TDynLongIntArray = array of Longint;
- TDynInt64Array = array of Int64;
- TDynCardinalArray = array of Cardinal;
- TDynIntegerArray = array of Integer;
- TDynSizeIntArray = array of SizeInt;
- TDynExtendedArray = array of Extended;
- TDynDoubleArray = array of Double;
- TDynSingleArray = array of Single;
- TDynFloatArray = array of Float;
- TDynPointerArray = array of Pointer;
- TDynStringArray = array of string;
- TDynAnsiStringArray = array of AnsiString;
- TDynWideStringArray = array of WideString;
- {$IFDEF SUPPORTS_UNICODE_STRING}
- TDynUnicodeStringArray = array of UnicodeString;
- {$ENDIF SUPPORTS_UNICODE_STRING}
- TDynIInterfaceArray = array of IInterface;
- TDynObjectArray = array of TObject;
- TDynCharArray = array of Char;
- TDynAnsiCharArray = array of AnsiChar;
- TDynWideCharArray = array of WideChar;
- // Cross-Platform Compatibility
- const
- // line delimiters for a version of Delphi/C++Builder
- NativeLineFeed = Char(#10);
- NativeCarriageReturn = Char(#13);
- NativeCrLf = string(#13#10);
- // default line break for a version of Delphi on a platform
- {$IFDEF MSWINDOWS}
- NativeLineBreak = NativeCrLf;
- {$ENDIF MSWINDOWS}
- {$IFDEF UNIX}
- NativeLineBreak = NativeLineFeed;
- {$ENDIF UNIX}
- HexPrefixPascal = string('$');
- HexPrefixC = string('0x');
- HexDigitFmt32 = string('%.8x');
- HexDigitFmt64 = string('%.16x');
- {$IFDEF BCB}
- HexPrefix = HexPrefixC;
- {$ELSE ~BCB}
- HexPrefix = HexPrefixPascal;
- {$ENDIF ~BCB}
- {$IFDEF CPU32}
- HexDigitFmt = HexDigitFmt32;
- {$ENDIF CPU32}
- {$IFDEF CPU64}
- HexDigitFmt = HexDigitFmt64;
- {$ENDIF CPU64}
- HexFmt = HexPrefix + HexDigitFmt;
- const
- BOM_UTF16_LSB: array [0..1] of Byte = ($FF,$FE);
- BOM_UTF16_MSB: array [0..1] of Byte = ($FE,$FF);
- BOM_UTF8: array [0..2] of Byte = ($EF,$BB,$BF);
- BOM_UTF32_LSB: array [0..3] of Byte = ($FF,$FE,$00,$00);
- BOM_UTF32_MSB: array [0..3] of Byte = ($00,$00,$FE,$FF);
- // BOM_UTF7_1: array [0..3] of Byte = ($2B,$2F,$76,$38);
- // BOM_UTF7_2: array [0..3] of Byte = ($2B,$2F,$76,$39);
- // BOM_UTF7_3: array [0..3] of Byte = ($2B,$2F,$76,$2B);
- // BOM_UTF7_4: array [0..3] of Byte = ($2B,$2F,$76,$2F);
- // BOM_UTF7_5: array [0..3] of Byte = ($2B,$2F,$76,$38,$2D);
- type
- // Unicode transformation formats (UTF) data types
- PUTF7 = ^UTF7;
- UTF7 = AnsiChar;
- PUTF8 = ^UTF8;
- UTF8 = AnsiChar;
- PUTF16 = ^UTF16;
- UTF16 = WideChar;
- PUTF32 = ^UTF32;
- UTF32 = Cardinal;
- // UTF conversion schemes (UCS) data types
- PUCS4 = ^UCS4;
- UCS4 = Cardinal;
- PUCS2 = PWideChar;
- UCS2 = WideChar;
- TUCS2Array = array of UCS2;
- TUCS4Array = array of UCS4;
- // string types
- TUTF8String = AnsiString;
- {$IFDEF SUPPORTS_UNICODE_STRING}
- TUTF16String = UnicodeString;
- TUCS2String = UnicodeString;
- {$ELSE}
- TUTF16String = WideString;
- TUCS2String = WideString;
- {$ENDIF SUPPORTS_UNICODE_STRING}
- var
- AnsiReplacementCharacter: AnsiChar;
- const
- UCS4ReplacementCharacter: UCS4 = $0000FFFD;
- MaximumUCS2: UCS4 = $0000FFFF;
- MaximumUTF16: UCS4 = $0010FFFF;
- MaximumUCS4: UCS4 = $7FFFFFFF;
- SurrogateHighStart = UCS4($D800);
- SurrogateHighEnd = UCS4($DBFF);
- SurrogateLowStart = UCS4($DC00);
- SurrogateLowEnd = UCS4($DFFF);
- // basic set types
- type
- TSetOfAnsiChar = set of AnsiChar;
- {$IFNDEF XPLATFORM_RTL}
- procedure RaiseLastOSError;
- {$ENDIF ~XPLATFORM_RTL}
- {$IFNDEF RTL230_UP}
- procedure CheckOSError(ErrorCode: Cardinal);
- {$ENDIF RTL230_UP}
- procedure MoveChar(const Source: string; FromIndex: SizeInt;
- var Dest: string; ToIndex, Count: SizeInt); overload; // Index: 0..n-1
- function AnsiByteArrayStringLen(Data: TBytes): SizeInt;
- function StringToAnsiByteArray(const S: string): TBytes;
- function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string;
- function BytesOf(const Value: AnsiString): TBytes; overload;
- function BytesOf(const Value: WideString): TBytes; overload;
- function BytesOf(const Value: WideChar): TBytes; overload;
- function BytesOf(const Value: AnsiChar): TBytes; overload;
- function StringOf(const Bytes: array of Byte): AnsiString; overload;
- function StringOf(const Bytes: Pointer; Size: Cardinal): AnsiString; overload;
- {$IFNDEF FPC}
- {$IFNDEF COMPILER11_UP}
- type // Definitions for 32 Bit Compilers
- // From BaseTsd.h
- INT_PTR = Integer;
- {$EXTERNALSYM INT_PTR}
- LONG_PTR = Longint;
- {$EXTERNALSYM LONG_PTR}
- UINT_PTR = Cardinal;
- {$EXTERNALSYM UINT_PTR}
- ULONG_PTR = LongWord;
- {$EXTERNALSYM ULONG_PTR}
- DWORD_PTR = ULONG_PTR;
- {$EXTERNALSYM DWORD_PTR}
- {$ENDIF ~COMPILER11_UP}
- type
- PDWORD_PTR = ^DWORD_PTR;
- {$EXTERNALSYM PDWORD_PTR}
- {$ENDIF ~FPC}
- type
- TJclAddr32 = Cardinal;
- {$IFDEF FPC}
- TJclAddr64 = QWord;
- {$IFDEF CPU64}
- TJclAddr = QWord;
- {$ENDIF CPU64}
- {$IFDEF CPU32}
- TJclAddr = Cardinal;
- {$ENDIF CPU32}
- {$ENDIF FPC}
- {$IFDEF BORLAND}
- TJclAddr64 = Int64;
- {$IFDEF CPU64}
- TJclAddr = TJclAddr64;
- {$ENDIF CPU64}
- {$IFDEF CPU32}
- TJclAddr = TJclAddr32;
- {$ENDIF CPU32}
- {$ENDIF BORLAND}
- PJclAddr = ^TJclAddr;
- EJclAddr64Exception = class(EJclError);
- function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32;
- function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64;
- {$IFDEF FPC}
- type
- HWND = type Windows.HWND;
- {$ENDIF FPC}
- {$IFDEF SUPPORTS_GENERICS}
- //DOM-IGNORE-BEGIN
- type
- TCompare<T> = function(const Obj1, Obj2: T): Integer;
- TEqualityCompare<T> = function(const Obj1, Obj2: T): Boolean;
- THashConvert<T> = function(const AItem: T): Integer;
- IEqualityComparer<T> = interface
- function Equals(A, B: T): Boolean;
- function GetHashCode(Obj: T): Integer;
- end;
- TEquatable<T: class> = class(TInterfacedObject, IEquatable<T>, IEqualityComparer<T>)
- public
- { IEquatable<T> }
- function TestEquals(Other: T): Boolean; overload;
- function IEquatable<T>.Equals = TestEquals;
- { IEqualityComparer<T> }
- function TestEquals(A, B: T): Boolean; overload;
- function IEqualityComparer<T>.Equals = TestEquals;
- function GetHashCode2(Obj: T): Integer;
- function IEqualityComparer<T>.GetHashCode = GetHashCode2;
- end;
- //DOM-IGNORE-END
- {$ENDIF SUPPORTS_GENERICS}
- const
- {$IFDEF SUPPORTS_UNICODE}
- AWSuffix = 'W';
- {$ELSE ~SUPPORTS_UNICODE}
- AWSuffix = 'A';
- {$ENDIF ~SUPPORTS_UNICODE}
- {$IFDEF FPC}
- // FPC emits a lot of warning because the first parameter of its internal
- // GetMem is a var parameter, which is not initialized before the call to GetMem
- procedure GetMem(out P; Size: Longint);
- {$ENDIF FPC}
- {$IFDEF UNITVERSIONING}
- const
- UnitVersioning: TUnitVersionInfo = (
- RCSfile: '$URL$';
- Revision: '$Revision$';
- Date: '$Date$';
- LogPath: 'JCL\source\common';
- Extra: '';
- Data: nil
- );
- {$ENDIF UNITVERSIONING}
- implementation
- uses
- JclResources;
- procedure MoveChar(const Source: string; FromIndex: SizeInt;
- var Dest: string; ToIndex, Count: SizeInt);
- begin
- Move(Source[FromIndex + 1], Dest[ToIndex + 1], Count * SizeOf(Char));
- end;
- function AnsiByteArrayStringLen(Data: TBytes): SizeInt;
- var
- I: SizeInt;
- begin
- Result := Length(Data);
- for I := 0 to Result - 1 do
- if Data[I] = 0 then
- begin
- Result := I + 1;
- Break;
- end;
- end;
- function StringToAnsiByteArray(const S: string): TBytes;
- var
- I: SizeInt;
- AnsiS: AnsiString;
- begin
- AnsiS := AnsiString(S); // convert to AnsiString
- SetLength(Result, Length(AnsiS));
- for I := 0 to High(Result) do
- Result[I] := Byte(AnsiS[I + 1]);
- end;
- function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string;
- var
- I: SizeInt;
- AnsiS: AnsiString;
- begin
- if Length(Data) < Count then
- Count := Length(Data);
- SetLength(AnsiS, Count);
- for I := 0 to Length(AnsiS) - 1 do
- AnsiS[I + 1] := AnsiChar(Data[I]);
- Result := string(AnsiS); // convert to System.String
- end;
- function BytesOf(const Value: AnsiString): TBytes;
- begin
- SetLength(Result, Length(Value));
- if Value <> '' then
- Move(Pointer(Value)^, Result[0], Length(Value));
- end;
- function BytesOf(const Value: WideString): TBytes;
- begin
- if Value <> '' then
- Result := JclBase.BytesOf(AnsiString(Value))
- else
- SetLength(Result, 0);
- end;
- function BytesOf(const Value: WideChar): TBytes;
- begin
- Result := JclBase.BytesOf(WideString(Value));
- end;
- function BytesOf(const Value: AnsiChar): TBytes;
- begin
- SetLength(Result, 1);
- Result[0] := Byte(Value);
- end;
- function StringOf(const Bytes: array of Byte): AnsiString;
- begin
- if Length(Bytes) > 0 then
- begin
- SetLength(Result, Length(Bytes));
- Move(Bytes[0], Pointer(Result)^, Length(Bytes));
- end
- else
- Result := '';
- end;
- function StringOf(const Bytes: Pointer; Size: Cardinal): AnsiString;
- begin
- if (Bytes <> nil) and (Size > 0) then
- begin
- SetLength(Result, Size);
- Move(Bytes^, Pointer(Result)^, Size);
- end
- else
- Result := '';
- end;
- // Int64 support
- procedure I64ToCardinals(I: Int64; out LowPart, HighPart: Cardinal);
- begin
- LowPart := TJclULargeInteger(I).LowPart;
- HighPart := TJclULargeInteger(I).HighPart;
- end;
- procedure CardinalsToI64(out I: Int64; const LowPart, HighPart: Cardinal);
- begin
- TJclULargeInteger(I).LowPart := LowPart;
- TJclULargeInteger(I).HighPart := HighPart;
- end;
- // Cross Platform Compatibility
- {$IFNDEF XPLATFORM_RTL}
- procedure RaiseLastOSError;
- begin
- RaiseLastWin32Error;
- end;
- {$ENDIF ~XPLATFORM_RTL}
- {$IFNDEF RTL230_UP}
- procedure CheckOSError(ErrorCode: Cardinal);
- begin
- if ErrorCode <> ERROR_SUCCESS then
- {$IFDEF RTL170_UP}
- RaiseLastOSError(ErrorCode);
- {$ELSE ~RTL170_UP}
- RaiseLastOSError;
- {$ENDIF ~RTL170_UP}
- end;
- {$ENDIF RTL230_UP}
- {$OVERFLOWCHECKS OFF}
- function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32;
- begin
- if (Value shr 32) = 0 then
- Result := Value
- else
- raise EJclAddr64Exception.CreateResFmt(@RsCantConvertAddr64, [HexPrefix, Value]);
- end;
- function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64;
- begin
- Result := Value;
- end;
- {$IFDEF OVERFLOWCHECKS_ON}
- {$OVERFLOWCHECKS ON}
- {$ENDIF OVERFLOWCHECKS_ON}
- {$IFDEF SUPPORTS_GENERICS}
- //DOM-IGNORE-BEGIN
- //=== { TEquatable<T> } ======================================================
- function TEquatable<T>.TestEquals(Other: T): Boolean;
- begin
- if Other = nil then
- Result := False
- else
- Result := GetHashCode = Other.GetHashCode;
- end;
- function TEquatable<T>.TestEquals(A, B: T): Boolean;
- begin
- if A = nil then
- Result := B = nil
- else
- if B = nil then
- Result := False
- else
- Result := A.GetHashCode = B.GetHashCode;
- end;
- function TEquatable<T>.GetHashCode2(Obj: T): Integer;
- begin
- if Obj = nil then
- Result := 0
- else
- Result := Obj.GetHashCode;
- end;
- //DOM-IGNORE-END
- {$ENDIF SUPPORTS_GENERICS}
- procedure LoadAnsiReplacementCharacter;
- {$IFDEF MSWINDOWS}
- var
- CpInfo: TCpInfo;
- begin
- CpInfo.MaxCharSize := 0;
- if GetCPInfo(CP_ACP, CpInfo) then
- AnsiReplacementCharacter := AnsiChar(Chr(CpInfo.DefaultChar[0]))
- else
- raise EJclInternalError.CreateRes(@RsEReplacementChar);
- end;
- {$ELSE ~MSWINDOWS}
- begin
- AnsiReplacementCharacter := '?';
- end;
- {$ENDIF ~MSWINDOWS}
- {$IFDEF FPC}
- // FPC emits a lot of warning because the first parameter of its internal
- // GetMem is a var parameter, which is not initialized before the call to GetMem
- procedure GetMem(out P; Size: Longint);
- begin
- Pointer(P) := nil;
- GetMem(Pointer(P), Size);
- end;
- {$ENDIF FPC}
- initialization
- LoadAnsiReplacementCharacter;
- {$IFDEF UNITVERSIONING}
- RegisterUnitVersion(HInstance, UnitVersioning);
- {$ENDIF UNITVERSIONING}
- finalization
- {$IFDEF UNITVERSIONING}
- UnregisterUnitVersion(HInstance);
- {$ENDIF UNITVERSIONING}
- end.
|