PageRenderTime 52ms CodeModel.GetById 13ms RepoModel.GetById 0ms 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
  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 (Status=stOk) Then GetPos := Position { Return position }
  944. Else GetPos := -1; { Stream in error }
  945. END;
  946. {--TStream------------------------------------------------------------------}
  947. { GetSize -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  948. {---------------------------------------------------------------------------}
  949. FUNCTION TStream.GetSize: LongInt;
  950. BEGIN
  951. If (Status=stOk) Then GetSize := StreamSize { Return stream size }
  952. Else GetSize := -1; { Stream in error }
  953. END;
  954. {--TStream------------------------------------------------------------------}
  955. { Close -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  956. {---------------------------------------------------------------------------}
  957. PROCEDURE TStream.Close;
  958. BEGIN { Abstract method }
  959. END;
  960. {--TStream------------------------------------------------------------------}
  961. { Reset -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  962. {---------------------------------------------------------------------------}
  963. PROCEDURE TStream.Reset;
  964. BEGIN
  965. Status := stOK; { Clear status }
  966. ErrorInfo := 0; { Clear error info }
  967. END;
  968. {--TStream------------------------------------------------------------------}
  969. { Flush -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  970. {---------------------------------------------------------------------------}
  971. PROCEDURE TStream.Flush;
  972. BEGIN { Abstract method }
  973. END;
  974. {--TStream------------------------------------------------------------------}
  975. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  976. {---------------------------------------------------------------------------}
  977. PROCEDURE TStream.Truncate;
  978. BEGIN
  979. Abstract; { Abstract error }
  980. END;
  981. {--TStream------------------------------------------------------------------}
  982. { Put -> Platforms DOS/DPMI/WIN/OS2 - Checked 02Sep97 LdB }
  983. {---------------------------------------------------------------------------}
  984. PROCEDURE TStream.Put (P: PObject);
  985. VAR ObjType: Sw_Word; Link: pointer; Q: PStreamRec; VmtPtr: ^pointer;
  986. ObjTypeWord: Word;
  987. BEGIN
  988. VmtPtr := Pointer(P); { Xfer object to ptr }
  989. if assigned(vmtptr) then
  990. Link := VmtPtr^ { VMT link }
  991. else
  992. Link:=nil;
  993. ObjType := 0; { Set objtype to zero }
  994. If (P<>Nil) AND (Link<>Nil) Then Begin { We have a VMT link }
  995. Q := StreamTypes; { Current reg list }
  996. While (Q <> Nil) AND (Q^.VMTLink <> Link) { Find link match OR }
  997. Do Q := Q^.Next; { Find end of chain }
  998. If (Q=Nil) Then Begin { End of chain found }
  999. Error(stPutError, 0); { Not registered error }
  1000. Exit; { Now exit }
  1001. End Else ObjType := Q^.ObjType; { Update object type }
  1002. End;
  1003. If TPCompatible Then Begin
  1004. ObjTypeWord := word(ObjType);
  1005. Write(ObjTypeWord, SizeOf(ObjTypeWord))
  1006. end
  1007. else
  1008. Write(ObjType, SizeOf(ObjType)); { Write object type }
  1009. If (ObjType<>0) Then { Registered object }
  1010. CallPointerMethod(Q^.Store, P, @Self);
  1011. END;
  1012. {--TStream------------------------------------------------------------------}
  1013. { Seek -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1014. {---------------------------------------------------------------------------}
  1015. PROCEDURE TStream.Seek (Pos: LongInt);
  1016. BEGIN
  1017. If (Status = stOk) Then Begin { Check status }
  1018. If (Pos < 0) Then Pos := 0; { Remove negatives }
  1019. If (Pos <= StreamSize) Then Position := Pos { If valid set pos }
  1020. Else Error(stSeekError, Pos); { Position error }
  1021. End;
  1022. END;
  1023. {--TStream------------------------------------------------------------------}
  1024. { StrWrite -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1025. {---------------------------------------------------------------------------}
  1026. PROCEDURE TStream.StrWrite (P: PChar);
  1027. VAR L: Word; Q: PByteArray;
  1028. BEGIN
  1029. L := 0; { Preset zero size }
  1030. Q := PByteArray(P); { Transfer type }
  1031. If (Q <> Nil) Then While (Q^[L] <> 0) Do Inc(L); { PChar length }
  1032. Write(L, SizeOf(L)); { Store length }
  1033. If (P <> Nil) Then Write(P[0], L); { Write data }
  1034. END;
  1035. {--TStream------------------------------------------------------------------}
  1036. { WriteStr -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1037. {---------------------------------------------------------------------------}
  1038. PROCEDURE TStream.WriteStr (P: PString);
  1039. CONST Empty: String[1] = '';
  1040. BEGIN
  1041. If (P <> Nil) Then Write(P^, Length(P^) + 1) { Write string }
  1042. Else Write(Empty, 1); { Write empty string }
  1043. END;
  1044. {--TStream------------------------------------------------------------------}
  1045. { Open -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1046. {---------------------------------------------------------------------------}
  1047. PROCEDURE TStream.Open (OpenMode: Word);
  1048. BEGIN { Abstract method }
  1049. END;
  1050. {--TStream------------------------------------------------------------------}
  1051. { Error -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1052. {---------------------------------------------------------------------------}
  1053. PROCEDURE TStream.Error (Code, Info: Integer);
  1054. TYPE TErrorProc = Procedure(Var S: TStream);
  1055. BEGIN
  1056. Status := Code; { Hold error code }
  1057. ErrorInfo := Info; { Hold error info }
  1058. If (StreamError <> Nil) Then
  1059. TErrorProc(StreamError)(Self); { Call error ptr }
  1060. END;
  1061. {--TStream------------------------------------------------------------------}
  1062. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1063. {---------------------------------------------------------------------------}
  1064. PROCEDURE TStream.Read (Var Buf; Count: Longint);
  1065. BEGIN
  1066. Abstract; { Abstract error }
  1067. END;
  1068. {--TStream------------------------------------------------------------------}
  1069. { Write -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1070. {---------------------------------------------------------------------------}
  1071. PROCEDURE TStream.Write (Var Buf; Count: Longint);
  1072. BEGIN
  1073. Abstract; { Abstract error }
  1074. END;
  1075. {--TStream------------------------------------------------------------------}
  1076. { CopyFrom -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1077. {---------------------------------------------------------------------------}
  1078. PROCEDURE TStream.CopyFrom (Var S: TStream; Count: Longint);
  1079. VAR W: Word; Buffer: Array[0..1023] of Byte;
  1080. BEGIN
  1081. While (Count > 0) Do Begin
  1082. If (Count > SizeOf(Buffer)) Then { To much data }
  1083. W := SizeOf(Buffer) Else W := Count; { Size to transfer }
  1084. S.Read(Buffer, W); { Read from stream }
  1085. Write(Buffer, W); { Write to stream }
  1086. Dec(Count, W); { Dec write count }
  1087. End;
  1088. END;
  1089. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1090. { TDosStream OBJECT METHODS }
  1091. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1092. {$PUSH}
  1093. {$I-}
  1094. {--TDosStream---------------------------------------------------------------}
  1095. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1096. {---------------------------------------------------------------------------}
  1097. CONSTRUCTOR TDosStream.Init (FileName: FNameStr; Mode: Word);
  1098. VAR OldFileMode : Byte;
  1099. DosStreamError : Word;
  1100. BEGIN
  1101. Inherited Init; { Call ancestor }
  1102. FileName := FileName+#0; { Make asciiz }
  1103. Move(FileName[1], FName, Length(FileName)); { Create asciiz name }
  1104. Handle := InvalidHandle;
  1105. Assign(FileInfo,FileName);
  1106. { Handle the mode }
  1107. if Mode =stCreate then
  1108. Begin
  1109. Rewrite(FileInfo,1);
  1110. end
  1111. else
  1112. Begin
  1113. OldFileMode := FileMode;
  1114. { Keep sharing modes! }
  1115. FileMode := Mode and $FF;
  1116. System.Reset(FileInfo,1);
  1117. FileMode := OldFileMode;
  1118. { To use the correct mode we must reclose the file
  1119. and open it again
  1120. }
  1121. end;
  1122. Handle := FileRec(FileInfo).Handle; { Set handle value }
  1123. DosStreamError := IOResult;
  1124. If DosStreamError = 0 then
  1125. Begin
  1126. StreamSize := System.FileSize(FileInfo);
  1127. end;
  1128. If DosStreamError = 0 then
  1129. DosStreamError := IOResult;
  1130. If (DosStreamError <> 0) Then
  1131. Error(stInitError, DosStreamError) { Call stream error }
  1132. else
  1133. Status := StOK;
  1134. END;
  1135. {--TDosStream---------------------------------------------------------------}
  1136. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1137. {---------------------------------------------------------------------------}
  1138. DESTRUCTOR TDosStream.Done;
  1139. var
  1140. DosStreamError : Word;
  1141. BEGIN
  1142. if Handle <> InvalidHandle then
  1143. Begin
  1144. System.Close(FileInfo);
  1145. DosStreamError := IOResult;
  1146. If DosStreamError = 0 then
  1147. Status := stOk
  1148. else
  1149. Error(stError, DosStreamError);
  1150. end;
  1151. Position := 0; { Zero the position }
  1152. Handle := InvalidHandle;
  1153. Inherited Done; { Call ancestor }
  1154. END;
  1155. {--TDosStream---------------------------------------------------------------}
  1156. { Close -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1157. {---------------------------------------------------------------------------}
  1158. PROCEDURE TDosStream.Close;
  1159. var
  1160. DosStreamError : Word;
  1161. BEGIN
  1162. if Handle <> InvalidHandle then { Is file closed ? }
  1163. Begin
  1164. System.Close(FileInfo); { Close file }
  1165. DosStreamError := IOResult; { Check for error }
  1166. If DosStreamError = 0 then
  1167. Status := stOk
  1168. else
  1169. Error(stError, DosStreamError); { Call error routine }
  1170. end;
  1171. Position := 0; { Zero the position }
  1172. Handle := InvalidHandle; { Handle invalid }
  1173. END;
  1174. {--TDosStream---------------------------------------------------------------}
  1175. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1176. {---------------------------------------------------------------------------}
  1177. PROCEDURE TDosStream.Truncate;
  1178. var
  1179. DosStreamError : Word;
  1180. BEGIN
  1181. If Status = stOk then
  1182. Begin
  1183. System.Truncate(FileInfo);
  1184. DosStreamError := IOResult;
  1185. If DosStreamError = 0 then
  1186. { Status is already = stOK }
  1187. StreamSize := Position
  1188. else
  1189. Error(stError, DosStreamError);
  1190. end;
  1191. END;
  1192. {--TDosStream---------------------------------------------------------------}
  1193. { Seek -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1194. {---------------------------------------------------------------------------}
  1195. PROCEDURE TDosStream.Seek (Pos: Longint);
  1196. var
  1197. DosStreamError : Word;
  1198. BEGIN
  1199. If (Status=stOk) Then
  1200. Begin { Check status okay }
  1201. If (Pos < 0) Then
  1202. Pos := 0; { Negatives removed }
  1203. System.Seek(FileInfo, Pos);
  1204. DosStreamError := IOResult;
  1205. if DosStreamError <> 0 then
  1206. Error(stSeekError, DosStreamError){ Specific seek error }
  1207. Else Position := Pos; { Adjust position }
  1208. { Status is already = stOK }
  1209. End;
  1210. END;
  1211. {--TDosStream---------------------------------------------------------------}
  1212. { Open -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1213. {---------------------------------------------------------------------------}
  1214. PROCEDURE TDosStream.Open (OpenMode: Word);
  1215. VAR OldFileMode : Byte;
  1216. DosStreamError : Word;
  1217. BEGIN
  1218. If (Status=stOk) Then
  1219. Begin { Check status okay }
  1220. If (Handle = InvalidHandle) Then
  1221. Begin { File not open }
  1222. Assign(FileInfo,FName);
  1223. { Handle the mode }
  1224. if OpenMode =stCreate then
  1225. Begin
  1226. System.Rewrite(FileInfo,1);
  1227. end
  1228. else
  1229. Begin
  1230. OldFileMode := FileMode;
  1231. FileMode := OpenMode and 3;
  1232. System.Reset(FileInfo,1);
  1233. FileMode := OldFileMode;
  1234. { To use the correct mode we must reclose the file
  1235. and open it again
  1236. }
  1237. end;
  1238. Handle := FileRec(FileInfo).Handle; { Set handle value }
  1239. DosStreamError := IOResult;
  1240. If DosStreamError = 0 then
  1241. StreamSize := System.FileSize(FileInfo);
  1242. If DosStreamError = 0 then
  1243. DosStreamError := IOResult;
  1244. If (DosStreamError <> 0) Then
  1245. Error(stOpenError, DosStreamError) { Call stream error }
  1246. else
  1247. Status := StOK;
  1248. Position := 0;
  1249. end
  1250. Else
  1251. Error(stOpenError, 104); { File already open }
  1252. End;
  1253. END;
  1254. {--TDosStream---------------------------------------------------------------}
  1255. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1256. {---------------------------------------------------------------------------}
  1257. PROCEDURE TDosStream.Read (Var Buf; Count: Longint);
  1258. VAR BytesMoved: Longint;
  1259. DosStreamError : Word;
  1260. BEGIN
  1261. If Status = StOK then
  1262. Begin
  1263. If (Position + Count > StreamSize) Then { Insufficient data }
  1264. Error(stReadError, 0); { Read beyond end!!! }
  1265. If (Handle = InvalidHandle) Then
  1266. Error(stReadError, 103); { File not open }
  1267. BlockRead(FileInfo, Buf, Count, BytesMoved); { Read from file }
  1268. DosStreamError := IOResult;
  1269. If ((DosStreamError<>0) OR (BytesMoved<>Count)) Then
  1270. Begin { Error was detected }
  1271. BytesMoved := 0; { Clear bytes moved }
  1272. If (DosStreamError <> 0) Then
  1273. Error(stReadError, DosStreamError) { Specific read error }
  1274. Else
  1275. Error(stReadError, 0); { Non specific error }
  1276. End;
  1277. Inc(Position, BytesMoved); { Adjust position }
  1278. End;
  1279. { If there was already an error, or an error was just
  1280. generated, fill the vuffer with NULL
  1281. }
  1282. If Status <> StOK then
  1283. FillChar(Buf, Count, #0); { Error clear buffer }
  1284. END;
  1285. {--TDosStream---------------