JclBase.pas 19 KB

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