objects.pp 139 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Objects.pas clone for Free Pascal
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {************[ SOURCE FILE OF FREE VISION ]****************}
  13. { }
  14. { System independent clone of objects.pas }
  15. { }
  16. { Interface Copyright (c) 1992 Borland International }
  17. { }
  18. { Parts Copyright (c) 1999-2000 by Florian Klaempfl }
  19. { [email protected] }
  20. { }
  21. { Parts Copyright (c) 1999-2000 by Frank ZAGO }
  22. { [email protected] }
  23. { }
  24. { Parts Copyright (c) 1999-2000 by MH Spiegel }
  25. { }
  26. { Parts Copyright (c) 1996, 1999-2000 by Leon de Boer }
  27. { [email protected] }
  28. { }
  29. { Free Vision project coordinator Balazs Scheidler }
  30. { [email protected] }
  31. { }
  32. UNIT Objects;
  33. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  34. INTERFACE
  35. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  36. {==== Select assembler ==============================================}
  37. {$IFDEF CPU86}
  38. {$ASMMODE ATT}
  39. {$ENDIF}
  40. {==== Compiler directives ===========================================}
  41. {$H-} { No ansistrings }
  42. {$E+} { Emulation is on }
  43. {$X+} { Extended syntax is ok }
  44. {$R-} { Disable range checking }
  45. {$ifndef Unix}
  46. {$S-} { Disable Stack Checking }
  47. {$endif}
  48. {$I-} { Disable IO Checking }
  49. {$Q-} { Disable Overflow Checking }
  50. {$V-} { Turn off strict VAR strings }
  51. {====================================================================}
  52. {$ifdef win32}
  53. uses
  54. Windows;
  55. {$endif}
  56. {***************************************************************************}
  57. { PUBLIC CONSTANTS }
  58. {***************************************************************************}
  59. {---------------------------------------------------------------------------}
  60. { STREAM ERROR STATE MASKS }
  61. {---------------------------------------------------------------------------}
  62. CONST
  63. stOk = 0; { No stream error }
  64. stError = -1; { Access error }
  65. stInitError = -2; { Initialize error }
  66. stReadError = -3; { Stream read error }
  67. stWriteError = -4; { Stream write error }
  68. stGetError = -5; { Get object error }
  69. stPutError = -6; { Put object error }
  70. stSeekError = -7; { Seek error in stream }
  71. stOpenError = -8; { Error opening stream }
  72. {---------------------------------------------------------------------------}
  73. { STREAM ACCESS MODE CONSTANTS }
  74. {---------------------------------------------------------------------------}
  75. CONST
  76. stCreate = $3C00; { Create new file }
  77. stOpenRead = $3D00; { Read access only }
  78. stOpenWrite = $3D01; { Write access only }
  79. stOpen = $3D02; { Read/write access }
  80. {---------------------------------------------------------------------------}
  81. { TCollection ERROR CODES }
  82. {---------------------------------------------------------------------------}
  83. CONST
  84. coIndexError = -1; { Index out of range }
  85. coOverflow = -2; { Overflow }
  86. {---------------------------------------------------------------------------}
  87. { VMT HEADER CONSTANT - HOPEFULLY WE CAN DROP THIS LATER }
  88. {---------------------------------------------------------------------------}
  89. CONST
  90. vmtHeaderSize = 8; { VMT header size }
  91. CONST
  92. {---------------------------------------------------------------------------}
  93. { MAXIUM DATA SIZES }
  94. {---------------------------------------------------------------------------}
  95. {$IFDEF FPC}
  96. MaxBytes = 128*1024*128; { Maximum data size }
  97. {$ELSE}
  98. MaxBytes = 16384;
  99. {$ENDIF}
  100. MaxWords = MaxBytes DIV SizeOf(Word); { Max word data size }
  101. MaxPtrs = MaxBytes DIV SizeOf(Pointer); { Max ptr data size }
  102. MaxCollectionSize = MaxBytes DIV SizeOf(Pointer); { Max collection size }
  103. MaxTPCompatibleCollectionSize = 65520 div 4;
  104. {***************************************************************************}
  105. { PUBLIC TYPE DEFINITIONS }
  106. {***************************************************************************}
  107. {---------------------------------------------------------------------------}
  108. { CHARACTER SET }
  109. {---------------------------------------------------------------------------}
  110. TYPE
  111. TCharSet = SET Of Char; { Character set }
  112. PCharSet = ^TCharSet; { Character set ptr }
  113. {---------------------------------------------------------------------------}
  114. { GENERAL ARRAYS }
  115. {---------------------------------------------------------------------------}
  116. TYPE
  117. TByteArray = ARRAY [0..MaxBytes-1] Of Byte; { Byte array }
  118. PByteArray = ^TByteArray; { Byte array pointer }
  119. TWordArray = ARRAY [0..MaxWords-1] Of Word; { Word array }
  120. PWordArray = ^TWordArray; { Word array pointer }
  121. TPointerArray = Array [0..MaxPtrs-1] Of Pointer; { Pointer array }
  122. PPointerArray = ^TPointerArray; { Pointer array ptr }
  123. {---------------------------------------------------------------------------}
  124. { POINTER TO STRING }
  125. {---------------------------------------------------------------------------}
  126. TYPE
  127. PString = PShortString; { String pointer }
  128. {---------------------------------------------------------------------------}
  129. { OS dependent File type / consts }
  130. {---------------------------------------------------------------------------}
  131. type
  132. FNameStr = String;
  133. const
  134. MaxReadBytes = $7fffffff;
  135. var
  136. invalidhandle : THandle;
  137. {---------------------------------------------------------------------------}
  138. { DOS ASCIIZ FILENAME }
  139. {---------------------------------------------------------------------------}
  140. TYPE
  141. AsciiZ = Array [0..255] Of Char; { Filename array }
  142. {---------------------------------------------------------------------------}
  143. { BIT SWITCHED TYPE CONSTANTS }
  144. {---------------------------------------------------------------------------}
  145. TYPE
  146. Sw_Word = Cardinal; { Long Word now }
  147. Sw_Integer = LongInt; { Long integer now }
  148. {***************************************************************************}
  149. { PUBLIC RECORD DEFINITIONS }
  150. {***************************************************************************}
  151. {---------------------------------------------------------------------------}
  152. { TYPE CONVERSION RECORDS }
  153. {---------------------------------------------------------------------------}
  154. TYPE
  155. WordRec = packed RECORD
  156. {$ifdef ENDIAN_LITTLE}
  157. Lo, Hi: Byte; { Word to bytes }
  158. {$else}
  159. Hi,Lo: Byte;
  160. {$endif}
  161. END;
  162. LongRec = packed RECORD
  163. {$ifdef ENDIAN_LITTLE}
  164. Lo, Hi: Word; { LongInt to words }
  165. {$else}
  166. Hi,Lo: Word; { LongInt to words }
  167. {$endif}
  168. END;
  169. PtrRec = packed RECORD
  170. Ofs, Seg: Word; { Pointer to words }
  171. END;
  172. {---------------------------------------------------------------------------}
  173. { TStreamRec RECORD - STREAM OBJECT RECORD }
  174. {---------------------------------------------------------------------------}
  175. TYPE
  176. PStreamRec = ^TStreamRec; { Stream record ptr }
  177. TStreamRec = Packed RECORD
  178. ObjType: Sw_Word; { Object type id }
  179. VmtLink: pointer; { VMT link }
  180. Load : Pointer; { Object load code }
  181. Store: Pointer; { Object store code }
  182. Next : PStreamRec; { Next stream record }
  183. END;
  184. {***************************************************************************}
  185. { PUBLIC OBJECT DEFINITIONS }
  186. {***************************************************************************}
  187. {---------------------------------------------------------------------------}
  188. { TPoint OBJECT - POINT OBJECT }
  189. {---------------------------------------------------------------------------}
  190. TYPE
  191. PPoint = ^TPoint;
  192. TPoint = OBJECT
  193. X, Y: Sw_Integer;
  194. END;
  195. {---------------------------------------------------------------------------}
  196. { TRect OBJECT - RECTANGLE OBJECT }
  197. {---------------------------------------------------------------------------}
  198. PRect = ^TRect;
  199. TRect = OBJECT
  200. A, B: TPoint; { Corner points }
  201. FUNCTION Empty: Boolean;
  202. FUNCTION Equals (R: TRect): Boolean;
  203. FUNCTION Contains (P: TPoint): Boolean;
  204. PROCEDURE Copy (R: TRect);
  205. PROCEDURE Union (R: TRect);
  206. PROCEDURE Intersect (R: TRect);
  207. PROCEDURE Move (ADX, ADY: Sw_Integer);
  208. PROCEDURE Grow (ADX, ADY: Sw_Integer);
  209. PROCEDURE Assign (XA, YA, XB, YB: Sw_Integer);
  210. END;
  211. {---------------------------------------------------------------------------}
  212. { TObject OBJECT - BASE ANCESTOR OBJECT }
  213. {---------------------------------------------------------------------------}
  214. TYPE
  215. TObject = OBJECT
  216. CONSTRUCTOR Init;
  217. PROCEDURE Free;
  218. FUNCTION Is_Object(P:Pointer):Boolean;
  219. DESTRUCTOR Done; Virtual;
  220. END;
  221. PObject = ^TObject;
  222. { ******************************* REMARK ****************************** }
  223. { Two new virtual methods have been added to the object in the form of }
  224. { Close and Open. The main use here is in the Disk Based Descendants }
  225. { the calls open and close the given file so these objects can be }
  226. { used like standard files. Two new fields have also been added to }
  227. { speed up seeks on descendants. All existing code will compile and }
  228. { work completely normally oblivious to these new methods and fields. }
  229. { ****************************** END REMARK *** Leon de Boer, 15May96 * }
  230. {---------------------------------------------------------------------------}
  231. { TStream OBJECT - STREAM ANCESTOR OBJECT }
  232. {---------------------------------------------------------------------------}
  233. TYPE
  234. TStream = OBJECT (TObject)
  235. Status : Integer; { Stream status }
  236. ErrorInfo : Integer; { Stream error info }
  237. StreamSize: LongInt; { Stream current size }
  238. Position : LongInt; { Current position }
  239. TPCompatible : Boolean;
  240. CONSTRUCTOR Init;
  241. FUNCTION Get: PObject;
  242. FUNCTION StrRead: PChar;
  243. FUNCTION GetPos: Longint; Virtual;
  244. FUNCTION GetSize: Longint; Virtual;
  245. FUNCTION ReadStr: PString;
  246. PROCEDURE Open (OpenMode: Word); Virtual;
  247. PROCEDURE Close; Virtual;
  248. PROCEDURE Reset;
  249. PROCEDURE Flush; Virtual;
  250. PROCEDURE Truncate; Virtual;
  251. PROCEDURE Put (P: PObject);
  252. PROCEDURE StrWrite (P: PChar);
  253. PROCEDURE WriteStr (P: PString);
  254. PROCEDURE Seek (Pos: LongInt); Virtual;
  255. PROCEDURE Error (Code, Info: Integer); Virtual;
  256. PROCEDURE Read (Var Buf; Count: LongInt); Virtual;
  257. PROCEDURE Write (Var Buf; Count: LongInt); Virtual;
  258. PROCEDURE CopyFrom (Var S: TStream; Count: Longint);
  259. END;
  260. PStream = ^TStream;
  261. { ******************************* REMARK ****************************** }
  262. { A few minor changes to this object and an extra field added called }
  263. { FName which holds an AsciiZ array of the filename this allows the }
  264. { streams file to be opened and closed like a normal text file. All }
  265. { existing code should work without any changes. }
  266. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  267. {---------------------------------------------------------------------------}
  268. { TDosStream OBJECT - DOS FILE STREAM OBJECT }
  269. {---------------------------------------------------------------------------}
  270. TYPE
  271. TDosStream = OBJECT (TStream)
  272. Handle: THandle; { DOS file handle }
  273. FName : AsciiZ; { AsciiZ filename }
  274. CONSTRUCTOR Init (FileName: FNameStr; Mode: Word);
  275. DESTRUCTOR Done; Virtual;
  276. PROCEDURE Close; Virtual;
  277. PROCEDURE Truncate; Virtual;
  278. PROCEDURE Seek (Pos: LongInt); Virtual;
  279. PROCEDURE Open (OpenMode: Word); Virtual;
  280. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  281. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  282. private
  283. FileInfo : File;
  284. END;
  285. PDosStream = ^TDosStream;
  286. { ******************************* REMARK ****************************** }
  287. { A few minor changes to this object and an extra field added called }
  288. { lastmode which holds the read or write condition last using the }
  289. { speed up buffer which helps speed up the flush, position and size }
  290. { functions. All existing code should work without any changes. }
  291. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  292. {---------------------------------------------------------------------------}
  293. { TBufStream OBJECT - BUFFERED DOS FILE STREAM }
  294. {---------------------------------------------------------------------------}
  295. TYPE
  296. TBufStream = OBJECT (TDosStream)
  297. LastMode: Byte; { Last buffer mode }
  298. BufSize : Longint; { Buffer size }
  299. BufPtr : Longint; { Buffer start }
  300. BufEnd : Longint; { Buffer end }
  301. Buffer : PByteArray; { Buffer allocated }
  302. CONSTRUCTOR Init (FileName: FNameStr; Mode, Size: Word);
  303. DESTRUCTOR Done; Virtual;
  304. PROCEDURE Close; Virtual;
  305. PROCEDURE Flush; Virtual;
  306. PROCEDURE Truncate; Virtual;
  307. PROCEDURE Seek (Pos: LongInt); Virtual;
  308. PROCEDURE Open (OpenMode: Word); Virtual;
  309. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  310. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  311. END;
  312. PBufStream = ^TBufStream;
  313. { ******************************* REMARK ****************************** }
  314. { All the changes here should be completely transparent to existing }
  315. { code. Basically the memory blocks do not have to be base segments }
  316. { but this means our list becomes memory blocks rather than segments. }
  317. { The stream will also expand like the other standard streams!! }
  318. { ****************************** END REMARK *** Leon de Boer, 19May96 * }
  319. {---------------------------------------------------------------------------}
  320. { TMemoryStream OBJECT - MEMORY STREAM OBJECT }
  321. {---------------------------------------------------------------------------}
  322. TYPE
  323. TMemoryStream = OBJECT (TStream)
  324. BlkCount: Longint; { Number of segments }
  325. BlkSize : Word; { Memory block size }
  326. MemSize : LongInt; { Memory alloc size }
  327. BlkList : PPointerArray; { Memory block list }
  328. CONSTRUCTOR Init (ALimit: Longint; ABlockSize: Word);
  329. DESTRUCTOR Done; Virtual;
  330. PROCEDURE Truncate; Virtual;
  331. PROCEDURE Read (Var Buf; Count: Longint); Virtual;
  332. PROCEDURE Write (Var Buf; Count: Longint); Virtual;
  333. PRIVATE
  334. FUNCTION ChangeListSize (ALimit: Longint): Boolean;
  335. END;
  336. PMemoryStream = ^TMemoryStream;
  337. TYPE
  338. TItemList = Array [0..MaxCollectionSize - 1] Of Pointer;
  339. PItemList = ^TItemList;
  340. { ******************************* REMARK ****************************** }
  341. { The changes here look worse than they are. The Sw_Integer simply }
  342. { switches between Integers and LongInts if switched between 16 and 32 }
  343. { bit code. All existing code will compile without any changes. }
  344. { ****************************** END REMARK *** Leon de Boer, 10May96 * }
  345. {---------------------------------------------------------------------------}
  346. { TCollection OBJECT - COLLECTION ANCESTOR OBJECT }
  347. {---------------------------------------------------------------------------}
  348. TCollection = OBJECT (TObject)
  349. Items: PItemList; { Item list pointer }
  350. Count: Sw_Integer; { Item count }
  351. Limit: Sw_Integer; { Item limit count }
  352. Delta: Sw_Integer; { Inc delta size }
  353. CONSTRUCTOR Init (ALimit, ADelta: Sw_Integer);
  354. CONSTRUCTOR Load (Var S: TStream);
  355. DESTRUCTOR Done; Virtual;
  356. FUNCTION At (Index: Sw_Integer): Pointer;
  357. FUNCTION IndexOf (Item: Pointer): Sw_Integer; Virtual;
  358. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  359. FUNCTION LastThat (Test: Pointer): Pointer;
  360. FUNCTION FirstThat (Test: Pointer): Pointer;
  361. PROCEDURE Pack;
  362. PROCEDURE FreeAll;
  363. PROCEDURE DeleteAll;
  364. PROCEDURE Free (Item: Pointer);
  365. PROCEDURE Insert (Item: Pointer); Virtual;
  366. PROCEDURE Delete (Item: Pointer);
  367. PROCEDURE AtFree (Index: Sw_Integer);
  368. PROCEDURE FreeItem (Item: Pointer); Virtual;
  369. PROCEDURE AtDelete (Index: Sw_Integer);
  370. PROCEDURE ForEach (Action: Pointer);
  371. PROCEDURE SetLimit (ALimit: Sw_Integer); Virtual;
  372. PROCEDURE Error (Code, Info: Integer); Virtual;
  373. PROCEDURE AtPut (Index: Sw_Integer; Item: Pointer);
  374. PROCEDURE AtInsert (Index: Sw_Integer; Item: Pointer);
  375. PROCEDURE Store (Var S: TStream);
  376. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  377. END;
  378. PCollection = ^TCollection;
  379. {---------------------------------------------------------------------------}
  380. { TSortedCollection OBJECT - SORTED COLLECTION ANCESTOR }
  381. {---------------------------------------------------------------------------}
  382. TYPE
  383. TSortedCollection = OBJECT (TCollection)
  384. Duplicates: Boolean; { Duplicates flag }
  385. CONSTRUCTOR Init (ALimit, ADelta: Sw_Integer);
  386. CONSTRUCTOR Load (Var S: TStream);
  387. FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
  388. FUNCTION IndexOf (Item: Pointer): Sw_Integer; Virtual;
  389. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  390. FUNCTION Search (Key: Pointer; Var Index: Sw_Integer): Boolean;Virtual;
  391. PROCEDURE Insert (Item: Pointer); Virtual;
  392. PROCEDURE Store (Var S: TStream);
  393. END;
  394. PSortedCollection = ^TSortedCollection;
  395. {---------------------------------------------------------------------------}
  396. { TStringCollection OBJECT - STRING COLLECTION OBJECT }
  397. {---------------------------------------------------------------------------}
  398. TYPE
  399. TStringCollection = OBJECT (TSortedCollection)
  400. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  401. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  402. PROCEDURE FreeItem (Item: Pointer); Virtual;
  403. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  404. END;
  405. PStringCollection = ^TStringCollection;
  406. {---------------------------------------------------------------------------}
  407. { TStrCollection OBJECT - STRING COLLECTION OBJECT }
  408. {---------------------------------------------------------------------------}
  409. TYPE
  410. TStrCollection = OBJECT (TSortedCollection)
  411. FUNCTION Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
  412. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  413. PROCEDURE FreeItem (Item: Pointer); Virtual;
  414. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  415. END;
  416. PStrCollection = ^TStrCollection;
  417. { ******************************* REMARK ****************************** }
  418. { This is a completely >> NEW << object which holds a collection of }
  419. { strings but does not alphabetically sort them. It is a very useful }
  420. { object for insert ordered list boxes! }
  421. { ****************************** END REMARK *** Leon de Boer, 15May96 * }
  422. {---------------------------------------------------------------------------}
  423. { TUnSortedStrCollection - UNSORTED STRING COLLECTION OBJECT }
  424. {---------------------------------------------------------------------------}
  425. TYPE
  426. TUnSortedStrCollection = OBJECT (TStringCollection)
  427. PROCEDURE Insert (Item: Pointer); Virtual;
  428. END;
  429. PUnSortedStrCollection = ^TUnSortedStrCollection;
  430. {---------------------------------------------------------------------------}
  431. { TResourceCollection OBJECT - RESOURCE COLLECTION OBJECT }
  432. {---------------------------------------------------------------------------}
  433. TYPE
  434. TResourceCollection = OBJECT (TStringCollection)
  435. FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
  436. FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
  437. PROCEDURE FreeItem (Item: Pointer); Virtual;
  438. PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
  439. END;
  440. PResourceCollection = ^TResourceCollection;
  441. {---------------------------------------------------------------------------}
  442. { TResourceFile OBJECT - RESOURCE FILE OBJECT }
  443. {---------------------------------------------------------------------------}
  444. TYPE
  445. TResourceFile = OBJECT (TObject)
  446. Stream : PStream; { File as a stream }
  447. Modified: Boolean; { Modified flag }
  448. CONSTRUCTOR Init (AStream: PStream);
  449. DESTRUCTOR Done; Virtual;
  450. FUNCTION Count: Sw_Integer;
  451. FUNCTION KeyAt (I: Sw_Integer): String;
  452. FUNCTION Get (Key: String): PObject;
  453. FUNCTION SwitchTo (AStream: PStream; Pack: Boolean): PStream;
  454. PROCEDURE Flush;
  455. PROCEDURE Delete (Key: String);
  456. PROCEDURE Put (Item: PObject; Key: String);
  457. PRIVATE
  458. BasePos: LongInt; { Base position }
  459. IndexPos: LongInt; { Index position }
  460. Index: TResourceCollection; { Index collection }
  461. END;
  462. PResourceFile = ^TResourceFile;
  463. TYPE
  464. TStrIndexRec = Packed RECORD
  465. Key : Sw_word;
  466. Count, Offset: Word;
  467. END;
  468. TStrIndex = Array [0..9999] Of TStrIndexRec;
  469. PStrIndex = ^TStrIndex;
  470. {---------------------------------------------------------------------------}
  471. { TStringList OBJECT - STRING LIST OBJECT }
  472. {---------------------------------------------------------------------------}
  473. TStringList = OBJECT (TObject)
  474. CONSTRUCTOR Load (Var S: TStream);
  475. DESTRUCTOR Done; Virtual;
  476. FUNCTION Get (Key: Sw_Word): String;
  477. PRIVATE
  478. Stream : PStream;
  479. BasePos : Longint;
  480. IndexSize: Longint;
  481. Index : PStrIndex;
  482. PROCEDURE ReadStr (Var S: String; Offset, Skip: Longint);
  483. END;
  484. PStringList = ^TStringList;
  485. {---------------------------------------------------------------------------}
  486. { TStrListMaker OBJECT - RESOURCE FILE OBJECT }
  487. {---------------------------------------------------------------------------}
  488. TYPE
  489. TStrListMaker = OBJECT (TObject)
  490. CONSTRUCTOR Init (AStrSize, AIndexSize: Sw_Word);
  491. DESTRUCTOR Done; Virtual;
  492. PROCEDURE Put (Key: Sw_Word; S: String);
  493. PROCEDURE Store (Var S: TStream);
  494. PRIVATE
  495. StrPos : Sw_Word;
  496. StrSize : Sw_Word;
  497. Strings : PByteArray;
  498. IndexPos : Sw_Word;
  499. IndexSize: Sw_Word;
  500. Index : PStrIndex;
  501. Cur : TStrIndexRec;
  502. PROCEDURE CloseCurrent;
  503. END;
  504. PStrListMaker = ^TStrListMaker;
  505. {***************************************************************************}
  506. { INTERFACE ROUTINES }
  507. {***************************************************************************}
  508. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  509. { CALL HELPERS INTERFACE ROUTINES }
  510. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  511. { Constructor calls.
  512. Ctor Pointer to the constructor.
  513. Obj Pointer to the instance. NIL if new instance to be allocated.
  514. VMT Pointer to the VMT (obtained by TypeOf()).
  515. returns Pointer to the instance.
  516. }
  517. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  518. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  519. { Method calls.
  520. Method Pointer to the method.
  521. Obj Pointer to the instance. NIL if new instance to be allocated.
  522. returns Pointer to the instance.
  523. }
  524. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  525. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  526. { Local-function/procedure calls.
  527. Func Pointer to the local function (which must be far-coded).
  528. Frame Frame pointer of the wrapping function.
  529. }
  530. function CallVoidLocal(Func: pointer; Frame: Pointer): pointer;
  531. function CallPointerLocal(Func: pointer; Frame: Pointer; Param1: pointer): pointer;
  532. { Calls of functions/procedures local to methods.
  533. Func Pointer to the local function (which must be far-coded).
  534. Frame Frame pointer of the wrapping method.
  535. Obj Pointer to the object that the method belongs to.
  536. }
  537. function CallVoidMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer): pointer;
  538. function CallPointerMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer; Param1: pointer): pointer;
  539. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  540. { DYNAMIC STRING INTERFACE ROUTINES }
  541. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  542. {-NewStr-------------------------------------------------------------
  543. Allocates a dynamic string into memory. If S is nil, NewStr returns
  544. a nil pointer, otherwise NewStr allocates Length(S)+1 bytes of memory
  545. containing a copy of S, and returns a pointer to the string.
  546. 12Jun96 LdB
  547. ---------------------------------------------------------------------}
  548. FUNCTION NewStr (Const S: String): PString;
  549. {-DisposeStr---------------------------------------------------------
  550. Disposes of a PString allocated by the function NewStr.
  551. 12Jun96 LdB
  552. ---------------------------------------------------------------------}
  553. PROCEDURE DisposeStr (P: PString);
  554. PROCEDURE SetStr(VAR p:pString; CONST s:STRING);
  555. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  556. { STREAM INTERFACE ROUTINES }
  557. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  558. {-Abstract-----------------------------------------------------------
  559. Terminates program with a run-time error 211. When implementing
  560. an abstract object type, call Abstract in those virtual methods that
  561. must be overridden in descendant types. This ensures that any
  562. attempt to use instances of the abstract object type will fail.
  563. 12Jun96 LdB
  564. ---------------------------------------------------------------------}
  565. PROCEDURE Abstract;
  566. {-RegisterObjects----------------------------------------------------
  567. Registers the three standard objects TCollection, TStringCollection
  568. and TStrCollection.
  569. 02Sep97 LdB
  570. ---------------------------------------------------------------------}
  571. PROCEDURE RegisterObjects;
  572. {-RegisterType-------------------------------------------------------
  573. Registers the given object type with Free Vision's streams, creating
  574. a list of known objects. Streams can only store and return these known
  575. object types. Each registered object needs a unique stream registration
  576. record, of type TStreamRec.
  577. 02Sep97 LdB
  578. ---------------------------------------------------------------------}
  579. PROCEDURE RegisterType (Var S: TStreamRec);
  580. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  581. { GENERAL FUNCTION INTERFACE ROUTINES }
  582. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  583. {-LongMul------------------------------------------------------------
  584. Returns the long integer value of X * Y integer values.
  585. 04Sep97 LdB
  586. ---------------------------------------------------------------------}
  587. FUNCTION LongMul (X, Y: Integer): LongInt;
  588. {-LongDiv------------------------------------------------------------
  589. Returns the integer value of long integer X divided by integer Y.
  590. 04Sep97 LdB
  591. ---------------------------------------------------------------------}
  592. FUNCTION LongDiv (X: Longint; Y: Integer): Integer;
  593. {***************************************************************************}
  594. { PUBLIC INITIALIZED VARIABLES }
  595. {***************************************************************************}
  596. CONST
  597. {---------------------------------------------------------------------------}
  598. { INITIALIZED DOS/DPMI/WIN/OS2 PUBLIC VARIABLES }
  599. {---------------------------------------------------------------------------}
  600. StreamError: Pointer = Nil; { Stream error ptr }
  601. DefaultTPCompatible: Boolean = false;
  602. {---------------------------------------------------------------------------}
  603. { STREAM REGISTRATION RECORDS }
  604. {---------------------------------------------------------------------------}
  605. CONST
  606. RCollection: TStreamRec = (
  607. ObjType: 50;
  608. VmtLink: Ofs(TypeOf(TCollection)^);
  609. Load: @TCollection.Load;
  610. Store: @TCollection.Store;
  611. Next: Nil);
  612. RStringCollection: TStreamRec = (
  613. ObjType: 51;
  614. VmtLink: Ofs(TypeOf(TStringCollection)^);
  615. Load: @TStringCollection.Load;
  616. Store: @TStringCollection.Store;
  617. Next: Nil);
  618. RStrCollection: TStreamRec = (
  619. ObjType: 69;
  620. VmtLink: Ofs(TypeOf(TStrCollection)^);
  621. Load: @TStrCollection.Load;
  622. Store: @TStrCollection.Store;
  623. Next: Nil);
  624. RStringList: TStreamRec = (
  625. ObjType: 52;
  626. VmtLink: Ofs(TypeOf(TStringList)^);
  627. Load: @TStringList.Load;
  628. Store: Nil;
  629. Next: Nil);
  630. RStrListMaker: TStreamRec = (
  631. ObjType: 52;
  632. VmtLink: Ofs(TypeOf(TStrListMaker)^);
  633. Load: Nil;
  634. Store: @TStrListMaker.Store;
  635. Next: Nil);
  636. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  637. IMPLEMENTATION
  638. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  639. Uses dos;
  640. {***************************************************************************}
  641. { HELPER ROUTINES FOR CALLING }
  642. {***************************************************************************}
  643. type
  644. VoidLocal = function(_EBP: Pointer): pointer;
  645. PointerLocal = function(_EBP: Pointer; Param1: pointer): pointer;
  646. VoidMethodLocal = function(_EBP: Pointer): pointer;
  647. PointerMethodLocal = function(_EBP: Pointer; Param1: pointer): pointer;
  648. VoidConstructor = function(VMT: pointer; Obj: pointer): pointer;
  649. PointerConstructor = function(VMT: pointer; Obj: pointer; Param1: pointer): pointer;
  650. VoidMethod = function(Obj: pointer): pointer;
  651. PointerMethod = function(Obj: pointer; Param1: pointer): pointer;
  652. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  653. begin
  654. {$ifdef VER1_0}
  655. asm
  656. {$ifdef cpui386}
  657. movl Obj, %esi
  658. {$endif}
  659. {$ifdef cpum68k}
  660. move.l Obj, a5
  661. {$endif}
  662. end;
  663. CallVoidConstructor := VoidConstructor(Ctor)(VMT, Obj);
  664. {$else}
  665. CallVoidConstructor := VoidConstructor(Ctor)(Obj, VMT);
  666. {$endif}
  667. end;
  668. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  669. {$undef FPC_CallPointerConstructor_Implemented}
  670. begin
  671. {$ifdef VER1_0}
  672. asm
  673. {$ifdef cpui386}
  674. {$define FPC_CallPointerConstructor_Implemented}
  675. movl Obj, %esi
  676. {$endif}
  677. {$ifdef cpum68k}
  678. {$define FPC_CallPointerConstructor_Implemented}
  679. move.l Obj, a5
  680. {$endif}
  681. end;
  682. CallPointerConstructor := PointerConstructor(Ctor)(VMT, Obj, Param1)
  683. {$else}
  684. { 1.1 does not esi to be loaded }
  685. {$define FPC_CallPointerConstructor_Implemented}
  686. CallPointerConstructor := PointerConstructor(Ctor)(Obj, VMT, Param1)
  687. {$endif}
  688. end;
  689. {$ifndef FPC_CallPointerConstructor_Implemented}
  690. {$error CallPointerConstructor function not implemented}
  691. {$endif not FPC_CallPointerConstructor_Implemented}
  692. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  693. begin
  694. {$ifdef VER1_0}
  695. { load the object pointer }
  696. {$ifdef CPUI386}
  697. asm
  698. movl Obj, %esi
  699. end;
  700. {$endif CPUI386}
  701. {$ifdef CPU68K}
  702. asm
  703. move.l Obj, a5
  704. end;
  705. {$endif CPU68K}
  706. {$endif VER1_0}
  707. CallVoidMethod := VoidMethod(Method)(Obj)
  708. end;
  709. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  710. {$undef FPC_CallPointerMethod_Implemented}
  711. begin
  712. {$ifdef VER1_0}
  713. asm
  714. {$ifdef cpui386}
  715. {$define FPC_CallPointerMethod_Implemented}
  716. movl Obj, %esi
  717. {$endif}
  718. {$ifdef cpum68k}
  719. {$define FPC_CallPointerMethod_Implemented}
  720. move.l Obj, a5
  721. {$endif}
  722. {$ifdef cpupowerpc}
  723. {$define FPC_CallPointerMethod_Implemented}
  724. { for the powerpc, we don't need to load self, because we use standard calling conventions
  725. so self should be in a register anyways }
  726. {$endif}
  727. end;
  728. {$else}
  729. { 1.1 does not esi to be loaded }
  730. {$define FPC_CallPointerMethod_Implemented}
  731. {$endif}
  732. CallPointerMethod := PointerMethod(Method)(Obj, Param1)
  733. end;
  734. {$ifndef FPC_CallPointerMethod_Implemented}
  735. {$error CallPointerMethod function not implemented}
  736. {$endif not FPC_CallPointerMethod_Implemented}
  737. function CallVoidLocal(Func: pointer; Frame: Pointer): pointer;
  738. begin
  739. CallVoidLocal := VoidLocal(Func)(Frame)
  740. end;
  741. function CallPointerLocal(Func: pointer; Frame: Pointer; Param1: pointer): pointer;
  742. begin
  743. CallPointerLocal := PointerLocal(Func)(Frame, Param1)
  744. end;
  745. function CallVoidMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer): pointer;
  746. begin
  747. {$ifdef VER1_0}
  748. { load the object pointer }
  749. {$ifdef CPUI386}
  750. asm
  751. movl Obj, %esi
  752. end;
  753. {$endif CPUI386}
  754. {$ifdef CPU68K}
  755. asm
  756. move.l Obj, a5
  757. end;
  758. {$endif CPU68K}
  759. {$endif VER1_0}
  760. CallVoidMethodLocal := VoidMethodLocal(Func)(Frame)
  761. end;
  762. function CallPointerMethodLocal(Func: pointer; Frame: Pointer; Obj: pointer; Param1: pointer): pointer;
  763. begin
  764. {$ifdef VER1_0}
  765. { load the object pointer }
  766. {$ifdef CPUI386}
  767. asm
  768. movl Obj, %esi
  769. end;
  770. {$endif CPUI386}
  771. {$ifdef CPU68K}
  772. asm
  773. move.l Obj, a5
  774. end;
  775. {$endif CPU68K}
  776. {$endif VER1_0}
  777. CallPointerMethodLocal := PointerMethodLocal(Func)(Frame, Param1)
  778. end;
  779. {***************************************************************************}
  780. { PRIVATE INITIALIZED VARIABLES }
  781. {***************************************************************************}
  782. {---------------------------------------------------------------------------}
  783. { INITIALIZED DOS/DPMI/WIN/OS2 PRIVATE VARIABLES }
  784. {---------------------------------------------------------------------------}
  785. CONST
  786. StreamTypes: PStreamRec = Nil; { Stream types reg }
  787. {***************************************************************************}
  788. { PRIVATE INTERNAL ROUTINES }
  789. {***************************************************************************}
  790. {---------------------------------------------------------------------------}
  791. { RegisterError -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 12Jun96 LdB }
  792. {---------------------------------------------------------------------------}
  793. PROCEDURE RegisterError;
  794. BEGIN
  795. RunError(212); { Register error }
  796. END;
  797. {***************************************************************************}
  798. { OBJECT METHODS }
  799. {***************************************************************************}
  800. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  801. { TRect OBJECT METHODS }
  802. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  803. PROCEDURE CheckEmpty (Var Rect: TRect);
  804. BEGIN
  805. With Rect Do Begin
  806. If (A.X >= B.X) OR (A.Y >= B.Y) Then Begin { Zero or reversed }
  807. A.X := 0; { Clear a.x }
  808. A.Y := 0; { Clear a.y }
  809. B.X := 0; { Clear b.x }
  810. B.Y := 0; { Clear b.y }
  811. End;
  812. End;
  813. END;
  814. {--TRect--------------------------------------------------------------------}
  815. { Empty -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  816. {---------------------------------------------------------------------------}
  817. FUNCTION TRect.Empty: Boolean;
  818. BEGIN
  819. Empty := (A.X >= B.X) OR (A.Y >= B.Y); { Empty result }
  820. END;
  821. {--TRect--------------------------------------------------------------------}
  822. { Equals -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  823. {---------------------------------------------------------------------------}
  824. FUNCTION TRect.Equals (R: TRect): Boolean;
  825. BEGIN
  826. Equals := (A.X = R.A.X) AND (A.Y = R.A.Y) AND
  827. (B.X = R.B.X) AND (B.Y = R.B.Y); { Equals result }
  828. END;
  829. {--TRect--------------------------------------------------------------------}
  830. { Contains -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  831. {---------------------------------------------------------------------------}
  832. FUNCTION TRect.Contains (P: TPoint): Boolean;
  833. BEGIN
  834. Contains := (P.X >= A.X) AND (P.X < B.X) AND
  835. (P.Y >= A.Y) AND (P.Y < B.Y); { Contains result }
  836. END;
  837. {--TRect--------------------------------------------------------------------}
  838. { Copy -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  839. {---------------------------------------------------------------------------}
  840. PROCEDURE TRect.Copy (R: TRect);
  841. BEGIN
  842. A := R.A; { Copy point a }
  843. B := R.B; { Copy point b }
  844. END;
  845. {--TRect--------------------------------------------------------------------}
  846. { Union -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  847. {---------------------------------------------------------------------------}
  848. PROCEDURE TRect.Union (R: TRect);
  849. BEGIN
  850. If (R.A.X < A.X) Then A.X := R.A.X; { Take if smaller }
  851. If (R.A.Y < A.Y) Then A.Y := R.A.Y; { Take if smaller }
  852. If (R.B.X > B.X) Then B.X := R.B.X; { Take if larger }
  853. If (R.B.Y > B.Y) Then B.Y := R.B.Y; { Take if larger }
  854. END;
  855. {--TRect--------------------------------------------------------------------}
  856. { Intersect -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  857. {---------------------------------------------------------------------------}
  858. PROCEDURE TRect.Intersect (R: TRect);
  859. BEGIN
  860. If (R.A.X > A.X) Then A.X := R.A.X; { Take if larger }
  861. If (R.A.Y > A.Y) Then A.Y := R.A.Y; { Take if larger }
  862. If (R.B.X < B.X) Then B.X := R.B.X; { Take if smaller }
  863. If (R.B.Y < B.Y) Then B.Y := R.B.Y; { Take if smaller }
  864. CheckEmpty(Self); { Check if empty }
  865. END;
  866. {--TRect--------------------------------------------------------------------}
  867. { Move -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  868. {---------------------------------------------------------------------------}
  869. PROCEDURE TRect.Move (ADX, ADY: Sw_Integer);
  870. BEGIN
  871. Inc(A.X, ADX); { Adjust A.X }
  872. Inc(A.Y, ADY); { Adjust A.Y }
  873. Inc(B.X, ADX); { Adjust B.X }
  874. Inc(B.Y, ADY); { Adjust B.Y }
  875. END;
  876. {--TRect--------------------------------------------------------------------}
  877. { Grow -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  878. {---------------------------------------------------------------------------}
  879. PROCEDURE TRect.Grow (ADX, ADY: Sw_Integer);
  880. BEGIN
  881. Dec(A.X, ADX); { Adjust A.X }
  882. Dec(A.Y, ADY); { Adjust A.Y }
  883. Inc(B.X, ADX); { Adjust B.X }
  884. Inc(B.Y, ADY); { Adjust B.Y }
  885. CheckEmpty(Self); { Check if empty }
  886. END;
  887. {--TRect--------------------------------------------------------------------}
  888. { Assign -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  889. {---------------------------------------------------------------------------}
  890. PROCEDURE TRect.Assign (XA, YA, XB, YB: Sw_Integer);
  891. BEGIN
  892. A.X := XA; { Hold A.X value }
  893. A.Y := YA; { Hold A.Y value }
  894. B.X := XB; { Hold B.X value }
  895. B.Y := YB; { Hold B.Y value }
  896. END;
  897. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  898. { TObject OBJECT METHODS }
  899. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  900. TYPE
  901. DummyObject = OBJECT (TObject) { Internal object }
  902. Data: RECORD END; { Helps size VMT link }
  903. END;
  904. { ******************************* REMARK ****************************** }
  905. { I Prefer this code because it self sizes VMT link rather than using a }
  906. { fixed record structure thus it should work on all compilers without a }
  907. { specific record to match each compiler. }
  908. { ****************************** END REMARK *** Leon de Boer, 10May96 * }
  909. {--TObject------------------------------------------------------------------}
  910. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  911. {---------------------------------------------------------------------------}
  912. CONSTRUCTOR TObject.Init;
  913. VAR LinkSize: LongInt; Dummy: DummyObject;
  914. BEGIN
  915. LinkSize := PtrInt(@Dummy.Data)-PtrInt(@Dummy); { Calc VMT link size }
  916. FillChar(Pointer(PtrInt(@Self)+LinkSize)^,
  917. SizeOf(Self)-LinkSize, #0); { Clear data fields }
  918. END;
  919. {--TObject------------------------------------------------------------------}
  920. { Free -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  921. {---------------------------------------------------------------------------}
  922. PROCEDURE TObject.Free;
  923. BEGIN
  924. Dispose(PObject(@Self), Done); { Dispose of self }
  925. END;
  926. {--TObject------------------------------------------------------------------}
  927. { Is_Object -> Platforms DOS/DPMI/WIN/OS2 - Checked 5Mar00 DM }
  928. {---------------------------------------------------------------------------}
  929. FUNCTION TObject.Is_Object(P:Pointer):Boolean;
  930. TYPE
  931. PVMT=^VMT;
  932. VMT=RECORD
  933. Size,NegSize:Longint;
  934. ParentLink:PVMT;
  935. END;
  936. VAR SP:^PVMT; Q:PVMT;
  937. BEGIN
  938. SP:=@SELF;
  939. Q:=SP^;
  940. Is_Object:=False;
  941. While Q<>Nil Do Begin
  942. IF Q=P THEN Begin
  943. Is_Object:=True;
  944. Break;
  945. End;
  946. Q:=Q^.Parentlink;
  947. End;
  948. END;
  949. {--TObject------------------------------------------------------------------}
  950. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  951. {---------------------------------------------------------------------------}
  952. DESTRUCTOR TObject.Done;
  953. BEGIN { Abstract method }
  954. END;
  955. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  956. { TStream OBJECT METHODS }
  957. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  958. CONSTRUCTOR TStream.Init;
  959. BEGIN
  960. Status := StOK;
  961. ErrorInfo := 0;
  962. StreamSize := 0;
  963. Position := 0;
  964. TPCompatible := DefaultTPCompatible;
  965. END;
  966. {--TStream------------------------------------------------------------------}
  967. { Get -> Platforms DOS/DPMI/WIN/OS2 - Checked 02Sep97 LdB }
  968. {---------------------------------------------------------------------------}
  969. FUNCTION TStream.Get: PObject;
  970. VAR ObjType: Sw_Word; P: PStreamRec; ObjTypeWord: Word;
  971. BEGIN
  972. If TPCompatible Then Begin
  973. { Read 16-bit word for TP compatibility. }
  974. Read(ObjTypeWord, SizeOf(ObjTypeWord));
  975. ObjType := ObjTypeWord
  976. End
  977. else
  978. Read(ObjType, SizeOf(ObjType)); { Read object type }
  979. If (ObjType<>0) Then Begin { Object registered }
  980. P := StreamTypes; { Current reg list }
  981. While (P <> Nil) AND (P^.ObjType <> ObjType) { Find object type OR }
  982. Do P := P^.Next; { Find end of chain }
  983. If (P=Nil) Then Begin { Not registered }
  984. Error(stGetError, ObjType); { Obj not registered }
  985. Get := Nil; { Return nil pointer }
  986. End Else
  987. Get :=PObject(
  988. CallPointerConstructor(P^.Load,Nil,P^.VMTLink, @Self)) { Call constructor }
  989. End Else Get := Nil; { Return nil pointer }
  990. END;
  991. {--TStream------------------------------------------------------------------}
  992. { StrRead -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  993. {---------------------------------------------------------------------------}
  994. FUNCTION TStream.StrRead: PChar;
  995. VAR L: Word; P: PChar;
  996. BEGIN
  997. Read(L, SizeOf(L)); { Read length }
  998. If (L = 0) Then StrRead := Nil Else Begin { Check for empty }
  999. GetMem(P, L + 1); { Allocate memory }
  1000. If (P <> Nil) Then Begin { Check allocate okay }
  1001. Read(P[0], L); { Read the data }
  1002. P[L] := #0; { Terminate with #0 }
  1003. End;
  1004. StrRead := P; { Return PChar }
  1005. End;
  1006. END;
  1007. {--TStream------------------------------------------------------------------}
  1008. { ReadStr -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1009. {---------------------------------------------------------------------------}
  1010. FUNCTION TStream.ReadStr: PString;
  1011. VAR L: Byte; P: PString;
  1012. BEGIN
  1013. Read(L, 1); { Read string length }
  1014. If (L > 0) Then Begin
  1015. GetMem(P, L + 1); { Allocate memory }
  1016. If (P <> Nil) Then Begin { Check allocate okay }
  1017. P^[0] := Char(L); { Hold length }
  1018. Read(P^[1], L); { Read string data }
  1019. End;
  1020. ReadStr := P; { Return string ptr }
  1021. End Else ReadStr := Nil;
  1022. END;
  1023. {--TStream------------------------------------------------------------------}
  1024. { GetPos -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1025. {---------------------------------------------------------------------------}
  1026. FUNCTION TStream.GetPos: LongInt;
  1027. BEGIN
  1028. If (Status=stOk) Then GetPos := Position { Return position }
  1029. Else GetPos := -1; { Stream in error }
  1030. END;
  1031. {--TStream------------------------------------------------------------------}
  1032. { GetSize -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1033. {---------------------------------------------------------------------------}
  1034. FUNCTION TStream.GetSize: LongInt;
  1035. BEGIN
  1036. If (Status=stOk) Then GetSize := StreamSize { Return stream size }
  1037. Else GetSize := -1; { Stream in error }
  1038. END;
  1039. {--TStream------------------------------------------------------------------}
  1040. { Close -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1041. {---------------------------------------------------------------------------}
  1042. PROCEDURE TStream.Close;
  1043. BEGIN { Abstract method }
  1044. END;
  1045. {--TStream------------------------------------------------------------------}
  1046. { Reset -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1047. {---------------------------------------------------------------------------}
  1048. PROCEDURE TStream.Reset;
  1049. BEGIN
  1050. Status := stOK; { Clear status }
  1051. ErrorInfo := 0; { Clear error info }
  1052. END;
  1053. {--TStream------------------------------------------------------------------}
  1054. { Flush -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1055. {---------------------------------------------------------------------------}
  1056. PROCEDURE TStream.Flush;
  1057. BEGIN { Abstract method }
  1058. END;
  1059. {--TStream------------------------------------------------------------------}
  1060. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1061. {---------------------------------------------------------------------------}
  1062. PROCEDURE TStream.Truncate;
  1063. BEGIN
  1064. Abstract; { Abstract error }
  1065. END;
  1066. {--TStream------------------------------------------------------------------}
  1067. { Put -> Platforms DOS/DPMI/WIN/OS2 - Checked 02Sep97 LdB }
  1068. {---------------------------------------------------------------------------}
  1069. PROCEDURE TStream.Put (P: PObject);
  1070. VAR ObjType: Sw_Word; Link: pointer; Q: PStreamRec; VmtPtr: ^pointer;
  1071. ObjTypeWord: Word;
  1072. BEGIN
  1073. VmtPtr := Pointer(P); { Xfer object to ptr }
  1074. if assigned(vmtptr) then
  1075. Link := VmtPtr^ { VMT link }
  1076. else
  1077. Link:=nil;
  1078. ObjType := 0; { Set objtype to zero }
  1079. If (P<>Nil) AND (Link<>Nil) Then Begin { We have a VMT link }
  1080. Q := StreamTypes; { Current reg list }
  1081. While (Q <> Nil) AND (Q^.VMTLink <> Link) { Find link match OR }
  1082. Do Q := Q^.Next; { Find end of chain }
  1083. If (Q=Nil) Then Begin { End of chain found }
  1084. Error(stPutError, 0); { Not registered error }
  1085. Exit; { Now exit }
  1086. End Else ObjType := Q^.ObjType; { Update object type }
  1087. End;
  1088. If TPCompatible Then Begin
  1089. ObjTypeWord := word(ObjType);
  1090. Write(ObjTypeWord, SizeOf(ObjTypeWord))
  1091. end
  1092. else
  1093. Write(ObjType, SizeOf(ObjType)); { Write object type }
  1094. If (ObjType<>0) Then { Registered object }
  1095. CallPointerMethod(Q^.Store, P, @Self);
  1096. END;
  1097. {--TStream------------------------------------------------------------------}
  1098. { Seek -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1099. {---------------------------------------------------------------------------}
  1100. PROCEDURE TStream.Seek (Pos: LongInt);
  1101. BEGIN
  1102. If (Status = stOk) Then Begin { Check status }
  1103. If (Pos < 0) Then Pos := 0; { Remove negatives }
  1104. If (Pos <= StreamSize) Then Position := Pos { If valid set pos }
  1105. Else Error(stSeekError, Pos); { Position error }
  1106. End;
  1107. END;
  1108. {--TStream------------------------------------------------------------------}
  1109. { StrWrite -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1110. {---------------------------------------------------------------------------}
  1111. PROCEDURE TStream.StrWrite (P: PChar);
  1112. VAR L: Word; Q: PByteArray;
  1113. BEGIN
  1114. L := 0; { Preset zero size }
  1115. Q := PByteArray(P); { Transfer type }
  1116. If (Q <> Nil) Then While (Q^[L] <> 0) Do Inc(L); { PChar length }
  1117. Write(L, SizeOf(L)); { Store length }
  1118. If (P <> Nil) Then Write(P[0], L); { Write data }
  1119. END;
  1120. {--TStream------------------------------------------------------------------}
  1121. { WriteStr -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1122. {---------------------------------------------------------------------------}
  1123. PROCEDURE TStream.WriteStr (P: PString);
  1124. CONST Empty: String[1] = '';
  1125. BEGIN
  1126. If (P <> Nil) Then Write(P^, Length(P^) + 1) { Write string }
  1127. Else Write(Empty, 1); { Write empty string }
  1128. END;
  1129. {--TStream------------------------------------------------------------------}
  1130. { Open -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1131. {---------------------------------------------------------------------------}
  1132. PROCEDURE TStream.Open (OpenMode: Word);
  1133. BEGIN { Abstract method }
  1134. END;
  1135. {--TStream------------------------------------------------------------------}
  1136. { Error -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1137. {---------------------------------------------------------------------------}
  1138. PROCEDURE TStream.Error (Code, Info: Integer);
  1139. TYPE TErrorProc = Procedure(Var S: TStream);
  1140. BEGIN
  1141. Status := Code; { Hold error code }
  1142. ErrorInfo := Info; { Hold error info }
  1143. If (StreamError <> Nil) Then
  1144. TErrorProc(StreamError)(Self); { Call error ptr }
  1145. END;
  1146. {--TStream------------------------------------------------------------------}
  1147. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1148. {---------------------------------------------------------------------------}
  1149. PROCEDURE TStream.Read (Var Buf; Count: Longint);
  1150. BEGIN
  1151. Abstract; { Abstract error }
  1152. END;
  1153. {--TStream------------------------------------------------------------------}
  1154. { Write -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1155. {---------------------------------------------------------------------------}
  1156. PROCEDURE TStream.Write (Var Buf; Count: Longint);
  1157. BEGIN
  1158. Abstract; { Abstract error }
  1159. END;
  1160. {--TStream------------------------------------------------------------------}
  1161. { CopyFrom -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB }
  1162. {---------------------------------------------------------------------------}
  1163. PROCEDURE TStream.CopyFrom (Var S: TStream; Count: Longint);
  1164. VAR W: Word; Buffer: Array[0..1023] of Byte;
  1165. BEGIN
  1166. While (Count > 0) Do Begin
  1167. If (Count > SizeOf(Buffer)) Then { To much data }
  1168. W := SizeOf(Buffer) Else W := Count; { Size to transfer }
  1169. S.Read(Buffer, W); { Read from stream }
  1170. Write(Buffer, W); { Write to stream }
  1171. Dec(Count, W); { Dec write count }
  1172. End;
  1173. END;
  1174. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1175. { TDosStream OBJECT METHODS }
  1176. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1177. {$IFOPT I+}
  1178. {$DEFINE IO_CHECK_ON}
  1179. {$I-}
  1180. {$ENDIF}
  1181. {--TDosStream---------------------------------------------------------------}
  1182. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1183. {---------------------------------------------------------------------------}
  1184. CONSTRUCTOR TDosStream.Init (FileName: FNameStr; Mode: Word);
  1185. VAR OldFileMode : Byte;
  1186. DosStreamError : Word;
  1187. BEGIN
  1188. Inherited Init; { Call ancestor }
  1189. FileName := FileName+#0; { Make asciiz }
  1190. Move(FileName[1], FName, Length(FileName)); { Create asciiz name }
  1191. Handle := InvalidHandle;
  1192. Assign(FileInfo,FileName);
  1193. { Handle the mode }
  1194. if Mode =stCreate then
  1195. Begin
  1196. Rewrite(FileInfo,1);
  1197. end
  1198. else
  1199. Begin
  1200. OldFileMode := FileMode;
  1201. { Keep sharing modes! }
  1202. FileMode := Mode and $FF;
  1203. System.Reset(FileInfo,1);
  1204. FileMode := OldFileMode;
  1205. { To use the correct mode we must reclose the file
  1206. and open it again
  1207. }
  1208. end;
  1209. Handle := FileRec(FileInfo).Handle; { Set handle value }
  1210. DosStreamError := IOResult;
  1211. If DosStreamError = 0 then
  1212. Begin
  1213. StreamSize := System.FileSize(FileInfo);
  1214. end;
  1215. If DosStreamError = 0 then
  1216. DosStreamError := IOResult;
  1217. If (DosStreamError <> 0) Then
  1218. Error(stInitError, DosStreamError) { Call stream error }
  1219. else
  1220. Status := StOK;
  1221. END;
  1222. {--TDosStream---------------------------------------------------------------}
  1223. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1224. {---------------------------------------------------------------------------}
  1225. DESTRUCTOR TDosStream.Done;
  1226. var
  1227. DosStreamError : Word;
  1228. BEGIN
  1229. if Handle <> InvalidHandle then
  1230. Begin
  1231. System.Close(FileInfo);
  1232. DosStreamError := IOResult;
  1233. If DosStreamError = 0 then
  1234. Status := stOk
  1235. else
  1236. Error(stError, DosStreamError);
  1237. end;
  1238. Position := 0; { Zero the position }
  1239. Handle := InvalidHandle;
  1240. Inherited Done; { Call ancestor }
  1241. END;
  1242. {--TDosStream---------------------------------------------------------------}
  1243. { Close -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1244. {---------------------------------------------------------------------------}
  1245. PROCEDURE TDosStream.Close;
  1246. var
  1247. DosStreamError : Word;
  1248. BEGIN
  1249. if Handle <> InvalidHandle then { Is file closed ? }
  1250. Begin
  1251. System.Close(FileInfo); { Close file }
  1252. DosStreamError := IOResult; { Check for error }
  1253. If DosStreamError = 0 then
  1254. Status := stOk
  1255. else
  1256. Error(stError, DosStreamError); { Call error routine }
  1257. end;
  1258. Position := 0; { Zero the position }
  1259. Handle := InvalidHandle; { Handle invalid }
  1260. END;
  1261. {--TDosStream---------------------------------------------------------------}
  1262. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1263. {---------------------------------------------------------------------------}
  1264. PROCEDURE TDosStream.Truncate;
  1265. var
  1266. DosStreamError : Word;
  1267. BEGIN
  1268. If Status = stOk then
  1269. Begin
  1270. System.Truncate(FileInfo);
  1271. DosStreamError := IOResult;
  1272. If DosStreamError = 0 then
  1273. { Status is already = stOK }
  1274. StreamSize := Position
  1275. else
  1276. Error(stError, DosStreamError);
  1277. end;
  1278. END;
  1279. {--TDosStream---------------------------------------------------------------}
  1280. { Seek -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1281. {---------------------------------------------------------------------------}
  1282. PROCEDURE TDosStream.Seek (Pos: Longint);
  1283. var
  1284. DosStreamError : Word;
  1285. BEGIN
  1286. If (Status=stOk) Then
  1287. Begin { Check status okay }
  1288. If (Pos < 0) Then
  1289. Pos := 0; { Negatives removed }
  1290. System.Seek(FileInfo, Pos);
  1291. DosStreamError := IOResult;
  1292. if DosStreamError <> 0 then
  1293. Error(stSeekError, DosStreamError){ Specific seek error }
  1294. Else Position := Pos; { Adjust position }
  1295. { Status is already = stOK }
  1296. End;
  1297. END;
  1298. {--TDosStream---------------------------------------------------------------}
  1299. { Open -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1300. {---------------------------------------------------------------------------}
  1301. PROCEDURE TDosStream.Open (OpenMode: Word);
  1302. VAR OldFileMode : Byte;
  1303. DosStreamError : Word;
  1304. BEGIN
  1305. If (Status=stOk) Then
  1306. Begin { Check status okay }
  1307. If (Handle = InvalidHandle) Then
  1308. Begin { File not open }
  1309. Assign(FileInfo,FName);
  1310. { Handle the mode }
  1311. if OpenMode =stCreate then
  1312. Begin
  1313. System.Rewrite(FileInfo,1);
  1314. end
  1315. else
  1316. Begin
  1317. OldFileMode := FileMode;
  1318. FileMode := OpenMode and 3;
  1319. System.Reset(FileInfo,1);
  1320. FileMode := OldFileMode;
  1321. { To use the correct mode we must reclose the file
  1322. and open it again
  1323. }
  1324. end;
  1325. Handle := FileRec(FileInfo).Handle; { Set handle value }
  1326. DosStreamError := IOResult;
  1327. If DosStreamError = 0 then
  1328. StreamSize := System.FileSize(FileInfo);
  1329. If DosStreamError = 0 then
  1330. DosStreamError := IOResult;
  1331. If (DosStreamError <> 0) Then
  1332. Error(stOpenError, DosStreamError) { Call stream error }
  1333. else
  1334. Status := StOK;
  1335. Position := 0;
  1336. end
  1337. Else
  1338. Error(stOpenError, 104); { File already open }
  1339. End;
  1340. END;
  1341. {--TDosStream---------------------------------------------------------------}
  1342. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1343. {---------------------------------------------------------------------------}
  1344. PROCEDURE TDosStream.Read (Var Buf; Count: Longint);
  1345. VAR BytesMoved: Longint;
  1346. DosStreamError : Word;
  1347. BEGIN
  1348. If Status = StOK then
  1349. Begin
  1350. If (Position + Count > StreamSize) Then { Insufficient data }
  1351. Error(stReadError, 0); { Read beyond end!!! }
  1352. If (Handle = InvalidHandle) Then
  1353. Error(stReadError, 103); { File not open }
  1354. BlockRead(FileInfo, Buf, Count, BytesMoved); { Read from file }
  1355. DosStreamError := IOResult;
  1356. If ((DosStreamError<>0) OR (BytesMoved<>Count)) Then
  1357. Begin { Error was detected }
  1358. BytesMoved := 0; { Clear bytes moved }
  1359. If (DosStreamError <> 0) Then
  1360. Error(stReadError, DosStreamError) { Specific read error }
  1361. Else
  1362. Error(stReadError, 0); { Non specific error }
  1363. End;
  1364. Inc(Position, BytesMoved); { Adjust position }
  1365. End;
  1366. { If there was already an error, or an error was just
  1367. generated, fill the vuffer with NULL
  1368. }
  1369. If Status <> StOK then
  1370. FillChar(Buf, Count, #0); { Error clear buffer }
  1371. END;
  1372. {--TDosStream---------------------------------------------------------------}
  1373. { Write -> Platforms DOS/DPMI/WIN/OS2 - Checked 16May96 LdB }
  1374. {---------------------------------------------------------------------------}
  1375. PROCEDURE TDosStream.Write (Var Buf; Count: Longint);
  1376. VAR BytesMoved: Longint;
  1377. DosStreamError : Word;
  1378. BEGIN
  1379. { If status is not OK, simply exit }
  1380. if Status <> StOK then
  1381. exit;
  1382. If (Handle = InvalidHandle) Then
  1383. Error(stWriteError, 103); { File not open }
  1384. BlockWrite(FileInfo, Buf, Count, BytesMoved); { Write to file }
  1385. DosStreamError := IOResult;
  1386. If ((DosStreamError<>0) OR (BytesMoved<>Count)) Then
  1387. Begin { Error was detected }
  1388. BytesMoved := 0; { Clear bytes moved }
  1389. If (DosStreamError<>0) Then
  1390. Error(stWriteError, DOSStreamError) { Specific write error }
  1391. Else
  1392. Error(stWriteError, 0); { Non specific error }
  1393. End;
  1394. Inc(Position, BytesMoved); { Adjust position }
  1395. If (Position > StreamSize) Then { File expanded }
  1396. StreamSize := Position; { Adjust stream size }
  1397. END;
  1398. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1399. { TBufStream OBJECT METHODS }
  1400. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1401. {--TBufStream---------------------------------------------------------------}
  1402. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1403. {---------------------------------------------------------------------------}
  1404. CONSTRUCTOR TBufStream.Init (FileName: FNameStr; Mode, Size: Word);
  1405. BEGIN
  1406. Inherited Init(FileName, Mode); { Call ancestor }
  1407. BufSize := Size; { Hold buffer size }
  1408. If (Size<>0) Then GetMem(Buffer, Size); { Allocate buffer }
  1409. If (Buffer=Nil) Then Error(stInitError, 0); { Buffer allocate fail }
  1410. END;
  1411. {--TBufStream---------------------------------------------------------------}
  1412. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1413. {---------------------------------------------------------------------------}
  1414. DESTRUCTOR TBufStream.Done;
  1415. BEGIN
  1416. Flush; { Flush the file }
  1417. Inherited Done; { Call ancestor }
  1418. If (Buffer<>Nil) Then FreeMem(Buffer, BufSize); { Release buffer }
  1419. END;
  1420. {--TBufStream---------------------------------------------------------------}
  1421. { Close -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1422. {---------------------------------------------------------------------------}
  1423. PROCEDURE TBufStream.Close;
  1424. BEGIN
  1425. Flush; { Flush the buffer }
  1426. Inherited Close; { Call ancestor }
  1427. END;
  1428. {--TBufStream---------------------------------------------------------------}
  1429. { Flush -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1430. {---------------------------------------------------------------------------}
  1431. PROCEDURE TBufStream.Flush;
  1432. VAR W: Longint;
  1433. DosStreamError : Word;
  1434. BEGIN
  1435. If Status <> StOK then
  1436. exit;
  1437. If (LastMode=2) AND (BufPtr<>0) Then Begin { Must update file }
  1438. If (Handle = InvalidHandle) Then DosStreamError := 103 { File is not open }
  1439. Else
  1440. Begin
  1441. BlockWrite(FileInfo, Buffer^,BufPtr, W); { Write to file }
  1442. DosStreamError := IOResult;
  1443. End;
  1444. If (DosStreamError<>0) OR (W<>BufPtr) Then { We have an error }
  1445. If (DosStreamError=0) Then Error(stWriteError, 0){ Unknown write error }
  1446. Else Error(stError, DosStreamError); { Specific write error }
  1447. End;
  1448. BufPtr := 0; { Reset buffer ptr }
  1449. BufEnd := 0; { Reset buffer end }
  1450. END;
  1451. {--TBufStream---------------------------------------------------------------}
  1452. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1453. {---------------------------------------------------------------------------}
  1454. PROCEDURE TBufStream.Truncate;
  1455. BEGIN
  1456. Flush; { Flush buffer }
  1457. Inherited Truncate; { Truncate file }
  1458. END;
  1459. {--TBufStream---------------------------------------------------------------}
  1460. { Seek -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1461. {---------------------------------------------------------------------------}
  1462. PROCEDURE TBufStream.Seek (Pos: LongInt);
  1463. BEGIN
  1464. If (Status=stOk) Then Begin { Check status okay }
  1465. If (Position<>Pos) Then Begin { Move required }
  1466. Flush; { Flush the buffer }
  1467. Inherited Seek(Pos); { Call ancestor }
  1468. End;
  1469. End;
  1470. END;
  1471. {--TBufStream---------------------------------------------------------------}
  1472. { Open -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1473. {---------------------------------------------------------------------------}
  1474. PROCEDURE TBufStream.Open (OpenMode: Word);
  1475. BEGIN
  1476. If (Status=stOk) Then Begin { Check status okay }
  1477. BufPtr := 0; { Clear buffer start }
  1478. BufEnd := 0; { Clear buffer end }
  1479. Inherited Open(OpenMode); { Call ancestor }
  1480. End;
  1481. END;
  1482. {--TBufStream---------------------------------------------------------------}
  1483. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1484. {---------------------------------------------------------------------------}
  1485. PROCEDURE TBufStream.Read (Var Buf; Count: Longint);
  1486. VAR W, Bw: Longint; P: PByte;
  1487. DosStreamError : Word;
  1488. BEGIN
  1489. If Status <> StOk then
  1490. begin
  1491. FillChar(Buf, Count, #0); { Error clear buffer }
  1492. exit;
  1493. end;
  1494. If (Position + Count > StreamSize) Then { Read pas stream end }
  1495. Error(stReadError, 0); { Call stream error }
  1496. If (Handle = InvalidHandle) Then Error(stReadError, 103); { File not open }
  1497. P := @Buf; { Transfer address }
  1498. If (LastMode=2) Then Flush; { Flush write buffer }
  1499. LastMode := 1; { Now set read mode }
  1500. While (Count>0) AND (Status=stOk) Do Begin { Check status & count }
  1501. If (BufPtr=BufEnd) Then Begin { Buffer is empty }
  1502. If (Position + BufSize > StreamSize) Then
  1503. Bw := StreamSize - Position { Amount of file left }
  1504. Else Bw := BufSize; { Full buffer size }
  1505. BlockRead(FileInfo, Buffer^, Bw, W);
  1506. DosStreamError := IOResult; { Read from file }
  1507. If ((DosStreamError<>0) OR (Bw<>W)) Then Begin { Error was detected }
  1508. If (DosStreamError<>0) Then
  1509. Error(stReadError, DosStreamError) { Specific read error }
  1510. Else Error(stReadError, 0); { Non specific error }
  1511. End Else Begin
  1512. BufPtr := 0; { Reset BufPtr }
  1513. BufEnd := W; { End of buffer }
  1514. End;
  1515. End;
  1516. If (Status=stOk) Then Begin { Status still okay }
  1517. W := BufEnd - BufPtr; { Space in buffer }
  1518. If (Count < W) Then W := Count; { Set transfer size }
  1519. Move(Buffer^[BufPtr], P^, W); { Data from buffer }
  1520. Dec(Count, W); { Reduce count }
  1521. Inc(BufPtr, W); { Advance buffer ptr }
  1522. Inc(P, W); { Transfer address }
  1523. Inc(Position, W); { Advance position }
  1524. End;
  1525. End;
  1526. If (Status<>stOk) AND (Count>0) Then
  1527. FillChar(P^, Count, #0); { Error clear buffer }
  1528. END;
  1529. {--TBufStream---------------------------------------------------------------}
  1530. { Write -> Platforms DOS/DPMI/WIN/OS2 - Checked 17May96 LdB }
  1531. {---------------------------------------------------------------------------}
  1532. PROCEDURE TBufStream.Write (Var Buf; Count: Longint);
  1533. VAR W: Longint;
  1534. P: PByte;
  1535. DosStreamError : Word;
  1536. BEGIN
  1537. if Status <> StOK then exit; { Exit if error }
  1538. If (Handle = InvalidHandle) Then Error(stWriteError, 103); { File not open }
  1539. If (LastMode=1) Then Flush; { Flush read buffer }
  1540. LastMode := 2; { Now set write mode }
  1541. P := @Buf; { Transfer address }
  1542. While (Count>0) AND (Status=stOk) Do Begin { Check status & count }
  1543. If (BufPtr=BufSize) Then Begin { Buffer is full }
  1544. BlockWrite(FileInfo, Buffer^, BufSize,W); { Write to file }
  1545. DosStreamError := IOResult;
  1546. If (DosStreamError<>0) OR (W<>BufSize) Then { We have an error }
  1547. If (DosStreamError=0) Then Error(stWriteError, 0) { Unknown write error }
  1548. Else Error(stError, DosStreamError); { Specific write error }
  1549. BufPtr := 0; { Reset BufPtr }
  1550. End;
  1551. If (Status=stOk) Then Begin { Status still okay }
  1552. W := BufSize - BufPtr; { Space in buffer }
  1553. If (Count < W) Then W := Count; { Transfer size }
  1554. Move(P^, Buffer^[BufPtr], W); { Data to buffer }
  1555. Dec(Count, W); { Reduce count }
  1556. Inc(BufPtr, W); { Advance buffer ptr }
  1557. Inc(P,W); { Transfer address }
  1558. Inc(Position, W); { Advance position }
  1559. If (Position > StreamSize) Then { File has expanded }
  1560. StreamSize := Position; { Update new size }
  1561. End;
  1562. End;
  1563. END;
  1564. {$IFDEF IO_CHECK_ON}
  1565. {$UNDEF IO_CHECK_ON}
  1566. {$I+}
  1567. {$ENDIF}
  1568. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1569. { TMemoryStream OBJECT METHODS }
  1570. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1571. {--TMemoryStream------------------------------------------------------------}
  1572. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1573. {---------------------------------------------------------------------------}
  1574. CONSTRUCTOR TMemoryStream.Init (ALimit: LongInt; ABlockSize: Word);
  1575. VAR W: Word;
  1576. BEGIN
  1577. Inherited Init; { Call ancestor }
  1578. If (ABlockSize=0) Then BlkSize := 8192 Else { Default blocksize }
  1579. BlkSize := ABlockSize; { Set blocksize }
  1580. If (ALimit = 0) Then W := 1 Else { At least 1 block }
  1581. W := (ALimit + BlkSize - 1) DIV BlkSize; { Blocks needed }
  1582. If NOT ChangeListSize(W) Then { Try allocate blocks }
  1583. Error(stInitError, 0); { Initialize error }
  1584. END;
  1585. {--TMemoryStream------------------------------------------------------------}
  1586. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1587. {---------------------------------------------------------------------------}
  1588. DESTRUCTOR TMemoryStream.Done;
  1589. BEGIN
  1590. ChangeListSize(0); { Release all memory }
  1591. Inherited Done; { Call ancestor }
  1592. END;
  1593. {--TMemoryStream------------------------------------------------------------}
  1594. { Truncate -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1595. {---------------------------------------------------------------------------}
  1596. PROCEDURE TMemoryStream.Truncate;
  1597. VAR W: Word;
  1598. BEGIN
  1599. If (Status=stOk) Then Begin { Check status okay }
  1600. If (Position = 0) Then W := 1 Else { At least one block }
  1601. W := (Position + BlkSize - 1) DIV BlkSize; { Blocks needed }
  1602. If ChangeListSize(W) Then StreamSize := Position { Set stream size }
  1603. Else Error(stError, 0); { Error truncating }
  1604. End;
  1605. END;
  1606. {--TMemoryStream------------------------------------------------------------}
  1607. { Read -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1608. {---------------------------------------------------------------------------}
  1609. PROCEDURE TMemoryStream.Read (Var Buf; Count: Longint);
  1610. VAR W, CurBlock, BlockPos: Word; Li: LongInt; P, Q: PByte;
  1611. BEGIN
  1612. If (Position + Count > StreamSize) Then { Insufficient data }
  1613. Error(stReadError, 0); { Read beyond end!!! }
  1614. P := @Buf; { Transfer address }
  1615. While (Count>0) AND (Status=stOk) Do Begin { Check status & count }
  1616. CurBlock := Position DIV BlkSize; { Current block }
  1617. { * REMARK * - Do not shorten this, result can be > 64K }
  1618. Li := CurBlock; { Transfer current block }
  1619. Li := Li * BlkSize; { Current position }
  1620. { * REMARK END * - Leon de Boer }
  1621. BlockPos := Position - Li; { Current position }
  1622. W := BlkSize - BlockPos; { Current block space }
  1623. If (W > Count) Then W := Count; { Adjust read size }
  1624. Q := BlkList^[CurBlock] + BlockPos; { Calc pointer }
  1625. Move(Q^, P^, W); { Move data to buffer }
  1626. Inc(Position, W); { Adjust position }
  1627. Inc(P, W);
  1628. Dec(Count, W); { Adjust count left }
  1629. End;
  1630. If (Count<>0) Then FillChar(P^, Count, #0); { Error clear buffer }
  1631. END;
  1632. {--TMemoryStream------------------------------------------------------------}
  1633. { Write -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1634. {---------------------------------------------------------------------------}
  1635. PROCEDURE TMemoryStream.Write (Var Buf; Count: Longint);
  1636. VAR
  1637. W, CurBlock, BlockPos: Word;
  1638. Li: LongInt;
  1639. P, Q: PByte;
  1640. BEGIN
  1641. If (Position + Count > MemSize) Then Begin { Expansion needed }
  1642. If (Position + Count = 0) Then W := 1 Else { At least 1 block }
  1643. W := (Position+Count+BlkSize-1) DIV BlkSize; { Blocks needed }
  1644. If NOT ChangeListSize(W) Then
  1645. Error(stWriteError, 0); { Expansion failed!!! }
  1646. End;
  1647. P := @Buf; { Transfer address }
  1648. While (Count>0) AND (Status=stOk) Do Begin { Check status & count }
  1649. CurBlock := Position DIV BlkSize; { Current segment }
  1650. { * REMARK * - Do not shorten this, result can be > 64K }
  1651. Li := CurBlock; { Transfer current block }
  1652. Li := Li * BlkSize; { Current position }
  1653. { * REMARK END * - Leon de Boer }
  1654. BlockPos := Position - Li; { Current position }
  1655. W := BlkSize - BlockPos; { Current block space }
  1656. If (W > Count) Then W := Count; { Adjust write size }
  1657. Q := BlkList^[CurBlock] + BlockPos; { Calc pointer }
  1658. Move(P^, Q^, W); { Transfer data }
  1659. Inc(Position, W); { Adjust position }
  1660. Inc(P, W);
  1661. Dec(Count, W); { Adjust count left }
  1662. If (Position > StreamSize) Then { File expanded }
  1663. StreamSize := Position; { Adjust stream size }
  1664. End;
  1665. END;
  1666. {***************************************************************************}
  1667. { TMemoryStream PRIVATE METHODS }
  1668. {***************************************************************************}
  1669. {--TMemoryStream------------------------------------------------------------}
  1670. { ChangeListSize -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB }
  1671. {---------------------------------------------------------------------------}
  1672. FUNCTION TMemoryStream.ChangeListSize (ALimit: Longint): Boolean;
  1673. VAR
  1674. I, W: Longint;
  1675. Li: LongInt;
  1676. P: PPointerArray;
  1677. BEGIN
  1678. If (ALimit <> BlkCount) Then Begin { Change is needed }
  1679. ChangeListSize := False; { Preset failure }
  1680. If (ALimit > MaxPtrs) Then Exit; { To many blocks req }
  1681. If (ALimit <> 0) Then Begin { Create segment list }
  1682. Li := ALimit * SizeOf(Pointer); { Block array size }
  1683. If (MaxAvail > Li) Then Begin
  1684. GetMem(P, Li); { Allocate memory }
  1685. FillChar(P^, Li, #0); { Clear the memory }
  1686. End Else Begin
  1687. GetMem(P,Li);
  1688. If P = Nil Then Exit;
  1689. FillChar(P^, Li, #0); { Clear the memory }
  1690. End; { Insufficient memory }
  1691. If (BlkCount <> 0) AND (BlkList <> Nil) Then { Current list valid }
  1692. If (BlkCount <= ALimit) Then Move(BlkList^,
  1693. P^, BlkCount * SizeOf(Pointer)) Else { Move whole old list }
  1694. Move(BlkList^, P^, Li); { Move partial list }
  1695. End Else P := Nil; { No new block list }
  1696. If (ALimit < BlkCount) Then { Shrink stream size }
  1697. For W := BlkCount-1 DownTo ALimit Do
  1698. FreeMem(BlkList^[W], BlkSize); { Release memory block }
  1699. If (P <> Nil) AND (ALimit > BlkCount) Then Begin { Expand stream size }
  1700. For W := BlkCount To ALimit-1 Do Begin
  1701. If (MaxAvail < BlkSize) Then Begin { Check enough memory }
  1702. GetMem(P^[W],BlkSize);
  1703. If P = Nil Then Begin
  1704. For I := BlkCount To W-1 Do
  1705. FreeMem(P^[I], BlkSize); { Free mem allocated }
  1706. FreeMem(P, Li); { Release memory }
  1707. Exit;
  1708. End { Now exit }
  1709. End Else GetMem(P^[W], BlkSize); { Allocate memory }
  1710. End;
  1711. End;
  1712. If (BlkCount <> 0) AND (BlkList<>Nil) Then
  1713. FreeMem(BlkList, BlkCount * SizeOf(Pointer)); { Release old list }
  1714. BlkList := P; { Hold new block list }
  1715. BlkCount := ALimit; { Hold new count }
  1716. { * REMARK * - Do not shorten this, result can be > 64K }
  1717. MemSize := BlkCount; { Block count }
  1718. MemSize := MemSize * BlkSize; { Current position }
  1719. { * REMARK END * - Leon de Boer }
  1720. End;
  1721. ChangeListSize := True; { Successful }
  1722. END;
  1723. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1724. { TCollection OBJECT METHODS }
  1725. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1726. {--TCollection--------------------------------------------------------------}
  1727. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1728. {---------------------------------------------------------------------------}
  1729. CONSTRUCTOR TCollection.Init (ALimit, ADelta: Sw_Integer);
  1730. BEGIN
  1731. Inherited Init; { Call ancestor }
  1732. Delta := ADelta; { Set increment }
  1733. SetLimit(ALimit); { Set limit }
  1734. END;
  1735. {--TCollection--------------------------------------------------------------}
  1736. { Load -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1737. {---------------------------------------------------------------------------}
  1738. CONSTRUCTOR TCollection.Load (Var S: TStream);
  1739. VAR C, I: Sw_Integer;
  1740. BEGIN
  1741. If S.TPCompatible Then Begin
  1742. { I ignore endianness issues here. If endianness is different,
  1743. you can't expect binary compatible resources anyway. }
  1744. Count := 0; S.Read(Count, Sizeof(Word));
  1745. Limit := 0; S.Read(Limit, Sizeof(Word));
  1746. Delta := 0; S.Read(Delta, Sizeof(Word))
  1747. End
  1748. Else Begin
  1749. S.Read(Count, Sizeof(Count)); { Read count }
  1750. S.Read(Limit, Sizeof(Limit)); { Read limit }
  1751. S.Read(Delta, Sizeof(Delta)); { Read delta }
  1752. End;
  1753. Items := Nil; { Clear item pointer }
  1754. C := Count; { Hold count }
  1755. I := Limit; { Hold limit }
  1756. Count := 0; { Clear count }
  1757. Limit := 0; { Clear limit }
  1758. SetLimit(I); { Set requested limit }
  1759. Count := C; { Set count }
  1760. For I := 0 To C-1 Do AtPut(I, GetItem(S)); { Get each item }
  1761. END;
  1762. {--TCollection--------------------------------------------------------------}
  1763. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1764. {---------------------------------------------------------------------------}
  1765. DESTRUCTOR TCollection.Done;
  1766. BEGIN
  1767. FreeAll; { Free all items }
  1768. SetLimit(0); { Release all memory }
  1769. END;
  1770. {--TCollection--------------------------------------------------------------}
  1771. { At -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1772. {---------------------------------------------------------------------------}
  1773. FUNCTION TCollection.At (Index: Sw_Integer): Pointer;
  1774. BEGIN
  1775. If (Index < 0) OR (Index >= Count) Then Begin { Invalid index }
  1776. Error(coIndexError, Index); { Call error }
  1777. At := Nil; { Return nil }
  1778. End Else At := Items^[Index]; { Return item }
  1779. END;
  1780. {--TCollection--------------------------------------------------------------}
  1781. { IndexOf -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1782. {---------------------------------------------------------------------------}
  1783. FUNCTION TCollection.IndexOf (Item: Pointer): Sw_Integer;
  1784. VAR I: Sw_Integer;
  1785. BEGIN
  1786. If (Count>0) Then Begin { Count is positive }
  1787. For I := 0 To Count-1 Do { For each item }
  1788. If (Items^[I]=Item) Then Begin { Look for match }
  1789. IndexOf := I; { Return index }
  1790. Exit; { Now exit }
  1791. End;
  1792. End;
  1793. IndexOf := -1; { Return index }
  1794. END;
  1795. {--TCollection--------------------------------------------------------------}
  1796. { GetItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1797. {---------------------------------------------------------------------------}
  1798. FUNCTION TCollection.GetItem (Var S: TStream): Pointer;
  1799. BEGIN
  1800. GetItem := S.Get; { Item off stream }
  1801. END;
  1802. {--TCollection--------------------------------------------------------------}
  1803. { LastThat -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1804. {---------------------------------------------------------------------------}
  1805. FUNCTION TCollection.LastThat (Test: Pointer): Pointer;
  1806. VAR I: LongInt;
  1807. BEGIN
  1808. For I := Count DownTo 1 Do
  1809. Begin { Down from last item }
  1810. IF Boolean(Byte(ptrint(CallPointerLocal(Test,get_caller_frame(get_frame),Items^[I-1])))) THEN
  1811. Begin { Test each item }
  1812. LastThat := Items^[I-1]; { Return item }
  1813. Exit; { Now exit }
  1814. End;
  1815. End;
  1816. LastThat := Nil; { None passed test }
  1817. END;
  1818. {--TCollection--------------------------------------------------------------}
  1819. { FirstThat -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1820. {---------------------------------------------------------------------------}
  1821. FUNCTION TCollection.FirstThat (Test: Pointer): Pointer;
  1822. VAR I: LongInt;
  1823. BEGIN
  1824. For I := 1 To Count Do Begin { Up from first item }
  1825. IF Boolean(Byte(ptrint(CallPointerLocal(Test,get_caller_frame(get_frame),Items^[I-1])))) THEN
  1826. Begin { Test each item }
  1827. FirstThat := Items^[I-1]; { Return item }
  1828. Exit; { Now exit }
  1829. End;
  1830. End;
  1831. FirstThat := Nil; { None passed test }
  1832. END;
  1833. {--TCollection--------------------------------------------------------------}
  1834. { Pack -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1835. {---------------------------------------------------------------------------}
  1836. PROCEDURE TCollection.Pack;
  1837. VAR I, J: Sw_Integer;
  1838. BEGIN
  1839. I := 0; { Initialize dest }
  1840. J := 0; { Intialize test }
  1841. While (I<Count) AND (J<Limit) Do Begin { Check fully packed }
  1842. If (Items^[J]<>Nil) Then Begin { Found a valid item }
  1843. If (I<>J) Then Begin
  1844. Items^[I] := Items^[J]; { Transfer item }
  1845. Items^[J] := Nil; { Now clear old item }
  1846. End;
  1847. Inc(I); { One item packed }
  1848. End;
  1849. Inc(J); { Next item to test }
  1850. End;
  1851. If (I<Count) Then Count := I; { New packed count }
  1852. END;
  1853. {--TCollection--------------------------------------------------------------}
  1854. { FreeAll -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1855. {---------------------------------------------------------------------------}
  1856. PROCEDURE TCollection.FreeAll;
  1857. VAR I: Sw_Integer;
  1858. BEGIN
  1859. for I := Count-1 downto 0 do
  1860. FreeItem(At(I));
  1861. Count := 0; { Clear item count }
  1862. END;
  1863. {--TCollection--------------------------------------------------------------}
  1864. { DeleteAll -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1865. {---------------------------------------------------------------------------}
  1866. PROCEDURE TCollection.DeleteAll;
  1867. BEGIN
  1868. Count := 0; { Clear item count }
  1869. END;
  1870. {--TCollection--------------------------------------------------------------}
  1871. { Free -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1872. {---------------------------------------------------------------------------}
  1873. PROCEDURE TCollection.Free (Item: Pointer);
  1874. BEGIN
  1875. Delete(Item); { Delete from list }
  1876. FreeItem(Item); { Free the item }
  1877. END;
  1878. {--TCollection--------------------------------------------------------------}
  1879. { Insert -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1880. {---------------------------------------------------------------------------}
  1881. PROCEDURE TCollection.Insert (Item: Pointer);
  1882. BEGIN
  1883. AtInsert(Count, Item); { Insert item }
  1884. END;
  1885. {--TCollection--------------------------------------------------------------}
  1886. { Delete -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1887. {---------------------------------------------------------------------------}
  1888. PROCEDURE TCollection.Delete (Item: Pointer);
  1889. BEGIN
  1890. AtDelete(IndexOf(Item)); { Delete from list }
  1891. END;
  1892. {--TCollection--------------------------------------------------------------}
  1893. { AtFree -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1894. {---------------------------------------------------------------------------}
  1895. PROCEDURE TCollection.AtFree (Index: Sw_Integer);
  1896. VAR Item: Pointer;
  1897. BEGIN
  1898. Item := At(Index); { Retreive item ptr }
  1899. AtDelete(Index); { Delete item }
  1900. FreeItem(Item); { Free the item }
  1901. END;
  1902. {--TCollection--------------------------------------------------------------}
  1903. { FreeItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1904. {---------------------------------------------------------------------------}
  1905. PROCEDURE TCollection.FreeItem (Item: Pointer);
  1906. VAR P: PObject;
  1907. BEGIN
  1908. P := PObject(Item); { Convert pointer }
  1909. If (P<>Nil) Then Dispose(P, Done); { Dispose of object }
  1910. END;
  1911. {--TCollection--------------------------------------------------------------}
  1912. { AtDelete -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1913. {---------------------------------------------------------------------------}
  1914. PROCEDURE TCollection.AtDelete (Index: Sw_Integer);
  1915. BEGIN
  1916. If (Index >= 0) AND (Index < Count) Then Begin { Valid index }
  1917. Dec(Count); { One less item }
  1918. If (Count>Index) Then Move(Items^[Index+1],
  1919. Items^[Index], (Count-Index)*Sizeof(Pointer)); { Shuffle items down }
  1920. End Else Error(coIndexError, Index); { Index error }
  1921. END;
  1922. {--TCollection--------------------------------------------------------------}
  1923. { ForEach -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1924. {---------------------------------------------------------------------------}
  1925. PROCEDURE TCollection.ForEach (Action: Pointer);
  1926. VAR I: LongInt;
  1927. BEGIN
  1928. For I := 1 To Count Do { Up from first item }
  1929. CallPointerLocal(Action,get_caller_frame(get_frame),Items^[I-1]); { Call with each item }
  1930. END;
  1931. {--TCollection--------------------------------------------------------------}
  1932. { SetLimit -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1933. {---------------------------------------------------------------------------}
  1934. PROCEDURE TCollection.SetLimit (ALimit: Sw_Integer);
  1935. VAR
  1936. AItems: PItemList;
  1937. BEGIN
  1938. If (ALimit < Count) Then
  1939. ALimit := Count;
  1940. If (ALimit > MaxCollectionSize) Then
  1941. ALimit := MaxCollectionSize;
  1942. If (ALimit <> Limit) Then
  1943. Begin
  1944. If (ALimit = 0) Then
  1945. AItems := Nil
  1946. Else
  1947. Begin
  1948. GetMem(AItems, ALimit * SizeOf(Pointer));
  1949. If (AItems<>Nil) Then
  1950. FillChar(AItems^,ALimit * SizeOf(Pointer), #0);
  1951. End;
  1952. If (AItems<>Nil) OR (ALimit=0) Then
  1953. Begin
  1954. If (AItems <>Nil) AND (Items <> Nil) Then
  1955. Move(Items^, AItems^, Count*SizeOf(Pointer));
  1956. If (Limit <> 0) AND (Items <> Nil) Then
  1957. FreeMem(Items, Limit * SizeOf(Pointer));
  1958. end;
  1959. Items := AItems;
  1960. Limit := ALimit;
  1961. End;
  1962. END;
  1963. {--TCollection--------------------------------------------------------------}
  1964. { Error -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1965. {---------------------------------------------------------------------------}
  1966. PROCEDURE TCollection.Error (Code, Info: Integer);
  1967. BEGIN
  1968. RunError(212 - Code); { Run error }
  1969. END;
  1970. {--TCollection--------------------------------------------------------------}
  1971. { AtPut -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1972. {---------------------------------------------------------------------------}
  1973. PROCEDURE TCollection.AtPut (Index: Sw_Integer; Item: Pointer);
  1974. BEGIN
  1975. If (Index >= 0) AND (Index < Count) Then { Index valid }
  1976. Items^[Index] := Item { Put item in index }
  1977. Else Error(coIndexError, Index); { Index error }
  1978. END;
  1979. {--TCollection--------------------------------------------------------------}
  1980. { AtInsert -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1981. {---------------------------------------------------------------------------}
  1982. PROCEDURE TCollection.AtInsert (Index: Sw_Integer; Item: Pointer);
  1983. VAR I: Sw_Integer;
  1984. BEGIN
  1985. If (Index >= 0) AND (Index <= Count) Then Begin { Valid index }
  1986. If (Count=Limit) Then SetLimit(Limit+Delta); { Expand size if able }
  1987. If (Limit>Count) Then Begin
  1988. If (Index < Count) Then Begin { Not last item }
  1989. For I := Count-1 DownTo Index Do { Start from back }
  1990. Items^[I+1] := Items^[I]; { Move each item }
  1991. End;
  1992. Items^[Index] := Item; { Put item in list }
  1993. Inc(Count); { Inc count }
  1994. End Else Error(coOverflow, Index); { Expand failed }
  1995. End Else Error(coIndexError, Index); { Index error }
  1996. END;
  1997. {--TCollection--------------------------------------------------------------}
  1998. { Store -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  1999. {---------------------------------------------------------------------------}
  2000. PROCEDURE TCollection.Store (Var S: TStream);
  2001. var
  2002. LimitWord, DeltaWord: Word;
  2003. PROCEDURE DoPutItem (P: Pointer);{$IFNDEF FPC}FAR;{$ENDIF}
  2004. BEGIN
  2005. PutItem(S, P); { Put item on stream }
  2006. END;
  2007. BEGIN
  2008. If S.TPCompatible Then Begin
  2009. { Check if it is safe to write in TP-compatible stream.
  2010. If Count is too big, signal an error.
  2011. If Limit or Delta are too big, write smaller values. }
  2012. If (Count > MaxTPCompatibleCollectionSize)
  2013. Then S.Error(stWriteError, 0)
  2014. Else Begin
  2015. S.Write(Count, Sizeof(Word));
  2016. if Limit > MaxTPCompatibleCollectionSize
  2017. then LimitWord := MaxTPCompatibleCollectionSize
  2018. else LimitWord := Limit;
  2019. S.Write(LimitWord, Sizeof(Word));
  2020. if Delta > MaxTPCompatibleCollectionSize
  2021. then DeltaWord := MaxTPCompatibleCollectionSize
  2022. else DeltaWord := Delta;
  2023. S.Write(DeltaWord, Sizeof(Word));
  2024. End
  2025. End
  2026. Else Begin
  2027. S.Write(Count, Sizeof(Count)); { Write count }
  2028. S.Write(Limit, Sizeof(Limit)); { Write limit }
  2029. S.Write(Delta, Sizeof(Delta)); { Write delta }
  2030. End;
  2031. ForEach(@DoPutItem); { Each item to stream }
  2032. END;
  2033. {--TCollection--------------------------------------------------------------}
  2034. { PutItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2035. {---------------------------------------------------------------------------}
  2036. PROCEDURE TCollection.PutItem (Var S: TStream; Item: Pointer);
  2037. BEGIN
  2038. S.Put(Item); { Put item on stream }
  2039. END;
  2040. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2041. { TSortedCollection OBJECT METHODS }
  2042. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2043. {--TSortedCollection--------------------------------------------------------}
  2044. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2045. {---------------------------------------------------------------------------}
  2046. CONSTRUCTOR TSortedCollection.Init (ALimit, ADelta: Sw_Integer);
  2047. BEGIN
  2048. Inherited Init(ALimit, ADelta); { Call ancestor }
  2049. Duplicates := False; { Clear flag }
  2050. END;
  2051. {--TSortedCollection--------------------------------------------------------}
  2052. { Load -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2053. {---------------------------------------------------------------------------}
  2054. CONSTRUCTOR TSortedCollection.Load (Var S: TStream);
  2055. BEGIN
  2056. Inherited Load(S); { Call ancestor }
  2057. S.Read(Duplicates, SizeOf(Duplicates)); { Read duplicate flag }
  2058. END;
  2059. {--TSortedCollection--------------------------------------------------------}
  2060. { KeyOf -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2061. {---------------------------------------------------------------------------}
  2062. FUNCTION TSortedCollection.KeyOf (Item: Pointer): Pointer;
  2063. BEGIN
  2064. KeyOf := Item; { Return item as key }
  2065. END;
  2066. {--TSortedCollection--------------------------------------------------------}
  2067. { IndexOf -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2068. {---------------------------------------------------------------------------}
  2069. FUNCTION TSortedCollection.IndexOf (Item: Pointer): Sw_Integer;
  2070. VAR I, J: Sw_Integer;
  2071. BEGIN
  2072. J := -1; { Preset result }
  2073. If Search(KeyOf(Item), I) Then Begin { Search for item }
  2074. If Duplicates Then { Duplicates allowed }
  2075. While (I < Count) AND (Item <> Items^[I]) Do
  2076. Inc(I); { Count duplicates }
  2077. If (I < Count) Then J := I; { Index result }
  2078. End;
  2079. IndexOf := J; { Return result }
  2080. END;
  2081. {--TSortedCollection--------------------------------------------------------}
  2082. { Compare -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2083. {---------------------------------------------------------------------------}
  2084. FUNCTION TSortedCollection.Compare (Key1, Key2: Pointer): Sw_Integer;
  2085. BEGIN
  2086. Abstract; { Abstract method }
  2087. Compare:=0;
  2088. END;
  2089. {--TSortedCollection--------------------------------------------------------}
  2090. { Search -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2091. {---------------------------------------------------------------------------}
  2092. FUNCTION TSortedCollection.Search (Key: Pointer; Var Index: Sw_Integer): Boolean;
  2093. VAR L, H, I, C: Sw_Integer;
  2094. BEGIN
  2095. Search := False; { Preset failure }
  2096. L := 0; { Start count }
  2097. H := Count - 1; { End count }
  2098. While (L <= H) Do Begin
  2099. I := (L + H) SHR 1; { Mid point }
  2100. C := Compare(KeyOf(Items^[I]), Key); { Compare with key }
  2101. If (C < 0) Then L := I + 1 Else Begin { Item to left }
  2102. H := I - 1; { Item to right }
  2103. If C = 0 Then Begin { Item match found }
  2104. Search := True; { Result true }
  2105. If NOT Duplicates Then L := I; { Force kick out }
  2106. End;
  2107. End;
  2108. End;
  2109. Index := L; { Return result }
  2110. END;
  2111. {--TSortedCollection--------------------------------------------------------}
  2112. { Insert -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2113. {---------------------------------------------------------------------------}
  2114. PROCEDURE TSortedCollection.Insert (Item: Pointer);
  2115. VAR I: Sw_Integer;
  2116. BEGIN
  2117. If NOT Search(KeyOf(Item), I) OR Duplicates Then { Item valid }
  2118. AtInsert(I, Item); { Insert the item }
  2119. END;
  2120. {--TSortedCollection--------------------------------------------------------}
  2121. { Store -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2122. {---------------------------------------------------------------------------}
  2123. PROCEDURE TSortedCollection.Store (Var S: TStream);
  2124. BEGIN
  2125. TCollection.Store(S); { Call ancestor }
  2126. S.Write(Duplicates, SizeOf(Duplicates)); { Write duplicate flag }
  2127. END;
  2128. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2129. { TStringCollection OBJECT METHODS }
  2130. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2131. {--TStringCollection--------------------------------------------------------}
  2132. { GetItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2133. {---------------------------------------------------------------------------}
  2134. FUNCTION TStringCollection.GetItem (Var S: TStream): Pointer;
  2135. BEGIN
  2136. GetItem := S.ReadStr; { Get new item }
  2137. END;
  2138. {--TStringCollection--------------------------------------------------------}
  2139. { Compare -> Platforms DOS/DPMI/WIN/OS2 - Checked 21Aug97 LdB }
  2140. {---------------------------------------------------------------------------}
  2141. FUNCTION TStringCollection.Compare (Key1, Key2: Pointer): Sw_Integer;
  2142. VAR I, J: Sw_Integer; P1, P2: PString;
  2143. BEGIN
  2144. P1 := PString(Key1); { String 1 pointer }
  2145. P2 := PString(Key2); { String 2 pointer }
  2146. If (Length(P1^)<Length(P2^)) Then J := Length(P1^)
  2147. Else J := Length(P2^); { Shortest length }
  2148. I := 1; { First character }
  2149. While (I<J) AND (P1^[I]=P2^[I]) Do Inc(I); { Scan till fail }
  2150. If (I=J) Then Begin { Possible match }
  2151. { * REMARK * - Bug fix 21 August 1997 }
  2152. If (P1^[I]<P2^[I]) Then Compare := -1 Else { String1 < String2 }
  2153. If (P1^[I]>P2^[I]) Then Compare := 1 Else { String1 > String2 }
  2154. If (Length(P1^)>Length(P2^)) Then Compare := 1 { String1 > String2 }
  2155. Else If (Length(P1^)<Length(P2^)) Then { String1 < String2 }
  2156. Compare := -1 Else Compare := 0; { String1 = String2 }
  2157. { * REMARK END * - Leon de Boer }
  2158. End Else If (P1^[I]<P2^[I]) Then Compare := -1 { String1 < String2 }
  2159. Else Compare := 1; { String1 > String2 }
  2160. END;
  2161. {--TStringCollection--------------------------------------------------------}
  2162. { FreeItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2163. {---------------------------------------------------------------------------}
  2164. PROCEDURE TStringCollection.FreeItem (Item: Pointer);
  2165. BEGIN
  2166. DisposeStr(Item); { Dispose item }
  2167. END;
  2168. {--TStringCollection--------------------------------------------------------}
  2169. { PutItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 22May96 LdB }
  2170. {---------------------------------------------------------------------------}
  2171. PROCEDURE TStringCollection.PutItem (Var S: TStream; Item: Pointer);
  2172. BEGIN
  2173. S.WriteStr(Item); { Write string }
  2174. END;
  2175. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2176. { TStrCollection OBJECT METHODS }
  2177. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2178. {--TStrCollection-----------------------------------------------------------}
  2179. { Compare -> Platforms DOS/DPMI/WIN/OS2 - Checked 23May96 LdB }
  2180. {---------------------------------------------------------------------------}
  2181. FUNCTION TStrCollection.Compare (Key1, Key2: Pointer): Sw_Integer;
  2182. VAR I, J: Sw_Integer; P1, P2: PByteArray;
  2183. BEGIN
  2184. P1 := PByteArray(Key1); { PChar 1 pointer }
  2185. P2 := PByteArray(Key2); { PChar 2 pointer }
  2186. I := 0; { Preset no size }
  2187. If (P1<>Nil) Then While (P1^[I]<>0) Do Inc(I); { PChar 1 length }
  2188. J := 0; { Preset no size }
  2189. If (P2<>Nil) Then While (P2^[J]<>0) Do Inc(J); { PChar 2 length }
  2190. If (I < J) Then J := I; { Shortest length }
  2191. I := 0; { First character }
  2192. While (I<J) AND (P1^[I]=P2^[I]) Do Inc(I); { Scan till fail }
  2193. If (P1^[I]=P2^[I]) Then Compare := 0 Else { Strings matched }
  2194. If (P1^[I]<P2^[I]) Then Compare := -1 Else { String1 < String2 }
  2195. Compare := 1; { String1 > String2 }
  2196. END;
  2197. {--TStrCollection-----------------------------------------------------------}
  2198. { GetItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 23May96 LdB }
  2199. {---------------------------------------------------------------------------}
  2200. FUNCTION TStrCollection.GetItem (Var S: TStream): Pointer;
  2201. BEGIN
  2202. GetItem := S.StrRead; { Get string item }
  2203. END;
  2204. {--TStrCollection-----------------------------------------------------------}
  2205. { FreeItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 23May96 LdB }
  2206. {---------------------------------------------------------------------------}
  2207. PROCEDURE TStrCollection.FreeItem (Item: Pointer);
  2208. VAR I: Sw_Integer; P: PByteArray;
  2209. BEGIN
  2210. If (Item<>Nil) Then Begin { Item is valid }
  2211. P := PByteArray(Item); { Create byte pointer }
  2212. I := 0; { Preset no size }
  2213. While (P^[I]<>0) Do Inc(I); { Find PChar end }
  2214. FreeMem(Item, I+1); { Release memory }
  2215. End;
  2216. END;
  2217. {--TStrCollection-----------------------------------------------------------}
  2218. { PutItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 23May96 LdB }
  2219. {---------------------------------------------------------------------------}
  2220. PROCEDURE TStrCollection.PutItem (Var S: TStream; Item: Pointer);
  2221. BEGIN
  2222. S.StrWrite(Item); { Write the string }
  2223. END;
  2224. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2225. { TUnSortedStrCollection OBJECT METHODS }
  2226. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2227. {--TUnSortedCollection------------------------------------------------------}
  2228. { Insert -> Platforms DOS/DPMI/WIN/OS2 - Checked 23May96 LdB }
  2229. {---------------------------------------------------------------------------}
  2230. PROCEDURE TUnSortedStrCollection.Insert (Item: Pointer);
  2231. BEGIN
  2232. AtInsert(Count, Item); { Insert - NO sorting }
  2233. END;
  2234. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2235. { TResourceItem RECORD }
  2236. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2237. TYPE
  2238. TResourceItem = packed RECORD
  2239. Posn: LongInt; { Resource position }
  2240. Size: LongInt; { Resource size }
  2241. Key : String; { Resource key }
  2242. End;
  2243. PResourceItem = ^TResourceItem;
  2244. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2245. { TResourceCollection OBJECT METHODS }
  2246. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2247. {--TResourceCollection------------------------------------------------------}
  2248. { KeyOf -> Platforms DOS/DPMI/WIN/OS2 - Checked 24May96 LdB }
  2249. {---------------------------------------------------------------------------}
  2250. FUNCTION TResourceCollection.KeyOf (Item: Pointer): Pointer;
  2251. BEGIN
  2252. KeyOf := @PResourceItem(Item)^.Key; { Pointer to key }
  2253. END;
  2254. {--TResourceCollection------------------------------------------------------}
  2255. { GetItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 24May96 LdB }
  2256. {---------------------------------------------------------------------------}
  2257. FUNCTION TResourceCollection.GetItem (Var S: TStream): Pointer;
  2258. VAR B: Byte; Pos: Longint; Size: Longint; Ts: String; P: PResourceItem;
  2259. BEGIN
  2260. S.Read(Pos, SizeOf(Pos)); { Read position }
  2261. S.Read(Size, SizeOf(Size)); { Read size }
  2262. S.Read(B, 1); { Read key length }
  2263. GetMem(P, B + (SizeOf(TResourceItem) -
  2264. SizeOf(Ts) + 1)); { Allocate min memory }
  2265. If (P<>Nil) Then Begin { If allocate works }
  2266. P^.Posn := Pos; { Xfer position }
  2267. P^.Size := Size; { Xfer size }
  2268. P^.Key[0] := Char(B); { Xfer string length }
  2269. S.Read(P^.Key[1], B); { Xfer string data }
  2270. End;
  2271. GetItem := P; { Return pointer }
  2272. END;
  2273. {--TResourceCollection------------------------------------------------------}
  2274. { FreeItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 24May96 LdB }
  2275. {---------------------------------------------------------------------------}
  2276. PROCEDURE TResourceCollection.FreeItem (Item: Pointer);
  2277. VAR Ts: String;
  2278. BEGIN
  2279. If (Item<>Nil) Then FreeMem(Item,
  2280. SizeOf(TResourceItem) - SizeOf(Ts) +
  2281. Length(PResourceItem(Item)^.Key) + 1); { Release memory }
  2282. END;
  2283. {--TResourceCollection------------------------------------------------------}
  2284. { PutItem -> Platforms DOS/DPMI/WIN/OS2 - Checked 24May96 LdB }
  2285. {---------------------------------------------------------------------------}
  2286. PROCEDURE TResourceCollection.PutItem (Var S: TStream; Item: Pointer);
  2287. VAR Ts: String;
  2288. BEGIN
  2289. If (Item<>Nil) Then S.Write(PResourceItem(Item)^,
  2290. SizeOf(TResourceItem) - SizeOf(Ts) +
  2291. Length(PResourceItem(Item)^.Key) + 1); { Write to stream }
  2292. END;
  2293. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2294. { PRIVATE RESOURCE MANAGER CONSTANTS }
  2295. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2296. CONST
  2297. RStreamMagic: LongInt = $52504246; { 'FBPR' }
  2298. RStreamBackLink: LongInt = $4C424246; { 'FBBL' }
  2299. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2300. { PRIVATE RESOURCE MANAGER TYPES }
  2301. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2302. TYPE
  2303. {$IFDEF NewExeFormat} { New EXE format }
  2304. TExeHeader = packed RECORD
  2305. eHdrSize: Word;
  2306. eMinAbove: Word;
  2307. eMaxAbove: Word;
  2308. eInitSS: Word;
  2309. eInitSP: Word;
  2310. eCheckSum: Word;
  2311. eInitPC: Word;
  2312. eInitCS: Word;
  2313. eRelocOfs: Word;
  2314. eOvlyNum: Word;
  2315. eRelocTab: Word;
  2316. eSpace: Array[1..30] of Byte;
  2317. eNewHeader: Word;
  2318. END;
  2319. {$ENDIF}
  2320. THeader = packed RECORD
  2321. Signature: Word;
  2322. Case Integer Of
  2323. 0: (
  2324. LastCount: Word;
  2325. PageCount: Word;
  2326. ReloCount: Word);
  2327. 1: (
  2328. InfoType: Word;
  2329. InfoSize: Longint);
  2330. End;
  2331. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2332. { TResourceFile OBJECT METHODS }
  2333. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2334. {--TResourceFile------------------------------------------------------------}
  2335. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2336. {---------------------------------------------------------------------------}
  2337. CONSTRUCTOR TResourceFile.Init(AStream: PStream);
  2338. VAR Found, Stop: Boolean; Header: THeader;
  2339. {$IFDEF NewExeFormat} ExeHeader: TExeHeader; {$ENDIF}
  2340. BEGIN
  2341. TObject.Init; { Initialize object }
  2342. Found := False; { Preset false }
  2343. If (AStream<>Nil) Then Begin
  2344. Stream := AStream; { Hold stream }
  2345. BasePos := Stream^.GetPos; { Get position }
  2346. Repeat
  2347. Stop := True; { Preset stop }
  2348. If (BasePos <= Stream^.GetSize-SizeOf(THeader))
  2349. Then Begin { Valid file header }
  2350. Stream^.Seek(BasePos); { Seek to position }
  2351. Stream^.Read(Header, SizeOf(THeader)); { Read header }
  2352. Case Header.Signature Of
  2353. {$IFDEF NewExeFormat} { New format file }
  2354. $5A4D: Begin
  2355. Stream^.Read(ExeHeader, SizeOf(TExeHeader));
  2356. BasePos := ExeHeader.eNewHeader; { Hold position }
  2357. Stop := False; { Clear stop flag }
  2358. End;
  2359. $454E: Begin
  2360. BasePos := Stream^.GetSize - 8; { Hold position }
  2361. Stop := False; { Clear stop flag }
  2362. End;
  2363. $4246: Begin
  2364. Stop := False; { Clear stop flag }
  2365. Case Header.Infotype Of
  2366. $5250: Begin { Found Resource }
  2367. Found := True; { Found flag is true }
  2368. Stop := True; { Set stop flag }
  2369. End;
  2370. $4C42: Dec(BasePos, Header.InfoSize-8);{ Found BackLink }
  2371. $4648: Dec(BasePos, SizeOf(THeader)*2);{ Found HelpFile }
  2372. Else Stop := True; { Set stop flag }
  2373. End;
  2374. End;
  2375. $424E: If Header.InfoType = $3230 { Found Debug Info }
  2376. Then Begin
  2377. Dec(BasePos, Header.InfoSize); { Adjust position }
  2378. Stop := False; { Clear stop flag }
  2379. End;
  2380. {$ELSE}
  2381. $5A4D: Begin
  2382. Inc(BasePos, LongInt(Header.PageCount)*512
  2383. - (-Header.LastCount AND 511)); { Calc position }
  2384. Stop := False; { Clear stop flag }
  2385. End;
  2386. $4246: If Header.InfoType = $5250 Then { Header was found }
  2387. Found := True Else Begin
  2388. Inc(BasePos, Header.InfoSize + 8); { Adjust position }
  2389. Stop := False; { Clear stop flag }
  2390. End;
  2391. {$ENDIF}
  2392. End;
  2393. End;
  2394. Until Stop; { Until flag is set }
  2395. End;
  2396. If Found Then Begin { Resource was found }
  2397. Stream^.Seek(BasePos + SizeOf(LongInt) * 2); { Seek to position }
  2398. Stream^.Read(IndexPos, SizeOf(LongInt)); { Read index position }
  2399. Stream^.Seek(BasePos + IndexPos); { Seek to resource }
  2400. Index.Load(Stream^); { Load resource }
  2401. End Else Begin
  2402. IndexPos := SizeOf(LongInt) * 3; { Set index position }
  2403. Index.Init(0, 8); { Set index }
  2404. End;
  2405. END;
  2406. {--TResourceFile------------------------------------------------------------}
  2407. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2408. {---------------------------------------------------------------------------}
  2409. DESTRUCTOR TResourceFile.Done;
  2410. BEGIN
  2411. Flush; { Flush the file }
  2412. Index.Done; { Dispose of index }
  2413. If (Stream<>Nil) Then Dispose(Stream, Done); { Dispose of stream }
  2414. END;
  2415. {--TResourceFile------------------------------------------------------------}
  2416. { Count -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2417. {---------------------------------------------------------------------------}
  2418. FUNCTION TResourceFile.Count: Sw_Integer;
  2419. BEGIN
  2420. Count := Index.Count; { Return index count }
  2421. END;
  2422. {--TResourceFile------------------------------------------------------------}
  2423. { KeyAt -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2424. {---------------------------------------------------------------------------}
  2425. FUNCTION TResourceFile.KeyAt (I: Sw_Integer): String;
  2426. BEGIN
  2427. KeyAt := PResourceItem(Index.At(I))^.Key; { Return key }
  2428. END;
  2429. {--TResourceFile------------------------------------------------------------}
  2430. { Get -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2431. {---------------------------------------------------------------------------}
  2432. FUNCTION TResourceFile.Get (Key: String): PObject;
  2433. VAR I: Sw_Integer;
  2434. BEGIN
  2435. If (Stream = Nil) OR (NOT Index.Search(@Key, I)) { No match on key }
  2436. Then Get := Nil Else Begin
  2437. Stream^.Seek(BasePos +
  2438. PResourceItem(Index.At(I))^.Posn); { Seek to position }
  2439. Get := Stream^.Get; { Get item }
  2440. End;
  2441. END;
  2442. {--TResourceFile------------------------------------------------------------}
  2443. { SwitchTo -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2444. {---------------------------------------------------------------------------}
  2445. FUNCTION TResourceFile.SwitchTo (AStream: PStream; Pack: Boolean): PStream;
  2446. VAR NewBasePos: LongInt;
  2447. PROCEDURE DoCopyResource (Item: PResourceItem);{$IFNDEF FPC}FAR;{$ENDIF}
  2448. BEGIN
  2449. Stream^.Seek(BasePos + Item^.Posn); { Move stream position }
  2450. Item^.Posn := AStream^.GetPos - NewBasePos; { Hold new position }
  2451. AStream^.CopyFrom(Stream^, Item^.Size); { Copy the item }
  2452. END;
  2453. BEGIN
  2454. SwitchTo := Stream; { Preset return }
  2455. If (AStream<>Nil) AND (Stream<>Nil) Then Begin { Both streams valid }
  2456. NewBasePos := AStream^.GetPos; { Get position }
  2457. If Pack Then Begin
  2458. AStream^.Seek(NewBasePos + SizeOf(LongInt)*3); { Seek to position }
  2459. Index.ForEach(@DoCopyResource); { Copy each resource }
  2460. IndexPos := AStream^.GetPos - NewBasePos; { Hold index position }
  2461. End Else Begin
  2462. Stream^.Seek(BasePos); { Seek to position }
  2463. AStream^.CopyFrom(Stream^, IndexPos); { Copy the resource }
  2464. End;
  2465. Stream := AStream; { Hold new stream }
  2466. BasePos := NewBasePos; { New base position }
  2467. Modified := True; { Set modified flag }
  2468. End;
  2469. END;
  2470. {--TResourceFile------------------------------------------------------------}
  2471. { Flush -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2472. {---------------------------------------------------------------------------}
  2473. PROCEDURE TResourceFile.Flush;
  2474. VAR ResSize: LongInt; LinkSize: LongInt;
  2475. BEGIN
  2476. If (Modified) AND (Stream<>Nil) Then Begin { We have modification }
  2477. Stream^.Seek(BasePos + IndexPos); { Seek to position }
  2478. Index.Store(Stream^); { Store the item }
  2479. ResSize := Stream^.GetPos - BasePos; { Hold position }
  2480. LinkSize := ResSize + SizeOf(LongInt) * 2; { Hold link size }
  2481. Stream^.Write(RStreamBackLink, SizeOf(LongInt)); { Write link back }
  2482. Stream^.Write(LinkSize, SizeOf(LongInt)); { Write link size }
  2483. Stream^.Seek(BasePos); { Move stream position }
  2484. Stream^.Write(RStreamMagic, SizeOf(LongInt)); { Write number }
  2485. Stream^.Write(ResSize, SizeOf(LongInt)); { Write record size }
  2486. Stream^.Write(IndexPos, SizeOf(LongInt)); { Write index position }
  2487. Stream^.Flush; { Flush the stream }
  2488. End;
  2489. Modified := False; { Clear modified flag }
  2490. END;
  2491. {--TResourceFile------------------------------------------------------------}
  2492. { Delete -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2493. {---------------------------------------------------------------------------}
  2494. PROCEDURE TResourceFile.Delete (Key: String);
  2495. VAR I: Sw_Integer;
  2496. BEGIN
  2497. If Index.Search(@Key, I) Then Begin { Search for key }
  2498. Index.Free(Index.At(I)); { Delete from index }
  2499. Modified := True; { Set modified flag }
  2500. End;
  2501. END;
  2502. {--TResourceFile------------------------------------------------------------}
  2503. { Put -> Platforms DOS/DPMI/WIN/OS2 - Checked 18Jun96 LdB }
  2504. {---------------------------------------------------------------------------}
  2505. PROCEDURE TResourceFile.Put (Item: PObject; Key: String);
  2506. VAR I: Sw_Integer; Ts: String; P: PResourceItem;
  2507. BEGIN
  2508. If (Stream=Nil) Then Exit; { Stream not valid }
  2509. If Index.Search(@Key, I) Then P := Index.At(I) { Search for item }
  2510. Else Begin
  2511. GetMem(P, Length(Key) + (SizeOf(TResourceItem) -
  2512. SizeOf(Ts) + 1)); { Allocate memory }
  2513. If (P<>Nil) Then Begin
  2514. P^.Key := Key; { Store key }
  2515. Index.AtInsert(I, P); { Insert item }
  2516. End;
  2517. End;
  2518. If (P<>Nil) Then Begin
  2519. P^.Posn := IndexPos; { Set index position }
  2520. Stream^.Seek(BasePos + IndexPos); { Seek file position }
  2521. Stream^.Put(Item); { Put item on stream }
  2522. IndexPos := Stream^.GetPos - BasePos; { Hold index position }
  2523. P^.Size := IndexPos - P^.Posn; { Calc size }
  2524. Modified := True; { Set modified flag }
  2525. End;
  2526. END;
  2527. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2528. { TStringList OBJECT METHODS }
  2529. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2530. {--TStringList--------------------------------------------------------------}
  2531. { Load -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2532. {---------------------------------------------------------------------------}
  2533. CONSTRUCTOR TStringList.Load (Var S: TStream);
  2534. VAR Size: Word;
  2535. BEGIN
  2536. Stream := @S; { Hold stream pointer }
  2537. S.Read(Size, SizeOf(Word)); { Read size }
  2538. BasePos := S.GetPos; { Hold position }
  2539. S.Seek(BasePos + Size); { Seek to position }
  2540. S.Read(IndexSize, SizeOf(Integer)); { Read index size }
  2541. GetMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Allocate memory }
  2542. S.Read(Index^, IndexSize * SizeOf(TStrIndexRec)); { Read indexes }
  2543. END;
  2544. {--TStringList--------------------------------------------------------------}
  2545. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2546. {---------------------------------------------------------------------------}
  2547. DESTRUCTOR TStringList.Done;
  2548. BEGIN
  2549. FreeMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Release memory }
  2550. END;
  2551. {--TStringList--------------------------------------------------------------}
  2552. { Get -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2553. {---------------------------------------------------------------------------}
  2554. FUNCTION TStringList.Get (Key: Sw_Word): String;
  2555. VAR I: Word; S: String;
  2556. BEGIN
  2557. S := ''; { Preset empty string }
  2558. If (IndexSize>0) Then Begin { We must have strings }
  2559. I := 0; { First entry }
  2560. While (I<IndexSize) AND (S='') Do Begin
  2561. If ((Key - Index^[I].Key)<Index^[I].Count) { Diff less than count }
  2562. Then ReadStr(S, Index^[I].Offset,
  2563. Key-Index^[I].Key); { Read the string }
  2564. Inc(I); { Next entry }
  2565. End;
  2566. End;
  2567. Get := S; { Return empty string }
  2568. END;
  2569. {***************************************************************************}
  2570. { TStringList PRIVATE METHODS }
  2571. {***************************************************************************}
  2572. {--TStringLis---------------------------------------------------------------}
  2573. { ReadStr -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2574. {---------------------------------------------------------------------------}
  2575. PROCEDURE TStringList.ReadStr (Var S: String; Offset, Skip: Longint);
  2576. BEGIN
  2577. Stream^.Seek(BasePos + Offset); { Seek to position }
  2578. Inc(Skip); { Adjust skip }
  2579. Repeat
  2580. Stream^.Read(S[0], 1); { Read string size }
  2581. Stream^.Read(S[1], Ord(S[0])); { Read string data }
  2582. Dec(Skip); { One string read }
  2583. Until (Skip = 0);
  2584. END;
  2585. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2586. { TStrListMaker OBJECT METHODS }
  2587. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2588. {--TStrListMaker------------------------------------------------------------}
  2589. { Init -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2590. {---------------------------------------------------------------------------}
  2591. CONSTRUCTOR TStrListMaker.Init (AStrSize, AIndexSize: Sw_Word);
  2592. BEGIN
  2593. Inherited Init; { Call ancestor }
  2594. StrSize := AStrSize; { Hold size }
  2595. IndexSize := AIndexSize; { Hold index size }
  2596. GetMem(Strings, AStrSize); { Allocate memory }
  2597. GetMem(Index, AIndexSize * SizeOf(TStrIndexRec)); { Allocate memory }
  2598. END;
  2599. {--TStrListMaker------------------------------------------------------------}
  2600. { Done -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2601. {---------------------------------------------------------------------------}
  2602. DESTRUCTOR TStrListMaker.Done;
  2603. BEGIN
  2604. FreeMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Free index memory }
  2605. FreeMem(Strings, StrSize); { Free data memory }
  2606. END;
  2607. {--TStrListMaker------------------------------------------------------------}
  2608. { Put -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2609. {---------------------------------------------------------------------------}
  2610. PROCEDURE TStrListMaker.Put (Key: Sw_Word; S: String);
  2611. BEGIN
  2612. If (Cur.Count = 16) OR (Key <> Cur.Key + Cur.Count)
  2613. Then CloseCurrent; { Close current }
  2614. If (Cur.Count = 0) Then Begin
  2615. Cur.Key := Key; { Set key }
  2616. Cur.Offset := StrPos; { Set offset }
  2617. End;
  2618. Inc(Cur.Count); { Inc count }
  2619. Move(S, Strings^[StrPos], Length(S) + 1); { Move string data }
  2620. Inc(StrPos, Length(S) + 1); { Adjust position }
  2621. END;
  2622. {--TStrListMaker------------------------------------------------------------}
  2623. { Store -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2624. {---------------------------------------------------------------------------}
  2625. PROCEDURE TStrListMaker.Store (Var S: TStream);
  2626. BEGIN
  2627. CloseCurrent; { Close all current }
  2628. S.Write(StrPos, SizeOf(Word)); { Write position }
  2629. S.Write(Strings^, StrPos); { Write string data }
  2630. S.Write(IndexPos, SizeOf(Word)); { Write index position }
  2631. S.Write(Index^, IndexPos * SizeOf(TStrIndexRec)); { Write indexes }
  2632. END;
  2633. {***************************************************************************}
  2634. { TStrListMaker PRIVATE METHODS }
  2635. {***************************************************************************}
  2636. {--TStrListMaker------------------------------------------------------------}
  2637. { CloseCurrent -> Platforms DOS/DPMI/WIN/OS2 - Checked 30Jun97 LdB }
  2638. {---------------------------------------------------------------------------}
  2639. PROCEDURE TStrListMaker.CloseCurrent;
  2640. BEGIN
  2641. If (Cur.Count <> 0) Then Begin
  2642. Index^[IndexPos] := Cur; { Hold index position }
  2643. Inc(IndexPos); { Next index }
  2644. Cur.Count := 0; { Adjust count }
  2645. End;
  2646. END;
  2647. {***************************************************************************}
  2648. { INTERFACE ROUTINES }
  2649. {***************************************************************************}
  2650. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2651. { DYNAMIC STRING INTERFACE ROUTINES }
  2652. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2653. {---------------------------------------------------------------------------}
  2654. { NewStr -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 12Jun96 LdB }
  2655. {---------------------------------------------------------------------------}
  2656. FUNCTION NewStr (Const S: String): PString;
  2657. VAR P: PString;
  2658. BEGIN
  2659. If (S = '') Then P := Nil Else Begin { Return nil }
  2660. GetMem(P, Length(S) + 1); { Allocate memory }
  2661. If (P<>Nil) Then P^ := S; { Hold string }
  2662. End;
  2663. NewStr := P; { Return result }
  2664. END;
  2665. {---------------------------------------------------------------------------}
  2666. { DisposeStr -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 12Jun96 LdB }
  2667. {---------------------------------------------------------------------------}
  2668. PROCEDURE DisposeStr (P: PString);
  2669. BEGIN
  2670. If (P <> Nil) Then FreeMem(P, Length(P^) + 1); { Release memory }
  2671. END;
  2672. PROCEDURE SetStr(VAR p:pString; CONST s:STRING);
  2673. BEGIN
  2674. IF p<>NIL THEN
  2675. FreeMem(P, Length(P^) + 1);
  2676. GetMem(p,LENGTH(s)+1);
  2677. pSTRING(p)^ := s
  2678. END;
  2679. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2680. { STREAM INTERFACE ROUTINES }
  2681. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2682. {---------------------------------------------------------------------------}
  2683. { Abstract -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 12Jun96 LdB }
  2684. {---------------------------------------------------------------------------}
  2685. PROCEDURE Abstract;
  2686. BEGIN
  2687. RunError(211); { Abstract error }
  2688. END;
  2689. {---------------------------------------------------------------------------}
  2690. { RegisterObjects -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 02Sep97 LdB }
  2691. {---------------------------------------------------------------------------}
  2692. PROCEDURE RegisterObjects;
  2693. BEGIN
  2694. RegisterType(RCollection); { Register object }
  2695. RegisterType(RStringCollection); { Register object }
  2696. RegisterType(RStrCollection); { Register object }
  2697. END;
  2698. {---------------------------------------------------------------------------}
  2699. { RegisterType -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 02Sep97 LdB }
  2700. {---------------------------------------------------------------------------}
  2701. PROCEDURE RegisterType (Var S: TStreamRec);
  2702. VAR P: PStreamRec;
  2703. BEGIN
  2704. P := StreamTypes; { Current reg list }
  2705. While (P <> Nil) AND (P^.ObjType <> S.ObjType)
  2706. Do P := P^.Next; { Find end of chain }
  2707. If (P = Nil) AND (S.ObjType <> 0) Then Begin { Valid end found }
  2708. S.Next := StreamTypes; { Chain the list }
  2709. StreamTypes := @S; { We are now first }
  2710. End Else RegisterError; { Register the error }
  2711. END;
  2712. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2713. { GENERAL FUNCTION INTERFACE ROUTINES }
  2714. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  2715. {---------------------------------------------------------------------------}
  2716. { LongMul -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 04Sep97 LdB }
  2717. {---------------------------------------------------------------------------}
  2718. FUNCTION LongMul (X, Y: Integer): LongInt;
  2719. BEGIN
  2720. LongMul:=Longint(X*Y);
  2721. END;
  2722. {---------------------------------------------------------------------------}
  2723. { LongDiv -> Platforms DOS/DPMI/WINDOWS/OS2 - Checked 04Sep97 LdB }
  2724. {---------------------------------------------------------------------------}
  2725. FUNCTION LongDiv (X: LongInt; Y: Integer): Integer;
  2726. BEGIN
  2727. LongDiv := Integer(X DIV Y);
  2728. END;
  2729. BEGIN
  2730. invalidhandle:=UnusedHandle;
  2731. END.
  2732. {
  2733. $Log$
  2734. Revision 1.35 2004-11-02 23:53:19 peter
  2735. * fixed crashes with ide and 1.9.x
  2736. Revision 1.34 2004/10/03 17:43:47 florian
  2737. * fixedPreviousFramePointer on sparc
  2738. Revision 1.33 2004/08/26 22:58:01 carl
  2739. * bugfix with file sharing modes. They are now kept, as is the case in BP.
  2740. Revision 1.32 2004/06/20 09:24:40 peter
  2741. fixed go32v2 compile
  2742. Revision 1.31 2004/04/28 20:48:20 peter
  2743. * ordinal-pointer conversions fixed
  2744. Revision 1.30 2004/04/22 20:59:23 peter
  2745. * longint to ptrint
  2746. Revision 1.29 2004/03/31 21:49:19 florian
  2747. * fixed GetParentFrame for ARM
  2748. Revision 1.28 2004/02/18 21:59:23 peter
  2749. * x86_64 added
  2750. Revision 1.27 2004/01/01 15:30:04 jonas
  2751. * fixed PreviousFramePointer() for ppc
  2752. Revision 1.26 2003/11/30 19:48:20 florian
  2753. * fixed some arm stuff
  2754. Revision 1.25 2003/11/03 17:46:37 peter
  2755. * fixed crash in bufstream.write
  2756. Revision 1.24 2003/11/03 09:42:28 marco
  2757. * Peter's Cardinal<->Longint fixes patch
  2758. Revision 1.23 2003/10/25 23:43:59 hajny
  2759. * THandle in sysutils common using System.THandle
  2760. Revision 1.22 2003/09/16 15:57:33 peter
  2761. * sparc register typo
  2762. Revision 1.21 2003/08/21 22:17:13 olle
  2763. - removed parameter from fpc_iocheck
  2764. Revision 1.20 2003/07/08 21:21:33 peter
  2765. * 1.1 does not need to load esi
  2766. Revision 1.19 2003/06/05 14:45:56 peter
  2767. * use Windows THandle
  2768. Revision 1.18 2003/01/05 16:27:05 hajny
  2769. * PString inherited from System
  2770. Revision 1.17 2002/12/07 14:37:15 carl
  2771. - avoid warnings (add typecast)
  2772. Revision 1.16 2002/10/31 13:08:04 carl
  2773. * forgot to init P buffer variable = crash
  2774. Revision 1.15 2002/10/31 12:47:30 carl
  2775. * more compatibility fixes for objects unit
  2776. Revision 1.14 2002/10/30 22:44:44 carl
  2777. * Bugfix for error checking
  2778. - DosStreamError is no longer global (bugfix 2043)
  2779. Revision 1.13 2002/10/09 16:10:14 carl
  2780. - removed OS depedencies
  2781. Revision 1.12 2002/09/07 21:15:25 carl
  2782. - some cleanup (less ifdef)
  2783. Revision 1.11 2002/09/07 15:07:45 peter
  2784. * old logs removed and tabs fixed
  2785. Revision 1.10 2002/09/01 19:03:19 florian
  2786. + powerpc support added
  2787. Revision 1.9 2002/03/28 20:56:00 carl
  2788. - remove go32v1 support
  2789. }