JclBase.pas 19 KB

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