JclBase.pas 19 KB

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