JclBase.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. {**************************************************************************************************}
  2. { }
  3. { Project JEDI Code Library (JCL) }
  4. { }
  5. { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
  6. { you may not use this file except in compliance with the License. You may obtain a copy of the }
  7. { License at http://www.mozilla.org/MPL/ }
  8. { }
  9. { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
  10. { ANY KIND, either express or implied. See the License for the specific language governing rights }
  11. { and limitations under the License. }
  12. { }
  13. { The Original Code is JclBase.pas. }
  14. { }
  15. { The Initial Developer of the Original Code is Marcel van Brakel. }
  16. { Portions created by Marcel van Brakel are Copyright Marcel van Brakel. All rights reserved. }
  17. { }
  18. { Contributors: }
  19. { Marcel van Brakel, }
  20. { Peter Friese, }
  21. { Robert Marquardt (marquardt) }
  22. { Robert Rossmair (rrossmair) }
  23. { Petr Vones (pvones) }
  24. { Florent Ouchet (outchy) }
  25. { }
  26. {**************************************************************************************************}
  27. { }
  28. { This unit contains generic JCL base classes and routines to support earlier }
  29. { versions of Delphi as well as FPC. }
  30. { }
  31. {**************************************************************************************************}
  32. { }
  33. { Last modified: $Date:: $ }
  34. { Revision: $Rev:: $ }
  35. { Author: $Author:: $ }
  36. { }
  37. {**************************************************************************************************}
  38. unit JclBase;
  39. {$I jcl.inc}
  40. interface
  41. uses
  42. {$IFDEF UNITVERSIONING}
  43. JclUnitVersioning,
  44. {$ENDIF UNITVERSIONING}
  45. {$IFDEF HAS_UNITSCOPE}
  46. {$IFDEF MSWINDOWS}
  47. Winapi.Windows,
  48. {$ENDIF MSWINDOWS}
  49. System.SysUtils;
  50. {$ELSE ~HAS_UNITSCOPE}
  51. {$IFDEF MSWINDOWS}
  52. Windows,
  53. {$ENDIF MSWINDOWS}
  54. SysUtils;
  55. {$ENDIF ~HAS_UNITSCOPE}
  56. // Version
  57. const
  58. JclVersionMajor = 2; // 0=pre-release|beta/1, 2, ...=final
  59. JclVersionMinor = 8; // Fifth minor release since JCL 1.90
  60. JclVersionRelease = 0; // 0: pre-release|beta/ 1: release
  61. JclVersionBuild = 5677; // build number, days since march 1, 2000
  62. JclVersion = (JclVersionMajor shl 24) or (JclVersionMinor shl 16) or
  63. (JclVersionRelease shl 15) or (JclVersionBuild shl 0);
  64. // EJclError
  65. type
  66. EJclError = class(Exception);
  67. // EJclInternalError
  68. type
  69. EJclInternalError = class(EJclError);
  70. // Types
  71. type
  72. {$IFDEF MATH_EXTENDED_PRECISION}
  73. Float = Extended;
  74. {$ENDIF MATH_EXTENDED_PRECISION}
  75. {$IFDEF MATH_DOUBLE_PRECISION}
  76. Float = Double;
  77. {$ENDIF MATH_DOUBLE_PRECISION}
  78. {$IFDEF MATH_SINGLE_PRECISION}
  79. Float = Single;
  80. {$ENDIF MATH_SINGLE_PRECISION}
  81. PFloat = ^Float;
  82. type
  83. {$IFDEF FPC}
  84. Largeint = Int64;
  85. {$ELSE ~FPC}
  86. {$IFDEF CPU32}
  87. SizeInt = Integer;
  88. {$ENDIF CPU32}
  89. {$IFDEF CPU64}
  90. SizeInt = NativeInt;
  91. {$ENDIF CPU64}
  92. PSizeInt = ^SizeInt;
  93. PPointer = ^Pointer;
  94. PByte = System.PByte;
  95. Int8 = ShortInt;
  96. Int16 = Smallint;
  97. Int32 = Integer;
  98. UInt8 = Byte;
  99. UInt16 = Word;
  100. UInt32 = LongWord;
  101. PCardinal = ^Cardinal;
  102. {$IFNDEF COMPILER7_UP}
  103. UInt64 = Int64;
  104. {$ENDIF ~COMPILER7_UP}
  105. PWideChar = System.PWideChar;
  106. PPWideChar = ^PWideChar;
  107. PPAnsiChar = ^PAnsiChar;
  108. PInt64 = type System.PInt64;
  109. {$ENDIF ~FPC}
  110. PPInt64 = ^PInt64;
  111. PPPAnsiChar = ^PPAnsiChar;
  112. // Int64 support
  113. procedure I64ToCardinals(I: Int64; out LowPart, HighPart: Cardinal);
  114. procedure CardinalsToI64(out I: Int64; const LowPart, HighPart: Cardinal);
  115. // Redefinition of TLargeInteger to relieve dependency on Windows.pas
  116. {$IFNDEF FPC}
  117. type
  118. PLargeInteger = ^TLargeInteger;
  119. TLargeInteger = Int64;
  120. {$ENDIF ~FPC}
  121. {$IFNDEF COMPILER11_UP}
  122. type
  123. TBytes = array of Byte;
  124. {$ENDIF ~COMPILER11_UP}
  125. type
  126. {$IFDEF RTL360_UP}
  127. TJclListSize = NativeInt;
  128. {$ELSE}
  129. TJclListSize = Integer;
  130. {$ENDIF ~RTL360_UP}
  131. // Redefinition of PByteArray to avoid range check exceptions.
  132. type
  133. TJclByteArray = array [0..MaxInt div SizeOf(Byte) - 1] of Byte;
  134. PJclByteArray = ^TJclByteArray;
  135. TJclBytes = Pointer; // under .NET System.pas: TBytes = array of Byte;
  136. // Redefinition of ULARGE_INTEGER to relieve dependency on Windows.pas
  137. type
  138. {$IFNDEF FPC}
  139. PULARGE_INTEGER = ^ULARGE_INTEGER;
  140. {$EXTERNALSYM PULARGE_INTEGER}
  141. ULARGE_INTEGER = record
  142. case Integer of
  143. 0:
  144. (LowPart: LongWord;
  145. HighPart: LongWord);
  146. 1:
  147. (QuadPart: Int64);
  148. end;
  149. {$EXTERNALSYM ULARGE_INTEGER}
  150. {$ENDIF ~FPC}
  151. TJclULargeInteger = ULARGE_INTEGER;
  152. PJclULargeInteger = PULARGE_INTEGER;
  153. {$IFNDEF COMPILER16_UP}
  154. LONG = Longint;
  155. {$EXTERNALSYM LONG}
  156. {$ENDIF ~COMPILER16_UP}
  157. // Dynamic Array support
  158. type
  159. TDynByteArray = array of Byte;
  160. TDynShortIntArray = array of Shortint;
  161. TDynWordArray = array of Word;
  162. TDynSmallIntArray = array of Smallint;
  163. TDynLongIntArray = array of Longint;
  164. TDynInt64Array = array of Int64;
  165. TDynCardinalArray = array of Cardinal;
  166. TDynIntegerArray = array of Integer;
  167. TDynSizeIntArray = array of SizeInt;
  168. TDynExtendedArray = array of Extended;
  169. TDynDoubleArray = array of Double;
  170. TDynSingleArray = array of Single;
  171. TDynFloatArray = array of Float;
  172. TDynPointerArray = array of Pointer;
  173. TDynStringArray = array of string;
  174. TDynAnsiStringArray = array of AnsiString;
  175. TDynWideStringArray = array of WideString;
  176. {$IFDEF SUPPORTS_UNICODE_STRING}
  177. TDynUnicodeStringArray = array of UnicodeString;
  178. {$ENDIF SUPPORTS_UNICODE_STRING}
  179. TDynIInterfaceArray = array of IInterface;
  180. TDynObjectArray = array of TObject;
  181. TDynCharArray = array of Char;
  182. TDynAnsiCharArray = array of AnsiChar;
  183. TDynWideCharArray = array of WideChar;
  184. // Cross-Platform Compatibility
  185. const
  186. // line delimiters for a version of Delphi/C++Builder
  187. NativeLineFeed = Char(#10);
  188. NativeCarriageReturn = Char(#13);
  189. NativeCrLf = string(#13#10);
  190. // default line break for a version of Delphi on a platform
  191. {$IFDEF MSWINDOWS}
  192. NativeLineBreak = NativeCrLf;
  193. {$ENDIF MSWINDOWS}
  194. {$IFDEF UNIX}
  195. NativeLineBreak = NativeLineFeed;
  196. {$ENDIF UNIX}
  197. HexPrefixPascal = string('$');
  198. HexPrefixC = string('0x');
  199. HexDigitFmt32 = string('%.8x');
  200. HexDigitFmt64 = string('%.16x');
  201. {$IFDEF BCB}
  202. HexPrefix = HexPrefixC;
  203. {$ELSE ~BCB}
  204. HexPrefix = HexPrefixPascal;
  205. {$ENDIF ~BCB}
  206. {$IFDEF CPU32}
  207. HexDigitFmt = HexDigitFmt32;
  208. {$ENDIF CPU32}
  209. {$IFDEF CPU64}
  210. HexDigitFmt = HexDigitFmt64;
  211. {$ENDIF CPU64}
  212. HexFmt = HexPrefix + HexDigitFmt;
  213. const
  214. BOM_UTF16_LSB: array [0..1] of Byte = ($FF,$FE);
  215. BOM_UTF16_MSB: array [0..1] of Byte = ($FE,$FF);
  216. BOM_UTF8: array [0..2] of Byte = ($EF,$BB,$BF);
  217. BOM_UTF32_LSB: array [0..3] of Byte = ($FF,$FE,$00,$00);
  218. BOM_UTF32_MSB: array [0..3] of Byte = ($00,$00,$FE,$FF);
  219. // BOM_UTF7_1: array [0..3] of Byte = ($2B,$2F,$76,$38);
  220. // BOM_UTF7_2: array [0..3] of Byte = ($2B,$2F,$76,$39);
  221. // BOM_UTF7_3: array [0..3] of Byte = ($2B,$2F,$76,$2B);
  222. // BOM_UTF7_4: array [0..3] of Byte = ($2B,$2F,$76,$2F);
  223. // BOM_UTF7_5: array [0..3] of Byte = ($2B,$2F,$76,$38,$2D);
  224. type
  225. // Unicode transformation formats (UTF) data types
  226. PUTF7 = ^UTF7;
  227. UTF7 = AnsiChar;
  228. PUTF8 = ^UTF8;
  229. UTF8 = AnsiChar;
  230. PUTF16 = ^UTF16;
  231. UTF16 = WideChar;
  232. PUTF32 = ^UTF32;
  233. UTF32 = Cardinal;
  234. // UTF conversion schemes (UCS) data types
  235. PUCS4 = ^UCS4;
  236. UCS4 = Cardinal;
  237. PUCS2 = PWideChar;
  238. UCS2 = WideChar;
  239. TUCS2Array = array of UCS2;
  240. TUCS4Array = array of UCS4;
  241. // string types
  242. TUTF8String = AnsiString;
  243. {$IFDEF SUPPORTS_UNICODE_STRING}
  244. TUTF16String = UnicodeString;
  245. TUCS2String = UnicodeString;
  246. {$ELSE}
  247. TUTF16String = WideString;
  248. TUCS2String = WideString;
  249. {$ENDIF SUPPORTS_UNICODE_STRING}
  250. var
  251. AnsiReplacementCharacter: AnsiChar;
  252. const
  253. UCS4ReplacementCharacter: UCS4 = $0000FFFD;
  254. MaximumUCS2: UCS4 = $0000FFFF;
  255. MaximumUTF16: UCS4 = $0010FFFF;
  256. MaximumUCS4: UCS4 = $7FFFFFFF;
  257. SurrogateHighStart = UCS4($D800);
  258. SurrogateHighEnd = UCS4($DBFF);
  259. SurrogateLowStart = UCS4($DC00);
  260. SurrogateLowEnd = UCS4($DFFF);
  261. // basic set types
  262. type
  263. TSetOfAnsiChar = set of AnsiChar;
  264. {$IFNDEF XPLATFORM_RTL}
  265. procedure RaiseLastOSError;
  266. {$ENDIF ~XPLATFORM_RTL}
  267. {$IFNDEF RTL230_UP}
  268. procedure CheckOSError(ErrorCode: Cardinal);
  269. {$ENDIF RTL230_UP}
  270. procedure MoveChar(const Source: string; FromIndex: SizeInt;
  271. var Dest: string; ToIndex, Count: SizeInt); overload; // Index: 0..n-1
  272. function AnsiByteArrayStringLen(Data: TBytes): SizeInt;
  273. function StringToAnsiByteArray(const S: string): TBytes;
  274. function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string;
  275. function BytesOf(const Value: AnsiString): TBytes; overload;
  276. function BytesOf(const Value: WideString): TBytes; overload;
  277. function BytesOf(const Value: WideChar): TBytes; overload;
  278. function BytesOf(const Value: AnsiChar): TBytes; overload;
  279. function StringOf(const Bytes: array of Byte): AnsiString; overload;
  280. function StringOf(const Bytes: Pointer; Size: Cardinal): AnsiString; overload;
  281. {$IFNDEF FPC}
  282. {$IFNDEF COMPILER11_UP}
  283. type // Definitions for 32 Bit Compilers
  284. // From BaseTsd.h
  285. INT_PTR = Integer;
  286. {$EXTERNALSYM INT_PTR}
  287. LONG_PTR = Longint;
  288. {$EXTERNALSYM LONG_PTR}
  289. UINT_PTR = Cardinal;
  290. {$EXTERNALSYM UINT_PTR}
  291. ULONG_PTR = LongWord;
  292. {$EXTERNALSYM ULONG_PTR}
  293. DWORD_PTR = ULONG_PTR;
  294. {$EXTERNALSYM DWORD_PTR}
  295. {$ENDIF ~COMPILER11_UP}
  296. type
  297. PDWORD_PTR = ^DWORD_PTR;
  298. {$EXTERNALSYM PDWORD_PTR}
  299. {$ENDIF ~FPC}
  300. type
  301. TJclAddr32 = Cardinal;
  302. {$IFDEF FPC}
  303. TJclAddr64 = QWord;
  304. {$IFDEF CPU64}
  305. TJclAddr = QWord;
  306. {$ENDIF CPU64}
  307. {$IFDEF CPU32}
  308. TJclAddr = Cardinal;
  309. {$ENDIF CPU32}
  310. {$ENDIF FPC}
  311. {$IFDEF BORLAND}
  312. TJclAddr64 = Int64;
  313. {$IFDEF CPU64}
  314. TJclAddr = TJclAddr64;
  315. {$ENDIF CPU64}
  316. {$IFDEF CPU32}
  317. TJclAddr = TJclAddr32;
  318. {$ENDIF CPU32}
  319. {$ENDIF BORLAND}
  320. PJclAddr = ^TJclAddr;
  321. EJclAddr64Exception = class(EJclError);
  322. function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32;
  323. function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64;
  324. {$IFDEF FPC}
  325. type
  326. HWND = type Windows.HWND;
  327. {$ENDIF FPC}
  328. {$IFDEF SUPPORTS_GENERICS}
  329. //DOM-IGNORE-BEGIN
  330. type
  331. TCompare<T> = function(const Obj1, Obj2: T): Integer;
  332. TEqualityCompare<T> = function(const Obj1, Obj2: T): Boolean;
  333. THashConvert<T> = function(const AItem: T): Integer;
  334. IEqualityComparer<T> = interface
  335. function Equals(A, B: T): Boolean;
  336. function GetHashCode(Obj: T): Integer;
  337. end;
  338. TEquatable<T: class> = class(TInterfacedObject, IEquatable<T>, IEqualityComparer<T>)
  339. public
  340. { IEquatable<T> }
  341. function TestEquals(Other: T): Boolean; overload;
  342. function IEquatable<T>.Equals = TestEquals;
  343. { IEqualityComparer<T> }
  344. function TestEquals(A, B: T): Boolean; overload;
  345. function IEqualityComparer<T>.Equals = TestEquals;
  346. function GetHashCode2(Obj: T): Integer;
  347. function IEqualityComparer<T>.GetHashCode = GetHashCode2;
  348. end;
  349. //DOM-IGNORE-END
  350. {$ENDIF SUPPORTS_GENERICS}
  351. const
  352. {$IFDEF SUPPORTS_UNICODE}
  353. AWSuffix = 'W';
  354. {$ELSE ~SUPPORTS_UNICODE}
  355. AWSuffix = 'A';
  356. {$ENDIF ~SUPPORTS_UNICODE}
  357. {$IFDEF FPC}
  358. // FPC emits a lot of warning because the first parameter of its internal
  359. // GetMem is a var parameter, which is not initialized before the call to GetMem
  360. procedure GetMem(out P; Size: Longint);
  361. {$ENDIF FPC}
  362. {$IFDEF UNITVERSIONING}
  363. const
  364. UnitVersioning: TUnitVersionInfo = (
  365. RCSfile: '$URL$';
  366. Revision: '$Revision$';
  367. Date: '$Date$';
  368. LogPath: 'JCL\source\common';
  369. Extra: '';
  370. Data: nil
  371. );
  372. {$ENDIF UNITVERSIONING}
  373. implementation
  374. uses
  375. JclResources;
  376. procedure MoveChar(const Source: string; FromIndex: SizeInt;
  377. var Dest: string; ToIndex, Count: SizeInt);
  378. begin
  379. Move(Source[FromIndex + 1], Dest[ToIndex + 1], Count * SizeOf(Char));
  380. end;
  381. function AnsiByteArrayStringLen(Data: TBytes): SizeInt;
  382. var
  383. I: SizeInt;
  384. begin
  385. Result := Length(Data);
  386. for I := 0 to Result - 1 do
  387. if Data[I] = 0 then
  388. begin
  389. Result := I + 1;
  390. Break;
  391. end;
  392. end;
  393. function StringToAnsiByteArray(const S: string): TBytes;
  394. var
  395. I: SizeInt;
  396. AnsiS: AnsiString;
  397. begin
  398. AnsiS := AnsiString(S); // convert to AnsiString
  399. SetLength(Result, Length(AnsiS));
  400. for I := 0 to High(Result) do
  401. Result[I] := Byte(AnsiS[I + 1]);
  402. end;
  403. function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string;
  404. var
  405. I: SizeInt;
  406. AnsiS: AnsiString;
  407. begin
  408. if Length(Data) < Count then
  409. Count := Length(Data);
  410. SetLength(AnsiS, Count);
  411. for I := 0 to Length(AnsiS) - 1 do
  412. AnsiS[I + 1] := AnsiChar(Data[I]);
  413. Result := string(AnsiS); // convert to System.String
  414. end;
  415. function BytesOf(const Value: AnsiString): TBytes;
  416. begin
  417. SetLength(Result, Length(Value));
  418. if Value <> '' then
  419. Move(Pointer(Value)^, Result[0], Length(Value));
  420. end;
  421. function BytesOf(const Value: WideString): TBytes;
  422. begin
  423. if Value <> '' then
  424. Result := JclBase.BytesOf(AnsiString(Value))
  425. else
  426. SetLength(Result, 0);
  427. end;
  428. function BytesOf(const Value: WideChar): TBytes;
  429. begin
  430. Result := JclBase.BytesOf(WideString(Value));
  431. end;
  432. function BytesOf(const Value: AnsiChar): TBytes;
  433. begin
  434. SetLength(Result, 1);
  435. Result[0] := Byte(Value);
  436. end;
  437. function StringOf(const Bytes: array of Byte): AnsiString;
  438. begin
  439. if Length(Bytes) > 0 then
  440. begin
  441. SetLength(Result, Length(Bytes));
  442. Move(Bytes[0], Pointer(Result)^, Length(Bytes));
  443. end
  444. else
  445. Result := '';
  446. end;
  447. function StringOf(const Bytes: Pointer; Size: Cardinal): AnsiString;
  448. begin
  449. if (Bytes <> nil) and (Size > 0) then
  450. begin
  451. SetLength(Result, Size);
  452. Move(Bytes^, Pointer(Result)^, Size);
  453. end
  454. else
  455. Result := '';
  456. end;
  457. // Int64 support
  458. procedure I64ToCardinals(I: Int64; out LowPart, HighPart: Cardinal);
  459. begin
  460. LowPart := TJclULargeInteger(I).LowPart;
  461. HighPart := TJclULargeInteger(I).HighPart;
  462. end;
  463. procedure CardinalsToI64(out I: Int64; const LowPart, HighPart: Cardinal);
  464. begin
  465. TJclULargeInteger(I).LowPart := LowPart;
  466. TJclULargeInteger(I).HighPart := HighPart;
  467. end;
  468. // Cross Platform Compatibility
  469. {$IFNDEF XPLATFORM_RTL}
  470. procedure RaiseLastOSError;
  471. begin
  472. RaiseLastWin32Error;
  473. end;
  474. {$ENDIF ~XPLATFORM_RTL}
  475. {$IFNDEF RTL230_UP}
  476. procedure CheckOSError(ErrorCode: Cardinal);
  477. begin
  478. if ErrorCode <> ERROR_SUCCESS then
  479. {$IFDEF RTL170_UP}
  480. RaiseLastOSError(ErrorCode);
  481. {$ELSE ~RTL170_UP}
  482. RaiseLastOSError;
  483. {$ENDIF ~RTL170_UP}
  484. end;
  485. {$ENDIF RTL230_UP}
  486. {$OVERFLOWCHECKS OFF}
  487. function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32;
  488. begin
  489. if (Value shr 32) = 0 then
  490. Result := Value
  491. else
  492. raise EJclAddr64Exception.CreateResFmt(@RsCantConvertAddr64, [HexPrefix, Value]);
  493. end;
  494. function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64;
  495. begin
  496. Result := Value;
  497. end;
  498. {$IFDEF OVERFLOWCHECKS_ON}
  499. {$OVERFLOWCHECKS ON}
  500. {$ENDIF OVERFLOWCHECKS_ON}
  501. {$IFDEF SUPPORTS_GENERICS}
  502. //DOM-IGNORE-BEGIN
  503. //=== { TEquatable<T> } ======================================================
  504. function TEquatable<T>.TestEquals(Other: T): Boolean;
  505. begin
  506. if Other = nil then
  507. Result := False
  508. else
  509. Result := GetHashCode = Other.GetHashCode;
  510. end;
  511. function TEquatable<T>.TestEquals(A, B: T): Boolean;
  512. begin
  513. if A = nil then
  514. Result := B = nil
  515. else
  516. if B = nil then
  517. Result := False
  518. else
  519. Result := A.GetHashCode = B.GetHashCode;
  520. end;
  521. function TEquatable<T>.GetHashCode2(Obj: T): Integer;
  522. begin
  523. if Obj = nil then
  524. Result := 0
  525. else
  526. Result := Obj.GetHashCode;
  527. end;
  528. //DOM-IGNORE-END
  529. {$ENDIF SUPPORTS_GENERICS}
  530. procedure LoadAnsiReplacementCharacter;
  531. {$IFDEF MSWINDOWS}
  532. var
  533. CpInfo: TCpInfo;
  534. begin
  535. CpInfo.MaxCharSize := 0;
  536. if GetCPInfo(CP_ACP, CpInfo) then
  537. AnsiReplacementCharacter := AnsiChar(Chr(CpInfo.DefaultChar[0]))
  538. else
  539. raise EJclInternalError.CreateRes(@RsEReplacementChar);
  540. end;
  541. {$ELSE ~MSWINDOWS}
  542. begin
  543. AnsiReplacementCharacter := '?';
  544. end;
  545. {$ENDIF ~MSWINDOWS}
  546. {$IFDEF FPC}
  547. // FPC emits a lot of warning because the first parameter of its internal
  548. // GetMem is a var parameter, which is not initialized before the call to GetMem
  549. procedure GetMem(out P; Size: Longint);
  550. begin
  551. Pointer(P) := nil;
  552. GetMem(Pointer(P), Size);
  553. end;
  554. {$ENDIF FPC}
  555. initialization
  556. LoadAnsiReplacementCharacter;
  557. {$IFDEF UNITVERSIONING}
  558. RegisterUnitVersion(HInstance, UnitVersioning);
  559. {$ENDIF UNITVERSIONING}
  560. finalization
  561. {$IFDEF UNITVERSIONING}
  562. UnregisterUnitVersion(HInstance);
  563. {$ENDIF UNITVERSIONING}
  564. end.