PageRenderTime 45ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/rtl/inc/objects.pp

http://github.com/graemeg/freepascal
Puppet | 1453 lines | 1373 code | 80 blank | 0 comment | 6 complexity | 248e0293cffc453cd564ac2569da7ce2 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team.
  4. Objects.pas clone for Free Pascal
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {************[ SOURCE FILE OF FREE VISION ]****************}
  12. { }
  13. { System independent clone of objects.pas }
  14. { }
  15. { Interface Copyright (c) 1992 Borland International }
  16. { }
  17. { Parts Copyright (c) 1999-2000 by Florian Klaempfl }
  18. { fnklaemp@cip.ft.uni-erlangen.de }
  19. { }
  20. { Parts Copyright (c) 1999-2000 by Frank ZAGO }
  21. { zago@ecoledoc.ipc.fr }
  22. { }
  23. { Parts Copyright (c) 1999-2000 by MH Spiegel }
  24. { }
  25. { Parts Copyright (c) 1996, 1999-2000 by Leon de Boer }
  26. { ldeboer@ibm.net }
  27. { }
  28. { Free Vision project coordinator Balazs Scheidler }
  29. { bazsi@tas.vein.hu }
  30. { }
  31. UNIT Objects;
  32. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  33. INTERFACE
  34. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  35. {==== Select assembler ==============================================}
  36. {$IFDEF CPU86}
  37. {$ASMMODE ATT}
  38. {$ENDIF}
  39. {==== Compiler directives ===========================================}
  40. {$H-} { No ansistrings }
  41. {$X+} { Extended syntax is ok }
  42. {$R-} { Disable range checking }
  43. {$ifndef Unix}
  44. {$S-} { Disable Stack Checking }
  45. {$endif}
  46. {$I-} { Disable IO Checking }
  47. {$Q-} { Disable Overflow Checking }
  48. {$V-} { Turn off strict VAR strings }
  49. {$INLINE ON} {Turn on inlining.}
  50. {====================================================================}
  51. {$ifdef win32}
  52. uses
  53. Windows;
  54. {$endif}
  55. {***************************************************************************}
  56. { PUBLIC CONSTANTS }
  57. {***************************************************************************}
  58. {---------------------------------------------------------------------------}
  59. { STREAM ERROR STATE MASKS }
  60. {---------------------------------------------------------------------------}
  61. CONST
  62. stOk = 0; { No stream error }
  63. stError = -1; { Access error }
  64. stInitError = -2; { Initialize error }
  65. stReadError = -3; { Stream read error }
  66. stWriteError = -4; { Stream write error }
  67. stGetError = -5; { Get object error }
  68. stPutError = -6; { Put object error }
  69. stSeekError = -7; { Seek error in stream }
  70. stOpenError = -8; { Error opening stream }
  71. {---------------------------------------------------------------------------}
  72. { STREAM ACCESS MODE CONSTANTS }
  73. {---------------------------------------------------------------------------}
  74. CONST
  75. stCreate = $3C00; { Create new file }
  76. stOpenRead = $3D00; { Read access only }
  77. stOpenWrite = $3D01; { Write access only }
  78. stOpen = $3D02; { Read/write access }
  79. {---------------------------------------------------------------------------}
  80. { TCollection ERROR CODES }
  81. {---------------------------------------------------------------------------}
  82. CONST
  83. coIndexError = -1; { Index out of range }
  84. coOverflow = -2; { Overflow }
  85. {---------------------------------------------------------------------------}
  86. { VMT HEADER CONSTANT - HOPEFULLY WE CAN DROP THIS LATER }
  87. {---------------------------------------------------------------------------}
  88. CONST
  89. vmtHeaderSize = 8; { VMT header size }
  90. CONST
  91. {---------------------------------------------------------------------------}
  92. { MAXIUM DATA SIZES }
  93. {---------------------------------------------------------------------------}
  94. {$IFDEF FPC}
  95. MaxBytes = 128*1024*128; { Maximum data size }
  96. {$ELSE}
  97. MaxBytes = 16384;
  98. {$ENDIF}
  99. MaxWords = MaxBytes DIV SizeOf(Word); { Max word data size }
  100. MaxPtrs = MaxBytes DIV SizeOf(Pointer); { Max ptr data size }
  101. MaxCollectionSize = MaxBytes DIV SizeOf(Pointer); { Max collection size }
  102. MaxTPCompatibleCollectionSize = 65520 div 4;
  103. {***************************************************************************}
  104. { PUBLIC TYPE DEFINITIONS }
  105. {***************************************************************************}
  106. {---------------------------------------------------------------------------}
  107. { CHARACTER SET }
  108. {---------------------------------------------------------------------------}
  109. TYPE
  110. TCharSet = SET Of Char; { Character set }
  111. PCharSet = ^TCharSet; { Character set ptr }
  112. {---------------------------------------------------------------------------}
  113. { GENERAL ARRAYS }
  114. {---------------------------------------------------------------------------}
  115. TYPE
  116. TByteArray = ARRAY [0..MaxBytes-1] Of Byte; { Byte array }
  117. PByteArray = ^TByteArray; { Byte array pointer }
  118. TWordArray = ARRAY [0..MaxWords-1] Of Word; { Word array }
  119. PWordArray = ^TWordArray; { Word array pointer }
  120. TPointerArray = Array [0..MaxPtrs-1] Of Pointer; { Pointer array }
  121. PPointerArray = ^TPointerArray; { Pointer array ptr }
  122. {---------------------------------------------------------------------------}
  123. { POINTER TO STRING }
  124. {---------------------------------------------------------------------------}
  125. TYPE
  126. PString = PShortString; { String pointer }
  127. {---------------------------------------------------------------------------}
  128. { OS dependent File type / consts }
  129. {---------------------------------------------------------------------------}
  130. type
  131. FNameStr = String;
  132. const
  133. MaxReadBytes = $7fffffff;
  134. var
  135. invalidhandle : THandle;
  136. {---------------------------------------------------------------------------}
  137. { DOS ASCIIZ FILENAME }
  138. {---------------------------------------------------------------------------}
  139. TYPE
  140. AsciiZ = Array [0..255] Of Char; { Filename array }
  141. {---------------------------------------------------------------------------}
  142. { BIT SWITCHED TYPE CONSTANTS }
  143. {---------------------------------------------------------------------------}
  144. TYPE
  145. Sw_Word = Cardinal; { Long Word now }
  146. Sw_Integer = LongInt; { Long integer now }
  147. {***************************************************************************}
  148. { PUBLIC RECORD DEFINITIONS }
  149. {***************************************************************************}
  150. {---------------------------------------------------------------------------}
  151. { TYPE CONVERSION RECORDS }
  152. {---------------------------------------------------------------------------}
  153. TYPE
  154. WordRec = packed RECORD
  155. {$ifdef ENDIAN_LITTLE}
  156. Lo, Hi: Byte; { Word to bytes }
  157. {$else}
  158. Hi,Lo: Byte;
  159. {$endif}
  160. END;
  161. LongRec = packed RECORD
  162. {$ifdef ENDIAN_LITTLE}
  163. Lo, Hi: Word; { LongInt to words }
  164. {$else}
  165. Hi,Lo: Word; { LongInt to words }
  166. {$endif}
  167. END;
  168. PtrRec = packed RECORD
  169. Ofs, Seg: Word; { Pointer to words }
  170. END;
  171. {---------------------------------------------------------------------------}
  172. { TStreamRec RECORD - STREAM OBJECT RECORD }
  173. {---------------------------------------------------------------------------}
  174. TYPE
  175. PStreamRec = ^TStreamRec; { Stream record ptr }
  176. TStreamRec = Packed RECORD
  177. ObjType: Sw_Word; { Object type id }
  178. VmtLink: pointer; { VMT link }
  179. Load : Pointer; { Object load code }
  180. Store: Pointer; { Object store code }
  181. Next : PStreamRec; { Next stream record }
  182. END;
  183. {***************************************************************************}
  184. { PUBLIC OBJECT DEFINITIONS }
  185. {***************************************************************************}
  186. {---------------------------------------------------------------------------}
  187. { TPoint OBJECT - POINT OBJECT }
  188. {---------------------------------------------------------------------------}
  189. TYPE
  190. PPoint = ^TPoint;
  191. TPoint = OBJECT
  192. X, Y: Sw_Integer;
  193. END;
  194. {---------------------------------------------------------------------------}
  195. { TRect OBJECT - RECTANGLE OBJECT }
  196. {---------------------------------------------------------------------------}
  197. PRect = ^TRect;
  198. TRect = OBJECT
  199. A, B: TPoint; { Corner points }
  200. FUNCTION Empty: Boolean;
  201. FUNCTION Equals (R: TRect): Boolean;
  202. FUNCTION Contains (P: TPoint): Boolean;
  203. PROCEDURE Copy (R: TRect);
  204. PROCEDURE Union (R: TRect);
  205. PROCEDURE Intersect (R: TRect);
  206. PROCEDURE Move (ADX, ADY: Sw_Integer);
  207. PROCEDURE Grow (ADX, ADY: Sw_Integer);
  208. PROCEDURE Assign (XA, YA, XB, YB: Sw_Integer);
  209. END;
  210. {---------------------------------------------------------------------------}
  211. { TObject OBJECT - BASE ANCESTOR OBJECT }
  212. {---------------------------------------------------------------------------}
  213. TYPE
  214. TObject = OBJECT
  215. CONSTRUCTOR Init;
  216. PROCEDURE Free;
  217. FUNCTION Is_Object(P:Pointer):Boolean;
  218. DESTRUCTOR Done; Virtual;
  219. END;
  220. PObject = ^TObject;
  221. { ******************************* REMARK ****************************** }
  222. { Two new virtual methods have been added to the object in the form of }
  223. { Close and Open. The main use here is in the Disk Based Descendants }
  224. { the calls open and close the given file so these objects can be }
  225. { used like standard files. Two new fields have also been added to }
  226. { speed up seeks on descendants. All existing code will compile and }
  227. { work completely normally oblivious to these new methods and fields. }
  228. { ****************************** END REMARK *** Leon de Boer, 15May96 * }
  229. {---------------------------------------------------------------------------}
  230. { TStream OBJECT - STREAM ANCESTOR OBJECT }
  231. {---------------------------------------------------------------------------}
  232. TYPE
  233. TStream = OBJECT (TObject)
  234. Status : Integer; { Stream status }
  235. ErrorInfo : Integer; { Stream error info }
  236. StreamSize: LongInt; { Stream current size }
  237. Position : LongInt; { Current position }
  238. TPCompatible : Boolean;
  239. CONSTRUCTOR Init;
  240. FUNCTION Get: PObject;
  241. FUNCTION StrRead: PChar;
  242. FUNCTION GetPos: Longint; Virtual;
  243. FUNCTION GetSize: Longint; Virtual;
  244. FUNCTION ReadStr: PString;
  245. PROCEDURE Open (OpenMode: Word); Virtual;
  246. PROCEDURE Close; Virtual;
  247. PROCEDURE Reset;
  248. PROCEDURE Flush; Virtual;
  249. PROCEDURE Truncate; Virtual;
  250. PROCEDURE Put (P: PObject);
  251. PROCEDURE StrWrite (P: PChar);
  252. PROCEDURE WriteStr (P: PString);
  253. PROCEDURE Seek (Pos: LongInt); Virtual;
  254. PROCEDURE Error (Code, Info: Integer); Virtual;
  255. PROCEDURE Read (Var Buf; Count: LongInt); Virtual;
  256. PROCEDURE Write (Var Buf; Count: LongInt); Virtual;
  257. PROCEDURE CopyFrom (Var S: TStream; Count: Longint);
  258. END;
  259. PStream = ^TStream;
  260. { ******************************* REMARK ****************************** }
  261. { A few minor changes to this object and an extra field added called }
  262. { FName which holds an AsciiZ array of the filename this allows the }
  263. { streams file to be opened and closed like a normal text file. All }
  264. { existing code should work without any changes. }
  265. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  266. {---------------------------------------------------------------------------}
  267. { TDosStream OBJECT - DOS FILE STREAM OBJECT }
  268. {---------------------------------------------------------------------------}
  269. TYPE
  270. TDosStream = OBJECT (TStream)
  271. Handle: THandle; { DOS file handle }
  272. FName : AsciiZ; { AsciiZ filename }
  273. CONSTRUCTOR Init (FileName: FNameStr; Mode: Word);
  274. DESTRUCTOR Done; Virtual;
  275. PROCEDURE Close; Virtual;
  276. PROCEDURE Truncate; Virtual;
  277. PROCEDURE Seek (Pos: LongInt); Virtual;
  278. PROCEDURE Open (OpenMode: Word); Virtual;
  279. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  280. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  281. private
  282. FileInfo : File;
  283. END;
  284. PDosStream = ^TDosStream;
  285. { ******************************* REMARK ****************************** }
  286. { A few minor changes to this object and an extra field added called }
  287. { lastmode which holds the read or write condition last using the }
  288. { speed up buffer which helps speed up the flush, position and size }
  289. { functions. All existing code should work without any changes. }
  290. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  291. {---------------------------------------------------------------------------}
  292. { TBufStream OBJECT - BUFFERED DOS FILE STREAM }
  293. {---------------------------------------------------------------------------}
  294. TYPE
  295. TBufStream = OBJECT (TDosStream)
  296. LastMode: Byte; { Last buffer mode }
  297. BufSize : Longint; { Buffer size }
  298. BufPtr : Longint; { Buffer start }
  299. BufEnd : Longint; { Buffer end }
  300. Buffer : PByteArray; { Buffer allocated }
  301. CONSTRUCTOR Init (FileName: FNameStr; Mode, Size: Word);
  302. DESTRUCTOR Done; Virtual;
  303. PROCEDURE Close; Virtual;
  304. PROCEDURE Flush; Virtual;
  305. PROCEDURE Truncate; Virtual;
  306. PROCEDURE Seek (Pos: LongInt); Virtual;
  307. PROCEDURE Open (OpenMode: Word); Virtual;
  308. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  309. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  310. END;
  311. PBufStream = ^TBufStream;
  312. { ******************************* REMARK ****************************** }
  313. { All the changes here should be completely transparent to existing }
  314. { code. Basically the memory blocks do not have to be base segments }
  315. { but this means our list becomes memory blocks rather than segments. }
  316. { The stream will also expand like the other standard streams!! }
  317. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  318. {---------------------------------------------------------------------------}
  319. { TMemoryStream OBJECT - MEMORY STREAM OBJECT }
  320. {---------------------------------------------------------------------------}
  321. TYPE
  322. TMemoryStream = OBJECT (TStream)
  323. BlkCount: Longint; { Number of segments }
  324. BlkSize : Word; { Memory block size }
  325. MemSize : LongInt; { Memory alloc size }
  326. BlkList : PPointerArray; { Memory block list }
  327. CONSTRUCTOR Init (ALimit: Longint; ABlockSize: Word);
  328. DESTRUCTOR Done; Virtual;
  329. PROCEDURE Truncate; Virtual;
  330. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  331. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  332. PRIVATE
  333. FUNCTION ChangeListSize (ALimit: Longint): Boolean;
  334. END;
  335. PMemoryStream = ^TMemoryStream;
  336. TYPE
  337. TItemList = Array [0..MaxCollectionSize - 1] Of Pointer;
  338. PItemList = ^TItemList;
  339. { ******************************* REMARK ****************************** }
  340. { The changes here look worse than they are. The Sw_Integer simply }
  341. { switches between Integers and LongInts if switched between 16 and 32 }
  342. { bit code. All existing code will compile without any changes. }
  343. { ****************************** END REMARK *** Leon de Boer, 10May96 * }
  344. {---------------------------------------------------------------------------}
  345. { TCollection OBJECT - COLLECTION ANCESTOR OBJECT }
  346. {---------------------------------------------------------------------------}
  347. TCollection = OBJECT (TObject)
  348. Items: PItemList; { Item list pointer }
  349. Count: Sw_Integer; { Item count }
  350. Limit: Sw_Integer; { Item limit count }
  351. Delta: Sw_Integer; { Inc delta size }
  352. CONSTRUCTOR Init (ALimit, ADelta: Sw_Integer);
  353. CONSTRUCTOR Load (Var S: TStream);
  354. DESTRUCTOR Done; Virtual;
  355. FUNCTION At (Index: Sw_Integer): Pointer;
  356. FUNCTION IndexOf (Item: Pointer): Sw_Integer; Virtual;
  357. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  358. FUNCTION LastThat (Test: Pointer): Pointer;
  359. FUNCTION FirstThat (Test: Pointer): Pointer;
  360. PROCEDURE Pack;
  361. PROCEDURE FreeAll;
  362. PROCEDURE DeleteAll;
  363. PROCEDURE Free (Item: Pointer);
  364. PROCEDURE Insert (Item: Pointer); Virtual;
  365. PROCEDURE Delete (Item: Pointer);
  366. PROCEDURE AtFree (Index: Sw_Integer);
  367. PROCEDURE FreeItem (Item: Pointer); Virtual;
  368. PROCEDURE AtDelete (Index: Sw_Integer);
  369. PROCEDURE ForEach (Action: Pointer);
  370. PROCEDURE SetLimit (ALimit: Sw_Integer); Virtual;
  371. PROCEDURE Error (Code, Info: Integer); Virtual;
  372. PROCEDURE AtPut (Index: Sw_Integer; Item: Pointer);
  373. PROCEDURE AtInsert (Index: Sw_Integer; Item: Pointer);
  374. PROCEDURE Store (Var S: TStream);
  375. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  376. END;
  377. PCollection = ^TCollection;
  378. {---------------------------------------------------------------------------}
  379. { TSortedCollection OBJECT - SORTED COLLECTION ANCESTOR }
  380. {---------------------------------------------------------------------------}
  381. TYPE
  382. TSortedCollection = OBJECT (TCollection)
  383. Duplicates: Boolean; { Duplicates flag }
  384. CONSTRUCTOR Init (ALimit, ADelta: Sw_Integer);
  385. CONSTRUCTOR Load (Var S: TStream);
  386. FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
  387. FUNCTION IndexOf (Item: Pointer): Sw_Integer; Virtual;
  388. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  389. FUNCTION Search (Key: Pointer; Var Index: Sw_Integer): Boolean;Virtual;
  390. PROCEDURE Insert (Item: Pointer); Virtual;
  391. PROCEDURE Store (Var S: TStream);
  392. END;
  393. PSortedCollection = ^TSortedCollection;
  394. {---------------------------------------------------------------------------}
  395. { TStringCollection OBJECT - STRING COLLECTION OBJECT }
  396. {---------------------------------------------------------------------------}
  397. TYPE
  398. TStringCollection = OBJECT (TSortedCollection)
  399. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  400. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  401. PROCEDURE FreeItem (Item: Pointer); Virtual;
  402. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  403. END;
  404. PStringCollection = ^TStringCollection;
  405. {---------------------------------------------------------------------------}
  406. { TStrCollection OBJECT - STRING COLLECTION OBJECT }
  407. {---------------------------------------------------------------------------}
  408. TYPE
  409. TStrCollection = OBJECT (TSortedCollection)
  410. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  411. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  412. PROCEDURE FreeItem (Item: Pointer); Virtual;
  413. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  414. END;
  415. PStrCollection = ^TStrCollection;
  416. { ******************************* REMARK ****************************** }
  417. { This is a completely >> NEW << object which holds a collection of }
  418. { strings but does not alphabetically sort them. It is a very useful }
  419. { object for insert ordered list boxes! }
  420. { ****************************** END REMARK *** Leon de Boer, 15May96 * }
  421. {---------------------------------------------------------------------------}
  422. { TUnSortedStrCollection - UNSORTED STRING COLLECTION OBJECT }
  423. {---------------------------------------------------------------------------}
  424. TYPE
  425. TUnSortedStrCollection = OBJECT (TStringCollection)
  426. PROCEDURE Insert (Item: Pointer); Virtual;
  427. END;
  428. PUnSortedStrCollection = ^TUnSortedStrCollection;
  429. {---------------------------------------------------------------------------}
  430. { TResourceCollection OBJECT - RESOURCE COLLECTION OBJECT }
  431. {---------------------------------------------------------------------------}
  432. TYPE
  433. TResourceCollection = OBJECT (TStringCollection)
  434. FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
  435. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  436. PROCEDURE FreeItem (Item: Pointer); Virtual;
  437. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  438. END;
  439. PResourceCollection = ^TResourceCollection;
  440. {---------------------------------------------------------------------------}
  441. { TResourceFile OBJECT - RESOURCE FILE OBJECT }
  442. {---------------------------------------------------------------------------}
  443. TYPE
  444. TResourceFile = OBJECT (TObject)
  445. Stream : PStream; { File as a stream }
  446. Modified: Boolean; { Modified flag }
  447. CONSTRUCTOR Init (AStream: PStream);
  448. DESTRUCTOR Done; Virtual;
  449. FUNCTION Count: Sw_Integer;
  450. FUNCTION KeyAt (I: Sw_Integer): String;
  451. FUNCTION Get (Key: String): PObject;
  452. FUNCTION SwitchTo (AStream: PStream; Pack: Boolean): PStream;
  453. PROCEDURE Flush;
  454. PROCEDURE Delete (Key: String);
  455. PROCEDURE Put (Item: PObject; Key: String);
  456. PRIVATE
  457. BasePos: LongInt; { Base position }
  458. IndexPos: LongInt; { Index position }
  459. Index: TResourceCollection; { Index collection }
  460. END;
  461. PResourceFile = ^TResourceFile;
  462. TYPE
  463. TStrIndexRec = Packed RECORD
  464. Key : Sw_word;
  465. Count, Offset: Word;
  466. END;
  467. TStrIndex = Array [0..9999] Of TStrIndexRec;
  468. PStrIndex = ^TStrIndex;
  469. {---------------------------------------------------------------------------}
  470. { TStringList OBJECT - STRING LIST OBJECT }
  471. {---------------------------------------------------------------------------}
  472. TStringList = OBJECT (TObject)
  473. CONSTRUCTOR Load (Var S: TStream);
  474. DESTRUCTOR Done; Virtual;
  475. FUNCTION Get (Key: Sw_Word): String;
  476. PRIVATE
  477. Stream : PStream;
  478. BasePos : Longint;
  479. IndexSize: Longint;
  480. Index : PStrIndex;
  481. PROCEDURE ReadStr (Var S: String; Offset, Skip: Longint);
  482. END;
  483. PStringList = ^TStringList;
  484. {---------------------------------------------------------------------------}
  485. { TStrListMaker OBJECT - RESOURCE FILE OBJECT }
  486. {---------------------------------------------------------------------------}
  487. TYPE
  488. TStrListMaker = OBJECT (TObject)
  489. CONSTRUCTOR Init (AStrSize, AIndexSize: Sw_Word);
  490. DESTRUCTOR Done; Virtual;
  491. PROCEDURE Put (Key: Sw_Word; S: String);
  492. PROCEDURE Store (Var S: TStream);
  493. PRIVATE
  494. StrPos : Sw_Word;
  495. StrSize : Sw_Word;
  496. Strings : PByteArray;
  497. IndexPos : Sw_Word;
  498. IndexSize: Sw_Word;
  499. Index : PStrIndex;
  500. Cur : TStrIndexRec;
  501. PROCEDURE CloseCurrent;
  502. END;
  503. PStrListMaker = ^TStrListMaker;
  504. {***************************************************************************}
  505. { INTERFACE ROUTINES }
  506. {***************************************************************************}
  507. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  508. { CALL HELPERS INTERFACE ROUTINES }
  509. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  510. { Constructor calls.
  511. Ctor Pointer to the constructor.
  512. Obj Pointer to the instance. NIL if new instance to be allocated.
  513. VMT Pointer to the VMT (obtained by TypeOf()).
  514. returns Pointer to the instance.
  515. }
  516. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;inline;
  517. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;inline;
  518. { Method calls.
  519. Method Pointer to the method.
  520. Obj Pointer to the instance. NIL if new instance to be allocated.
  521. returns Pointer to the instance.
  522. }
  523. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;inline;
  524. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;inline;
  525. { Local-function/procedure calls.
  526. Func Pointer to the local function (which must be far-coded).
  527. Frame Frame pointer of the wrapping function.
  528. }
  529. function CallVoidLocal(Func: pointer; Frame: Pointer): pointer;inline;
  530. function CallPointerLocal(Func: pointer; Frame: Pointer; Param1: pointer): pointer;inline;
  531. { Calls of functions/procedures local to methods.
  532. Func Pointer to the local function (which must be far-coded).
  533. Frame Frame pointer of the wrapping method.
  534. Obj Pointer to the object that the method belongs to.
  535. }
  536. function CallVoidMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer): pointer;inline;
  537. function CallPointerMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer; Param1: pointer): pointer;inline;
  538. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  539. { DYNAMIC STRING INTERFACE ROUTINES }
  540. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  541. {-NewStr-------------------------------------------------------------
  542. Allocates a dynamic string into memory. If S is nil, NewStr returns
  543. a nil pointer, otherwise NewStr allocates Length(S)+1 bytes of memory
  544. containing a copy of S, and returns a pointer to the string.
  545. 12Jun96 LdB
  546. ---------------------------------------------------------------------}
  547. FUNCTION NewStr (Const S: String): PString;
  548. {-DisposeStr---------------------------------------------------------
  549. Disposes of a PString allocated by the function NewStr.
  550. 12Jun96 LdB
  551. ---------------------------------------------------------------------}
  552. PROCEDURE DisposeStr (P: PString);
  553. PROCEDURE SetStr(VAR p:pString; CONST s:STRING);
  554. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  555. { STREAM INTERFACE ROUTINES }
  556. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  557. {-Abstract-----------------------------------------------------------
  558. Terminates program with a run-time error 211. When implementing
  559. an abstract object type, call Abstract in those virtual methods that
  560. must be overridden in descendant types. This ensures that any
  561. attempt to use instances of the abstract object type will fail.
  562. 12Jun96 LdB
  563. ---------------------------------------------------------------------}
  564. PROCEDURE Abstract;
  565. {-RegisterObjects----------------------------------------------------
  566. Registers the three standard objects TCollection, TStringCollection
  567. and TStrCollection.
  568. 02Sep97 LdB
  569. ---------------------------------------------------------------------}
  570. PROCEDURE RegisterObjects;
  571. {-RegisterType-------------------------------------------------------
  572. Registers the given object type with Free Vision's streams, creating
  573. a list of known objects. Streams can only store and return these known
  574. object types. Each registered object needs a unique stream registration
  575. record, of type TStreamRec.
  576. 02Sep97 LdB
  577. ---------------------------------------------------------------------}
  578. PROCEDURE RegisterType (Var S: TStreamRec);
  579. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  580. { GENERAL FUNCTION INTERFACE ROUTINES }
  581. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  582. {-LongMul------------------------------------------------------------
  583. Returns the long integer value of X * Y integer values.
  584. 04Sep97 LdB
  585. ---------------------------------------------------------------------}
  586. FUNCTION LongMul (X, Y: Integer): LongInt;
  587. {-LongDiv------------------------------------------------------------
  588. Returns the integer value of long integer X divided by integer Y.
  589. 04Sep97 LdB
  590. ---------------------------------------------------------------------}
  591. FUNCTION LongDiv (X: Longint; Y: Integer): Integer;
  592. {***************************************************************************}
  593. { PUBLIC INITIALIZED VARIABLES }
  594. {***************************************************************************}
  595. CONST
  596. {---------------------------------------------------------------------------}
  597. { INITIALIZED DOS/DPMI/WIN/OS2 PUBLIC VARIABLES }
  598. {---------------------------------------------------------------------------}
  599. StreamError: Pointer = Nil; { Stream error ptr }
  600. DefaultTPCompatible: Boolean = false;
  601. {---------------------------------------------------------------------------}
  602. { STREAM REGISTRATION RECORDS }
  603. {---------------------------------------------------------------------------}
  604. CONST
  605. RCollection: TStreamRec = (
  606. ObjType: 50;
  607. VmtLink: Ofs(TypeOf(TCollection)^);
  608. Load: @TCollection.Load;
  609. Store: @TCollection.Store;
  610. Next: Nil);
  611. RStringCollection: TStreamRec = (
  612. ObjType: 51;
  613. VmtLink: Ofs(TypeOf(TStringCollection)^);
  614. Load: @TStringCollection.Load;
  615. Store: @TStringCollection.Store;
  616. Next: Nil);
  617. RStrCollection: TStreamRec = (
  618. ObjType: 69;
  619. VmtLink: Ofs(TypeOf(TStrCollection)^);
  620. Load: @TStrCollection.Load;
  621. Store: @TStrCollection.Store;
  622. Next: Nil);
  623. RStringList: TStreamRec = (
  624. ObjType: 52;
  625. VmtLink: Ofs(TypeOf(TStringList)^);
  626. Load: @TStringList.Load;
  627. Store: Nil;
  628. Next: Nil);
  629. RStrListMaker: TStreamRec = (
  630. ObjType: 52;
  631. VmtLink: Ofs(TypeOf(TStrListMaker)^);
  632. Load: Nil;
  633. Store: @TStrListMaker.Store;
  634. Next: Nil);
  635. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  636. IMPLEMENTATION
  637. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  638. Uses dos;
  639. {***************************************************************************}
  640. { HELPER ROUTINES FOR CALLING }
  641. {***************************************************************************}
  642. type
  643. VoidLocal = function(_EBP: Pointer): pointer;
  644. PointerLocal = function(_EBP: Pointer; Param1: pointer): pointer;
  645. VoidMethodLocal = function(_EBP: Pointer): pointer;
  646. PointerMethodLocal = function(_EBP: Pointer; Param1: pointer): pointer;
  647. VoidConstructor = function(VMT: pointer; Obj: pointer): pointer;
  648. PointerConstructor = function(VMT: pointer; Obj: pointer; Param1: pointer): pointer;
  649. VoidMethod = function(Obj: pointer): pointer;
  650. PointerMethod = function(Obj: pointer; Param1: pointer): pointer;
  651. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;inline;
  652. begin
  653. CallVoidConstructor := VoidConstructor(Ctor)(Obj, VMT);
  654. end;
  655. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;inline;
  656. {$undef FPC_CallPointerConstructor_Implemented}
  657. begin
  658. {$define FPC_CallPointerConstructor_Implemented}
  659. CallPointerConstructor := PointerConstructor(Ctor)(Obj, VMT, Param1)
  660. end;
  661. {$ifndef FPC_CallPointerConstructor_Implemented}
  662. {$error CallPointerConstructor function not implemented}
  663. {$endif not FPC_CallPointerConstructor_Implemented}
  664. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;inline;
  665. begin
  666. CallVoidMethod := VoidMethod(Method)(Obj)
  667. end;
  668. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;inline;
  669. {$undef FPC_CallPointerMethod_Implemented}
  670. begin
  671. {$define FPC_CallPointerMethod_Implemented}
  672. CallPointerMethod := PointerMethod(Method)(Obj, Param1)
  673. end;
  674. {$ifndef FPC_CallPointerMethod_Implemented}
  675. {$error CallPointerMethod function not implemented}
  676. {$endif not FPC_CallPointerMethod_Implemented}
  677. function CallVoidLocal(Func: pointer; Frame: Pointer): pointer;inline;
  678. begin
  679. CallVoidLocal := VoidLocal(Func)(Frame)
  680. end;
  681. function CallPointerLocal(Func: pointer; Frame: Pointer; Param1: pointer): pointer;inline;
  682. begin
  683. CallPointerLocal := PointerLocal(Func)(Frame, Param1)
  684. end;
  685. function CallVoidMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer): pointer;inline;
  686. begin
  687. CallVoidMethodLocal := VoidMethodLocal(Func)(Frame)
  688. end;
  689. function CallPointerMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer; Param1: pointer): pointer;inline;
  690. begin
  691. CallPointerMethodLocal := PointerMethodLocal(Func)(Frame, Param1)
  692. end;
  693. {***************************************************************************}
  694. { PRIVATE INITIALIZED VARIABLES }
  695. {***************************************************************************}
  696. {---------------------------------------------------------------------------}
  697. { INITIALIZED DOS/DPMI/WIN/OS2 PRIVATE VARIABLES }
  698. {---------------------------------------------------------------------------}
  699. CONST
  700. StreamTypes: PStreamRec = Nil; { Stream types reg }
  701. {***************************************************************************}
  702. { PRIVATE INTERNAL ROUTINES }
  703. {***************************************************************************}
  704. {---------------------------------------------------------------------------}
  705. { RegisterError -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 12Jun96 LdB }
  706. {---------------------------------------------------------------------------}
  707. PROCEDURE RegisterError;
  708. BEGIN
  709. RunError(212); { Register error }
  710. END;
  711. {***************************************************************************}
  712. { OBJECT METHODS }
  713. {***************************************************************************}
  714. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  715. { TRect OBJECT METHODS }
  716. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  717. PROCEDURE CheckEmpty (Var Rect: TRect);
  718. BEGIN
  719. With Rect Do Begin
  720. If (A.X >= B.X) OR (A.Y >= B.Y) Then Begin { Zero or reversed }
  721. A.X := 0; { Clear a.x }
  722. A.Y := 0; { Clear a.y }
  723. B.X := 0; { Clear b.x }
  724. B.Y := 0; { Clear b.y }
  725. End;
  726. End;
  727. END;
  728. {--TRect--------------------------------------------------------------------}
  729. { Empty -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  730. {---------------------------------------------------------------------------}
  731. FUNCTION TRect.Empty: Boolean;
  732. BEGIN
  733. Empty := (A.X >= B.X) OR (A.Y >= B.Y); { Empty result }
  734. END;
  735. {--TRect--------------------------------------------------------------------}
  736. { Equals -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  737. {---------------------------------------------------------------------------}
  738. FUNCTION TRect.Equals (R: TRect): Boolean;
  739. BEGIN
  740. Equals := (A.X = R.A.X) AND (A.Y = R.A.Y) AND
  741. (B.X = R.B.X) AND (B.Y = R.B.Y); { Equals result }
  742. END;
  743. {--TRect--------------------------------------------------------------------}
  744. { Contains -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  745. {---------------------------------------------------------------------------}
  746. FUNCTION TRect.Contains (P: TPoint): Boolean;
  747. BEGIN
  748. Contains := (P.X >= A.X) AND (P.X < B.X) AND
  749. (P.Y >= A.Y) AND (P.Y < B.Y); { Contains result }
  750. END;
  751. {--TRect--------------------------------------------------------------------}
  752. { Copy -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  753. {---------------------------------------------------------------------------}
  754. PROCEDURE TRect.Copy (R: TRect);
  755. BEGIN
  756. A := R.A; { Copy point a }
  757. B := R.B; { Copy point b }
  758. END;
  759. {--TRect--------------------------------------------------------------------}
  760. { Union -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  761. {---------------------------------------------------------------------------}
  762. PROCEDURE TRect.Union (R: TRect);
  763. BEGIN
  764. If (R.A.X < A.X) Then A.X := R.A.X; { Take if smaller }
  765. If (R.A.Y < A.Y) Then A.Y := R.A.Y; { Take if smaller }
  766. If (R.B.X > B.X) Then B.X := R.B.X; { Take if larger }
  767. If (R.B.Y > B.Y) Then B.Y := R.B.Y; { Take if larger }
  768. END;
  769. {--TRect--------------------------------------------------------------------}
  770. { Intersect -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  771. {---------------------------------------------------------------------------}
  772. PROCEDURE TRect.Intersect (R: TRect);
  773. BEGIN
  774. If (R.A.X > A.X) Then A.X := R.A.X; { Take if larger }
  775. If (R.A.Y > A.Y) Then A.Y := R.A.Y; { Take if larger }
  776. If (R.B.X < B.X) Then B.X := R.B.X; { Take if smaller }
  777. If (R.B.Y < B.Y) Then B.Y := R.B.Y; { Take if smaller }
  778. CheckEmpty(Self); { Check if empty }
  779. END;
  780. {--TRect--------------------------------------------------------------------}
  781. { Move -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  782. {---------------------------------------------------------------------------}
  783. PROCEDURE TRect.Move (ADX, ADY: Sw_Integer);
  784. BEGIN
  785. Inc(A.X, ADX); { Adjust A.X }
  786. Inc(A.Y, ADY); { Adjust A.Y }
  787. Inc(B.X, ADX); { Adjust B.X }
  788. Inc(B.Y, ADY); { Adjust B.Y }
  789. END;
  790. {--TRect--------------------------------------------------------------------}
  791. { Grow -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  792. {---------------------------------------------------------------------------}
  793. PROCEDURE TRect.Grow (ADX, ADY: Sw_Integer);
  794. BEGIN
  795. Dec(A.X, ADX); { Adjust A.X }
  796. Dec(A.Y, ADY); { Adjust A.Y }
  797. Inc(B.X, ADX); { Adjust B.X }
  798. Inc(B.Y, ADY); { Adjust B.Y }
  799. CheckEmpty(Self); { Check if empty }
  800. END;
  801. {--TRect--------------------------------------------------------------------}
  802. { Assign -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  803. {---------------------------------------------------------------------------}
  804. PROCEDURE TRect.Assign (XA, YA, XB, YB: Sw_Integer);
  805. BEGIN
  806. A.X := XA; { Hold A.X value }
  807. A.Y := YA; { Hold A.Y value }
  808. B.X := XB; { Hold B.X value }
  809. B.Y := YB; { Hold B.Y value }
  810. END;
  811. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  812. { TObject OBJECT METHODS }
  813. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  814. TYPE
  815. DummyObject = OBJECT (TObject) { Internal object }
  816. Data: RECORD END; { Helps size VMT link }
  817. END;
  818. { ******************************* REMARK ****************************** }
  819. { I Prefer this code because it self sizes VMT link rather than using a }
  820. { fixed record structure thus it should work on all compilers without a }
  821. { specific record to match each compiler. }
  822. { ****************************** END REMARK *** Leon de Boer, 10May96 * }
  823. {--TObject------------------------------------------------------------------}
  824. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  825. {---------------------------------------------------------------------------}
  826. CONSTRUCTOR TObject.Init;
  827. VAR LinkSize: LongInt; Dummy: DummyObject;
  828. BEGIN
  829. LinkSize := Pbyte(@Dummy.Data)-Pbyte(@Dummy); { Calc VMT link size }
  830. FillChar((Pbyte(@Self)+LinkSize)^,
  831. SizeOf(Self)-LinkSize, #0); { Clear data fields }
  832. END;
  833. {--TObject------------------------------------------------------------------}
  834. { Free -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  835. {---------------------------------------------------------------------------}
  836. PROCEDURE TObject.Free;
  837. BEGIN
  838. Dispose(PObject(@Self), Done); { Dispose of self }
  839. END;
  840. {--TObject------------------------------------------------------------------}
  841. { Is_Object -> Platforms DOS/DPMI/WIN/OS2 - Checked 5Mar00 DM }
  842. {---------------------------------------------------------------------------}
  843. FUNCTION TObject.Is_Object(P:Pointer):Boolean;
  844. TYPE
  845. PVMT=^VMT;
  846. PPVMT=^PVMT;
  847. VMT=RECORD
  848. Size,NegSize:Longint;
  849. ParentLink:PVMT;
  850. END;
  851. VAR SP:PPVMT; Q:PVMT;
  852. BEGIN
  853. SP:=PPVMT(@SELF);
  854. Q:=SP^;
  855. Is_Object:=False;
  856. While Q<>Nil Do Begin
  857. IF Q=P THEN Begin
  858. Is_Object:=True;
  859. Break;
  860. End;
  861. Q:=Q^.Parentlink;
  862. End;
  863. END;
  864. {--TObject------------------------------------------------------------------}
  865. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  866. {---------------------------------------------------------------------------}
  867. DESTRUCTOR TObject.Done;
  868. BEGIN { Abstract method }
  869. END;
  870. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  871. { TStream OBJECT METHODS }
  872. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  873. CONSTRUCTOR TStream.Init;
  874. BEGIN
  875. Status := StOK;
  876. ErrorInfo := 0;
  877. StreamSize := 0;
  878. Position := 0;
  879. TPCompatible := DefaultTPCompatible;
  880. END;
  881. {--TStream------------------------------------------------------------------}
  882. { Get -> Platforms DOS/DPMI/WIN/OS2 - Checked 02Sep97 LdB }
  883. {---------------------------------------------------------------------------}
  884. FUNCTION TStream.Get: PObject;
  885. VAR ObjType: Sw_Word; P: PStreamRec; ObjTypeWord: Word;
  886. BEGIN
  887. If TPCompatible Then Begin
  888. { Read 16-bit word for TP compatibility. }
  889. Read(ObjTypeWord, SizeOf(ObjTypeWord));
  890. ObjType := ObjTypeWord
  891. End
  892. else
  893. Read(ObjType, SizeOf(ObjType)); { Read object type }
  894. If (ObjType<>0) Then Begin { Object registered }
  895. P := StreamTypes; { Current reg list }
  896. While (P <> Nil) AND (P^.ObjType <> ObjType) { Find object type OR }
  897. Do P := P^.Next; { Find end of chain }
  898. If (P=Nil) Then Begin { Not registered }
  899. Error(stGetError, ObjType); { Obj not registered }
  900. Get := Nil; { Return nil pointer }
  901. End Else
  902. Get :=PObject(
  903. CallPointerConstructor(P^.Load,Nil,P^.VMTLink, @Self)) { Call constructor }
  904. End Else Get := Nil; { Return nil pointer }
  905. END;
  906. {--TStream------------------------------------------------------------------}
  907. { StrRead -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  908. {---------------------------------------------------------------------------}
  909. FUNCTION TStream.StrRead: PChar;
  910. VAR L: Word; P: PChar;
  911. BEGIN
  912. Read(L, SizeOf(L)); { Read length }
  913. If (L = 0) Then StrRead := Nil Else Begin { Check for empty }
  914. GetMem(P, L + 1); { Allocate memory }
  915. If (P <> Nil) Then Begin { Check allocate okay }
  916. Read(P[0], L); { Read the data }
  917. P[L] := #0; { Terminate with #0 }
  918. End;
  919. StrRead := P; { Return PChar }
  920. End;
  921. END;
  922. {--TStream------------------------------------------------------------------}
  923. { ReadStr -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  924. {---------------------------------------------------------------------------}
  925. FUNCTION TStream.ReadStr: PString;
  926. VAR L: Byte; P: PString;
  927. BEGIN
  928. Read(L, 1); { Read string length }
  929. If (L > 0) Then Begin
  930. GetMem(P, L + 1); { Allocate memory }
  931. If (P <> Nil) Then Begin { Check allocate okay }
  932. P^[0] := Char(L); { Hold length }
  933. Read(P^[1], L); { Read string data }
  934. End;
  935. ReadStr := P; { Return string ptr }
  936. End Else ReadStr := Nil;
  937. END;
  938. {--TStream------------------------------------------------------------------}
  939. { GetPos -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  940. {---------------------------------------------------------------------------}
  941. FUNCTION TStream.GetPos: LongInt;
  942. BEGIN
  943. If (Stat

Large files files are truncated, but you can click here to view the full file