| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 | {**************************************************************************************************}{                                                                                                  }{ 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}interfaceuses  {$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}// Versionconst  JclVersionMajor   = 2;    // 0=pre-release|beta/1, 2, ...=final  JclVersionMinor   = 7;    // Fifth minor release since JCL 1.90  JclVersionRelease = 0;    // 0: pre-release|beta/ 1: release  JclVersionBuild   = 5676; // build number, days since march 1, 2000  JclVersion = (JclVersionMajor shl 24) or (JclVersionMinor shl 16) or    (JclVersionRelease shl 15) or (JclVersionBuild shl 0);// EJclErrortype  EJclError = class(Exception);// EJclInternalErrortype  EJclInternalError = class(EJclError);// Typestype  {$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 = ^JclBase.PWideChar;  PPAnsiChar = ^PAnsiChar;  PInt64 = type System.PInt64;  {$ENDIF ~FPC}  PPInt64 = ^PInt64;  PPPAnsiChar = ^PPAnsiChar;// Int64 supportprocedure 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}// 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.pastype  {$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;// Dynamic Array supporttype  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 Compatibilityconst  // 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 typestype  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-1function 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-BEGINtype  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 GetMemprocedure 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}implementationuses  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.Stringend;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 supportprocedure 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 GetMemprocedure 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.
 |