1
0

JclBase.pas 19 KB

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