1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223 |
- { $Id$ }
- {**********************************************************}
- { }
- { System independent clone of OBJECTS.PAS }
- { }
- { Interface Copyright (c) 1992 Borland International }
- { }
- { Parts Copyright (c) 1992,96 by Florian Klaempfl }
- { [email protected] }
- { }
- { Parts Copyright (c) 1996 by Frank ZAGO }
- { [email protected] }
- { }
- { Parts Copyright (c) 1995 by MH Spiegel }
- { }
- { Parts Copyright (c) 1996, 1997, 1998, 1999 }
- { [email protected] - primary e-mail address }
- { [email protected] - backup e-mail address }
- { }
- {****************[ THIS CODE IS FREEWARE ]*****************}
- { }
- { This sourcecode is released for the purpose to }
- { promote the pascal language on all platforms. You may }
- { redistribute it and/or modify with the following }
- { DISCLAIMER. }
- { }
- { This SOURCE CODE is distributed "AS IS" WITHOUT }
- { WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
- { ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
- { }
- {*****************[ SUPPORTED PLATFORMS ]******************}
- { 16 and 32 Bit compilers }
- { DOS - Turbo Pascal 7.0 + (16 Bit) }
- { DPMI - Turbo Pascal 7.0 + (16 Bit) }
- { - FPC 0.9912+ (GO32V2) (32 Bit) }
- { WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
- { - Delphi 1.0+ (16 Bit) }
- { WIN95/NT - Delphi 2.0+ (32 Bit) }
- { - Virtual Pascal 2.0+ (32 Bit) }
- { - Speedsoft Sybil 2.0+ (32 Bit) }
- { - FPC 0.9912+ (32 Bit) }
- { OS2 - Virtual Pascal 1.0+ (32 Bit) }
- { - Speed Pascal 1.0+ (32 Bit) }
- { - C'T patch to BP (16 Bit) }
- { }
- {*****************[ REVISION HISTORY ]*********************}
- { Version Date Fix }
- { ------- --------- --------------------------------- }
- { 1.00 12 Jun 96 First multi platform release }
- { 1.01 20 Jun 96 Fixes to TCollection }
- { 1.02 07 Aug 96 Fixed TStringCollection.Compare }
- { 1.10 18 Jul 97 Windows 95 support added. }
- { 1.11 21 Aug 97 FPC pascal 0.92 implemented }
- { 1.15 26 Aug 97 TXMSStream compatability added }
- { TEMSStream compatability added }
- { 1.30 29 Aug 97 Platform.inc sort added. }
- { 1.32 02 Sep 97 RegisterTypes completed. }
- { 1.37 04 Sep 97 TStream.Get & Put completed. }
- { 1.40 04 Sep 97 LongMul & LongDiv added. }
- { 1.45 04 Sep 97 Refined and passed all tests. }
- { FPC - bugged on register records! }
- { 1.50 05 May 98 Fixed DOS Access to files, one }
- { version for all intel platforms }
- { (CEC) }
- { 1.60 22 Oct 97 Delphi3 32 bit code added. }
- { 1.70 05 Feb 98 Speed pascal code added. }
- { 1.80 05 May 98 Virtual pascal 2.0 compiler added. }
- { 1.85 10 Sep 98 Checks run & commenting added. }
- { 1.90 03 Nov 98 Fixed for FPC version 0.998 }
- { Only Go32v2 supported no Go32v1 }
- { 1.95 02 Feb 99 Moved some stuff to common.pas }
- { 1.97 28 May 99 Bug fix to TCollection.AtInsert }
- { 1.98 07 Jul 99 Speedsoft SYBIL 2.0 code added. }
- { 1.99 08 Jul 99 Fixed TCollection FirstThat etc. }
- { 2.00 27 Oct 99 All stream read/writes checked. }
- { Delphi3+ memory code to COMMON.PAS }
- { 2.01 03 Nov 99 FPC windows support added. }
- {**********************************************************}
- UNIT Objects;
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- INTERFACE
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- {====Include file to sort compiler platform out =====================}
- {$I Platform.inc}
- {====================================================================}
- {==== Compiler directives ===========================================}
- {$IFNDEF PPC_FPC} { FPC doesn't support these switches }
- {$F+} { Force far calls - Used because of the Foreach, FirstThat etc...}
- {$A+} { Word Align Data }
- {$B-} { Allow short circuit boolean evaluations }
- {$O+} { This unit may be overlaid }
- {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
- {$E+} { Emulation is on }
- {$N-} { No 80x87 code generation }
- {$ENDIF}
- {$X+} { Extended syntax is ok }
- {$R-} { Disable range checking }
- {$S-} { Disable Stack Checking }
- {$I-} { Disable IO Checking }
- {$Q-} { Disable Overflow Checking }
- {$V-} { Turn off strict VAR strings }
- {====================================================================}
- USES
- {$IFDEF OS_WINDOWS} { WIN/NT CODE }
- {$IFNDEF PPC_SPEED} { NON SPEED COMPILER }
- {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
- Windows, { Standard unit }
- {$ELSE} { OTHER COMPILERS }
- WinTypes, WinProcs, { Stardard units }
- {$ENDIF}
- {$ELSE} { SPEEDSOFT COMPILER }
- WinBase, WinUser, { Standard unit }
- {$ENDIF}
- {$ENDIF}
- Common, FileIO; { GFV standard units }
- {***************************************************************************}
- { PUBLIC CONSTANTS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { STREAM ERROR STATE MASKS }
- {---------------------------------------------------------------------------}
- CONST
- stOk = 0; { No stream error }
- stError = -1; { Access error }
- stInitError = -2; { Initialize error }
- stReadError = -3; { Stream read error }
- stWriteError = -4; { Stream write error }
- stGetError = -5; { Get object error }
- stPutError = -6; { Put object error }
- stSeekError = -7; { Seek error in stream }
- stOpenError = -8; { Error opening stream }
- {---------------------------------------------------------------------------}
- { STREAM ACCESS MODE CONSTANTS }
- {---------------------------------------------------------------------------}
- CONST
- stCreate = fa_Create; { Create new file }
- stOpenRead = fa_OpenRead; { Read access only }
- stOpenWrite = fa_OpenWrite; { Write access only }
- stOpen = fa_Open; { Read/write access }
- {---------------------------------------------------------------------------}
- { TCollection ERROR CODES }
- {---------------------------------------------------------------------------}
- CONST
- coIndexError = -1; { Index out of range }
- coOverflow = -2; { Overflow }
- {---------------------------------------------------------------------------}
- { VMT HEADER CONSTANT - HOPEFULLY WE CAN DROP THIS LATER }
- {---------------------------------------------------------------------------}
- {$IFDEF PPC_Virtual} { Virtual is different }
- CONST
- vmtHeaderSize = 12; { VMT header size }
- {$ELSE}
- CONST
- vmtHeaderSize = 8; { VMT header size }
- {$ENDIF}
- {---------------------------------------------------------------------------}
- { MAXIUM DATA SIZES }
- {---------------------------------------------------------------------------}
- CONST
- MaxCollectionSize = 65520 DIV SizeOf(Pointer); { Max collection size }
- {***************************************************************************}
- { PUBLIC TYPE DEFINITIONS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { CHARACTER SET }
- {---------------------------------------------------------------------------}
- TYPE
- TCharSet = SET Of Char; { Character set }
- PCharSet = ^TCharSet; { Character set ptr }
- {---------------------------------------------------------------------------}
- { POINTER TO STRING }
- {---------------------------------------------------------------------------}
- TYPE
- PString = ^String; { String pointer }
- {---------------------------------------------------------------------------}
- { DOS FILENAME STRING }
- {---------------------------------------------------------------------------}
- TYPE
- {$IFDEF OS_DOS} { DOS/DPMI DEFINE }
- FNameStr = String[79]; { DOS filename }
- {$ENDIF}
- {$IFDEF OS_WINDOWS} { WIN/NT DEFINE }
- FNameStr = PChar; { Windows filename }
- {$ENDIF}
- {$IFDEF OS_OS2} { OS2 DEFINE }
- FNameStr = String; { OS2 filename }
- {$ENDIF}
- {$IFDEF OS_LINUX} { LINUX DEFINE }
- FNameStr = String; { Linux filename }
- {$ENDIF}
- {$IFDEF OS_AMIGA} { AMIGA DEFINE }
- FNameStr = String; { Amiga filename }
- {$ENDIF}
- {$IFDEF OS_ATARI} { ATARI DEFINE }
- FNameStr = String[79]; { Atari filename }
- {$ENDIF}
- {$IFDEF OS_MAC} { MACINTOSH DEFINE }
- FNameStr = String; { Mac filename }
- {$ENDIF}
- {---------------------------------------------------------------------------}
- { FILE HANDLE SIZE }
- {---------------------------------------------------------------------------}
- TYPE
- {$IFDEF OS_DOS} { DOS DEFINITION }
- THandle = Integer; { Handles are 16 bits }
- {$ENDIF}
- {$IFDEF OS_ATARI} { ATARI DEFINITION }
- THandle = Integer; { Handles are 16 bits }
- {$ENDIF}
- {$IFDEF OS_LINUX} { LINUX DEFINITIONS }
- { values are words, though the OS calls return 32-bit values }
- { to check (CEC) }
- THandle = LongInt; { Simulated 32 bits }
- {$ENDIF}
- {$IFDEF OS_AMIGA} { AMIGA DEFINITIONS }
- THandle = LongInt; { Handles are 32 bits }
- {$ENDIF}
- {$IFDEF OS_WINDOWS} { WIN/NT DEFINITIONS }
- THandle = sw_Integer; { Can be either }
- {$ENDIF}
- {$IFDEF OS_OS2} { OS2 DEFINITIONS }
- THandle = sw_Integer; { Can be either }
- {$ENDIF}
- {$IFDEF OS_MAC} { MACINTOSH DEFINITIONS }
- THandle = LongInt; { Handles are 32 bits }
- {$ENDIF}
- {***************************************************************************}
- { PUBLIC RECORD DEFINITIONS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { TYPE CONVERSION RECORDS }
- {---------------------------------------------------------------------------}
- TYPE
- WordRec = PACKED RECORD
- Lo, Hi: Byte; { Word to bytes }
- END;
- LongRec = PACKED RECORD
- Lo, Hi: Word; { LongInt to words }
- END;
- PtrRec = PACKED RECORD
- Ofs, Seg: Word; { Pointer to words }
- END;
- {---------------------------------------------------------------------------}
- { TStreamRec RECORD - STREAM OBJECT RECORD }
- {---------------------------------------------------------------------------}
- TYPE
- PStreamRec = ^TStreamRec; { Stream record ptr }
- TStreamRec = PACKED RECORD
- ObjType: Word; { Object type id }
- {$IFDEF BP_VmtLink}
- VmtLink: Sw_Word; { VMT link like BP }
- {$ELSE}
- VmtLink: Pointer; { Delphi3/FPC like VMT }
- {$ENDIF}
- Load : Pointer; { Object load code }
- Store: Pointer; { Object store code }
- Next : PStreamRec; { Next stream record }
- END;
- {***************************************************************************}
- { PUBLIC OBJECT DEFINITIONS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { TPoint OBJECT - POINT OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TPoint = OBJECT
- X, Y: Integer;
- END;
- PPoint = ^TPoint;
- {---------------------------------------------------------------------------}
- { TRect OBJECT - RECTANGLE OBJECT }
- {---------------------------------------------------------------------------}
- TRect = OBJECT
- A, B: TPoint; { Corner points }
- FUNCTION Empty: Boolean;
- FUNCTION Equals (R: TRect): Boolean;
- FUNCTION Contains (P: TPoint): Boolean;
- PROCEDURE Copy (R: TRect);
- PROCEDURE Union (R: TRect);
- PROCEDURE Intersect (R: TRect);
- PROCEDURE Move (ADX, ADY: Integer);
- PROCEDURE Grow (ADX, ADY: Integer);
- PROCEDURE Assign (XA, YA, XB, YB: Integer);
- END;
- PRect = ^TRect;
- {---------------------------------------------------------------------------}
- { TObject OBJECT - BASE ANCESTOR OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TObject = OBJECT
- CONSTRUCTOR Init;
- PROCEDURE Free;
- DESTRUCTOR Done; Virtual;
- END;
- PObject = ^TObject;
- { ******************************* REMARK ****************************** }
- { Two new virtual methods have been added to the object in the form of }
- { Close and Open. The main use here is in the Disk Based Descendants }
- { the calls open and close the given file so these objects can be }
- { used like standard files. Two new fields have also been added to }
- { speed up seeks on descendants. All existing code will compile and }
- { work completely normally oblivious to these new methods and fields. }
- { ****************************** END REMARK *** Leon de Boer, 15May96 * }
- {---------------------------------------------------------------------------}
- { TStream OBJECT - STREAM ANCESTOR OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TStream = OBJECT (TObject)
- Status : Integer; { Stream status }
- ErrorInfo : Integer; { Stream error info }
- StreamSize: LongInt; { Stream current size }
- Position : LongInt; { Current position }
- FUNCTION Get: PObject;
- FUNCTION StrRead: PChar;
- FUNCTION GetPos: LongInt; Virtual;
- FUNCTION GetSize: LongInt; Virtual;
- FUNCTION ReadStr: PString;
- PROCEDURE Open (OpenMode: Word); Virtual;
- PROCEDURE Close; Virtual;
- PROCEDURE Reset;
- PROCEDURE Flush; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Put (P: PObject);
- PROCEDURE StrWrite (P: PChar);
- PROCEDURE WriteStr (P: PString);
- PROCEDURE Seek (Pos: LongInt); Virtual;
- PROCEDURE Error (Code, Info: Integer); Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- PROCEDURE CopyFrom (Var S: TStream; Count: LongInt);
- END;
- PStream = ^TStream;
- { ******************************* REMARK ****************************** }
- { A few minor changes to this object and an extra field added called }
- { FName which holds an AsciiZ array of the filename this allows the }
- { streams file to be opened and closed like a normal text file. All }
- { existing code should work without any changes. }
- { ****************************** END REMARK *** Leon de Boer, 19May96 * }
- {---------------------------------------------------------------------------}
- { TDosStream OBJECT - DOS FILE STREAM OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TDosStream = OBJECT (TStream)
- Handle: THandle; { DOS file handle }
- FName : AsciiZ; { AsciiZ filename }
- CONSTRUCTOR Init (FileName: FNameStr; Mode: Word);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Close; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Seek (Pos: LongInt); Virtual;
- PROCEDURE Open (OpenMode: Word); Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- END;
- PDosStream = ^TDosStream;
- { ******************************* REMARK ****************************** }
- { A few minor changes to this object and an extra field added called }
- { lastmode which holds the read or write condition last using the }
- { speed up buffer which helps speed up the flush, position and size }
- { functions. All existing code should work without any changes. }
- { ****************************** END REMARK *** Leon de Boer, 19May96 * }
- {---------------------------------------------------------------------------}
- { TBufStream OBJECT - BUFFERED DOS FILE STREAM }
- {---------------------------------------------------------------------------}
- TYPE
- TBufStream = OBJECT (TDosStream)
- LastMode: Byte; { Last buffer mode }
- BufSize : Word; { Buffer size }
- BufPtr : Word; { Buffer start }
- BufEnd : Word; { Buffer end }
- Buffer : PByteArray; { Buffer allocated }
- CONSTRUCTOR Init (FileName: FNameStr; Mode, Size: Word);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Close; Virtual;
- PROCEDURE Flush; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Seek (Pos: LongInt); Virtual;
- PROCEDURE Open (OpenMode: Word); Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- END;
- PBufStream = ^TBufStream;
- { ******************************* REMARK ****************************** }
- { All the changes here should be completely transparent to existing }
- { code. Basically the memory blocks do not have to be base segments }
- { but this means our list becomes memory blocks rather than segments. }
- { The stream will also expand like the other standard streams!! }
- { ****************************** END REMARK *** Leon de Boer, 19May96 * }
- {---------------------------------------------------------------------------}
- { TMemoryStream OBJECT - MEMORY STREAM OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TMemoryStream = OBJECT (TStream)
- BlkCount: Word; { Number of segments }
- BlkSize : Word; { Memory block size }
- MemSize : LongInt; { Memory alloc size }
- BlkList : PPointerArray; { Memory block list }
- CONSTRUCTOR Init (ALimit: LongInt; ABlockSize: Word);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- PRIVATE
- FUNCTION ChangeListSize (ALimit: Word): Boolean;
- END;
- PMemoryStream = ^TMemoryStream;
- { ******************************* REMARK ****************************** }
- { This object under all but real mode DOS is simple a TMemoryStream }
- { by another name. Under real mode DOS programs it copies the standard }
- { standard EMS stream object as per Borland's original unit. }
- { ****************************** END REMARK *** Leon de Boer, 14Aug98 * }
- {---------------------------------------------------------------------------}
- { TEmsStream OBJECT - EMS STREAM OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- TEmsStream = OBJECT (TStream)
- Handle : Word; { EMS handle }
- PageCount: Word; { Pages allocated }
- MemSize : LongInt; { EMS alloc size }
- CONSTRUCTOR Init (MinSize, MaxSize: LongInt);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- END;
- {$ELSE} { DPMI/WIN/OS2 CODE }
- TEmsStream = OBJECT (TMemoryStream) { Memory stream object }
- CONSTRUCTOR Init (MinSize, MaxSize: LongInt);
- END;
- {$ENDIF}
- PEmsStream = ^TEmsStream; { EMS stream pointer }
- { ******************************* REMARK ****************************** }
- { This object under all but real mode DOS is simple a TMemoryStream }
- { by another name. Under real mode DOS programs it is a copy of the }
- { EMS stream object but using XMS, it can replace use of TEMSStream. }
- { ****************************** END REMARK *** Leon de Boer, 14Aug98 * }
- {---------------------------------------------------------------------------}
- { TXmsStream OBJECT - XMS STREAM OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- TXmsStream = OBJECT (TStream)
- Handle : Word; { XMS handle number }
- BlocksUsed: Word; { XMS blocks in use }
- MemSize : LongInt; { XMS alloc size }
- CONSTRUCTOR Init (MinSize, MaxSize: LongInt);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Truncate; Virtual;
- PROCEDURE Read (Var Buf; Count: Word); Virtual;
- PROCEDURE Write (Var Buf; Count: Word); Virtual;
- END;
- {$ELSE} { DPMI/WIN/NT/OS2 CODE }
- TXmsStream = OBJECT (TMemoryStream) { Memory stream object }
- CONSTRUCTOR Init (MinSize, MaxSize: LongInt);
- END;
- {$ENDIF}
- PXmsStream = ^TXmsStream; { XMS stream pointer }
- TYPE
- TItemList = Array [0..MaxCollectionSize - 1] Of Pointer;
- PItemList = ^TItemList;
- { ******************************* REMARK ****************************** }
- { The changes here look worse than they are. The Sw_Integer simply }
- { switches between Integers and LongInts if switched between 16 and 32 }
- { bit code. All existing code will compile without any changes. }
- { ****************************** END REMARK *** Leon de Boer, 10May96 * }
- {---------------------------------------------------------------------------}
- { TCollection OBJECT - COLLECTION ANCESTOR OBJECT }
- {---------------------------------------------------------------------------}
- TCollection = OBJECT (TObject)
- Items: PItemList; { Item list pointer }
- Count: Integer; { Item count }
- Limit: Integer; { Item limit count }
- Delta: Integer; { Inc delta size }
- CONSTRUCTOR Init (ALimit, ADelta: Integer);
- CONSTRUCTOR Load (Var S: TStream);
- DESTRUCTOR Done; Virtual;
- FUNCTION At (Index: Integer): Pointer;
- FUNCTION IndexOf (Item: Pointer): Integer; Virtual;
- FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
- FUNCTION LastThat (Test: Pointer): Pointer;
- FUNCTION FirstThat (Test: Pointer): Pointer;
- PROCEDURE Pack;
- PROCEDURE FreeAll;
- PROCEDURE DeleteAll;
- PROCEDURE Free (Item: Pointer);
- PROCEDURE Insert (Item: Pointer); Virtual;
- PROCEDURE Delete (Item: Pointer);
- PROCEDURE AtFree (Index: Integer);
- PROCEDURE FreeItem (Item: Pointer); Virtual;
- PROCEDURE AtDelete (Index: Integer);
- PROCEDURE ForEach (Action: Pointer);
- PROCEDURE SetLimit (ALimit: Integer); Virtual;
- PROCEDURE Error (Code, Info: Integer); Virtual;
- PROCEDURE AtPut (Index: Integer; Item: Pointer);
- PROCEDURE AtInsert (Index: Integer; Item: Pointer);
- PROCEDURE Store (Var S: TStream);
- PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
- END;
- PCollection = ^TCollection;
- {---------------------------------------------------------------------------}
- { TSortedCollection OBJECT - SORTED COLLECTION ANCESTOR }
- {---------------------------------------------------------------------------}
- TYPE
- TSortedCollection = OBJECT (TCollection)
- Duplicates: Boolean; { Duplicates flag }
- CONSTRUCTOR Init (ALimit, ADelta: Integer);
- CONSTRUCTOR Load (Var S: TStream);
- FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
- FUNCTION IndexOf (Item: Pointer): Integer; Virtual;
- FUNCTION Compare (Key1, Key2: Pointer): Integer; Virtual;
- FUNCTION Search (Key: Pointer; Var Index: Integer): Boolean; Virtual;
- PROCEDURE Insert (Item: Pointer); Virtual;
- PROCEDURE Store (Var S: TStream);
- END;
- PSortedCollection = ^TSortedCollection;
- {---------------------------------------------------------------------------}
- { TStringCollection OBJECT - STRING COLLECTION OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TStringCollection = OBJECT (TSortedCollection)
- FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
- FUNCTION Compare (Key1, Key2: Pointer): Integer; Virtual;
- PROCEDURE FreeItem (Item: Pointer); Virtual;
- PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
- END;
- PStringCollection = ^TStringCollection;
- {---------------------------------------------------------------------------}
- { TStrCollection OBJECT - STRING COLLECTION OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TStrCollection = OBJECT (TSortedCollection)
- FUNCTION Compare (Key1, Key2: Pointer): Integer; Virtual;
- FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
- PROCEDURE FreeItem (Item: Pointer); Virtual;
- PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
- END;
- PStrCollection = ^TStrCollection;
- { ******************************* REMARK ****************************** }
- { This is a completely >> NEW << object which holds a collection of }
- { strings but does not alphabetically sort them. It is a very useful }
- { object for insert ordered list boxes! }
- { ****************************** END REMARK *** Leon de Boer, 15May96 * }
- {---------------------------------------------------------------------------}
- { TUnSortedStrCollection - UNSORTED STRING COLLECTION OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TUnSortedStrCollection = OBJECT (TStringCollection)
- PROCEDURE Insert (Item: Pointer); Virtual;
- END;
- PUnSortedStrCollection = ^TUnSortedStrCollection;
- {---------------------------------------------------------------------------}
- { TResourceCollection OBJECT - RESOURCE COLLECTION OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TResourceCollection = OBJECT (TStringCollection)
- FUNCTION KeyOf (Item: Pointer): Pointer; Virtual;
- FUNCTION GetItem (Var S: TStream): Pointer; Virtual;
- PROCEDURE FreeItem (Item: Pointer); Virtual;
- PROCEDURE PutItem (Var S: TStream; Item: Pointer); Virtual;
- END;
- PResourceCollection = ^TResourceCollection;
- {---------------------------------------------------------------------------}
- { TResourceFile OBJECT - RESOURCE FILE OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TResourceFile = OBJECT (TObject)
- Stream : PStream; { File as a stream }
- Modified: Boolean; { Modified flag }
- CONSTRUCTOR Init (AStream: PStream);
- DESTRUCTOR Done; Virtual;
- FUNCTION Count: Integer;
- FUNCTION KeyAt (I: Integer): String;
- FUNCTION Get (Key: String): PObject;
- FUNCTION SwitchTo (AStream: PStream; Pack: Boolean): PStream;
- PROCEDURE Flush;
- PROCEDURE Delete (Key: String);
- PROCEDURE Put (Item: PObject; Key: String);
- PRIVATE
- BasePos: LongInt; { Base position }
- IndexPos: LongInt; { Index position }
- Index: TResourceCollection; { Index collection }
- END;
- PResourceFile = ^TResourceFile;
- TYPE
- TStrIndexRec = PACKED RECORD Key, Count, Offset: Word; END;
- TStrIndex = Array [0..9999] Of TStrIndexRec;
- PStrIndex = ^TStrIndex;
- {---------------------------------------------------------------------------}
- { TStringList OBJECT - STRING LIST OBJECT }
- {---------------------------------------------------------------------------}
- TStringList = OBJECT (TObject)
- CONSTRUCTOR Load (Var S: TStream);
- DESTRUCTOR Done; Virtual;
- FUNCTION Get (Key: Word): String;
- PRIVATE
- Stream : PStream;
- BasePos : LongInt;
- IndexSize: Sw_Word;
- Index : PStrIndex;
- PROCEDURE ReadStr (Var S: String; Offset, Skip: Word);
- END;
- PStringList = ^TStringList;
- {---------------------------------------------------------------------------}
- { TStrListMaker OBJECT - RESOURCE FILE OBJECT }
- {---------------------------------------------------------------------------}
- TYPE
- TStrListMaker = OBJECT (TObject)
- CONSTRUCTOR Init (AStrSize, AIndexSize: Word);
- DESTRUCTOR Done; Virtual;
- PROCEDURE Put (Key: Word; S: String);
- PROCEDURE Store (Var S: TStream);
- PRIVATE
- StrPos : Sw_Word;
- StrSize : Sw_Word;
- Strings : PByteArray;
- IndexPos : Sw_Word;
- IndexSize: Sw_Word;
- Index : PStrIndex;
- Cur : TStrIndexRec;
- PROCEDURE CloseCurrent;
- END;
- PStrListMaker = ^TStrListMaker;
- {***************************************************************************}
- { INTERFACE ROUTINES }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { STREAM INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-Abstract-----------------------------------------------------------
- Terminates program with a run-time error 211. When implementing
- an abstract object type, call Abstract in those virtual methods that
- must be overridden in descendant types. This ensures that any
- attempt to use instances of the abstract object type will fail.
- 12Jun96 LdB
- ---------------------------------------------------------------------}
- PROCEDURE Abstract;
- {-RegisterObjects----------------------------------------------------
- Registers the three standard objects TCollection, TStringCollection
- and TStrCollection.
- 02Sep97 LdB
- ---------------------------------------------------------------------}
- PROCEDURE RegisterObjects;
- {-RegisterType-------------------------------------------------------
- Registers the given object type with Free Vision's streams, creating
- a list of known objects. Streams can only store and return these known
- object types. Each registered object needs a unique stream registration
- record, of type TStreamRec.
- 02Sep97 LdB
- ---------------------------------------------------------------------}
- PROCEDURE RegisterType (Var S: TStreamRec);
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { GENERAL FUNCTION INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-LongMul------------------------------------------------------------
- Returns the long integer value of X * Y integer values.
- 10Feb98 LdB
- ---------------------------------------------------------------------}
- FUNCTION LongMul (X, Y: Integer): LongInt;
- {-LongDiv------------------------------------------------------------
- Returns the integer value of long integer X divided by integer Y.
- 10Feb98 LdB
- ---------------------------------------------------------------------}
- FUNCTION LongDiv (X: LongInt; Y: Integer): Integer;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { DYNAMIC STRING INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-NewStr-------------------------------------------------------------
- Allocates a dynamic string into memory. If S is nil, NewStr returns
- a nil pointer, otherwise NewStr allocates Length(S)+1 bytes of memory
- containing a copy of S, and returns a pointer to the string.
- 12Jun96 LdB
- ---------------------------------------------------------------------}
- FUNCTION NewStr (S: String): PString;
- {-DisposeStr---------------------------------------------------------
- Disposes of a PString allocated by the function NewStr.
- 12Jun96 LdB
- ---------------------------------------------------------------------}
- PROCEDURE DisposeStr (P: PString);
- {***************************************************************************}
- { PUBLIC INITIALIZED VARIABLES }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { INITIALIZED DOS/DPMI/WIN/NT/OS2 PUBLIC VARIABLES }
- {---------------------------------------------------------------------------}
- CONST
- StreamError : Pointer = Nil; { Stream error ptr }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { STREAM REGISTRATION RECORDS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {---------------------------------------------------------------------------}
- { TCollection STREAM REGISTRATION }
- {---------------------------------------------------------------------------}
- CONST
- RCollection: TStreamRec = (
- ObjType: 50; { Register id = 50 }
- {$IFDEF BP_VMTLink}
- VmtLink: Ofs(TypeOf(TCollection)^); { BP style VMT link }
- {$ELSE}
- VmtLink: TypeOf(TCollection); { Alt style VMT link }
- {$ENDIF}
- Load: @TCollection.Load; { Object load method }
- Store: @TCollection.Store); { Object store method }
- {---------------------------------------------------------------------------}
- { TStringCollection STREAM REGISTRATION }
- {---------------------------------------------------------------------------}
- CONST
- RStringCollection: TStreamRec = (
- ObjType: 51; { Register id = 51 }
- {$IFDEF BP_VMTLink}
- VmtLink: Ofs(TypeOf(TStringCollection)^); { BP style VMT link }
- {$ELSE}
- VmtLink: TypeOf(TStringCollection); { Alt style VMT link }
- {$ENDIF}
- Load: @TStringCollection.Load; { Object load method }
- Store: @TStringCollection.Store); { Object store method }
- {---------------------------------------------------------------------------}
- { TStrCollection STREAM REGISTRATION }
- {---------------------------------------------------------------------------}
- CONST
- RStrCollection: TStreamRec = (
- ObjType: 69; { Register id = 69 }
- {$IFDEF BP_VMTLink}
- VmtLink: Ofs(TypeOf(TStrCollection)^); { BP style VMT link }
- {$ELSE}
- VmtLink: TypeOf(TStrCollection); { Alt style VMT link }
- {$ENDIF}
- Load: @TStrCollection.Load; { Object load method }
- Store: @TStrCollection.Store); { Object store method }
- {---------------------------------------------------------------------------}
- { TStringList STREAM REGISTRATION }
- {---------------------------------------------------------------------------}
- CONST
- RStringList: TStreamRec = (
- ObjType: 52; { Register id = 52 }
- {$IFDEF BP_VMTLink}
- VmtLink: Ofs(TypeOf(TStringList)^); { BP style VMT link }
- {$ELSE}
- VmtLink: TypeOf(TStringList); { Alt style VMT link }
- {$ENDIF}
- Load: @TStringList.Load; { Object load method }
- Store: Nil); { No store method }
- {---------------------------------------------------------------------------}
- { TStrListMaker STREAM REGISTRATION }
- {---------------------------------------------------------------------------}
- CONST
- RStrListMaker: TStreamRec = (
- ObjType: 52; { Register id = 52 }
- {$IFDEF BP_VMTLink}
- VmtLink: Ofs(TypeOf(TStrListMaker)^); { BP style VMT link }
- {$ELSE}
- VmtLink: TypeOf(TStrListMaker); { Alt style VMT link }
- {$ENDIF}
- Load: Nil; { No load method }
- Store: @TStrListMaker.Store); { Object store method }
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- IMPLEMENTATION
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- USES XMSUnit, EMSUnit; { Needs these units }
- {$ENDIF}
- {$IFNDEF PROC_Real} { NOT DOS REAL CODE }
- {$DEFINE NewExeFormat} { New format EXE }
- {$ENDIF}
- {$IFDEF OS_OS2} { OS2 COMPILERS }
- {$IFDEF PPC_Virtual} { VIRTUAL PASCAL UNITS }
- USES OS2Base; { Standard unit }
- {$ENDIF}
- {$IFDEF PPC_Speed} { SPEED PASCAL UNITS }
- USES BseDos, Os2Def; { Standard units }
- {$ENDIF}
- {$IFDEF PPC_BPOS2} { C'T PATCH TO BP UNITS }
- USES DosTypes, DosProcs; { Standard units }
- TYPE FILEFINDBUF = TFILEFINDBUF; { Type correction }
- {$ENDIF}
- {$ENDIF}
- {***************************************************************************}
- { PRIVATE TYPE DEFINITIONS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { FRAME POINTER SIZE SWITCH TYPE }
- {---------------------------------------------------------------------------}
- TYPE
- FramePointer = sw_Word; { Frame pointer }
- { ******************************* REMARK ****************************** }
- { This TYPECAST is serverely COMPILER SPECIFIC if you have a different }
- { compiler you will probably have to work this out. }
- { ****************************** END REMARK *** Leon de Boer, 08Jul99 * }
- {---------------------------------------------------------------------------}
- { POINTER LOCAl FUNCTION DEFINITION SWITCH }
- {---------------------------------------------------------------------------}
- TYPE
- {$IFDEF PPC_VIRTUAL} { VIRTUAL PASCAL }
- FuncCallPtr = FUNCTION (Param1: Pointer): Boolean;
- {$ELSE} { OTHER COMPILERS }
- {$IFNDEF PPC_FPC} { NON FPC COMPILERS }
- FuncCallPtr = FUNCTION (Param1: Pointer; _EBP: FramePointer): Boolean;
- {$ELSE} { FPC COMPILER }
- FuncCallPtr = FUNCTION (_EBP: FramePointer; Param1: Pointer): Boolean;
- {$ENDIF}
- {$ENDIF}
- {***************************************************************************}
- { PRIVATE INITIALIZED VARIABLES }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { INITIALIZED DOS/DPMI/WIN/NT/OS2 PRIVATE VARIABLES }
- {---------------------------------------------------------------------------}
- CONST
- StreamTypes: PStreamRec = Nil; { Stream types reg }
- {***************************************************************************}
- { PRIVATE INTERNAL ROUTINES }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { PRIVATE INTERNAL DOS/DPMI/WIN/NT/OS2 ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { ******************************* REMARK ****************************** }
- { This routine is serverely COMPILER SPECIFIC if you have a different }
- { compiler you will probably have to work this out. }
- { ****************************** END REMARK *** Leon de Boer, 08Jul99 * }
- {---------------------------------------------------------------------------}
- { PrevFramePtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION PrevFramePtr: FramePointer; ASSEMBLER;
- {$IFNDEF PPC_FPC} { NON FPC COMPILER }
- ASM
- {$IFDEF BIT_16} { 16 BIT CODE }
- MOV AX, [BP]; { Load AX from BP }
- {$IFDEF OS_WINDOWS} { WIN 16 BIT CODE }
- AND AL, 0FEH; { Windows make even }
- {$ENDIF}
- {$IFDEF OS_OS2} { OS2 16 BIT CODE }
- AND AL, 0FEH; { OS2 make even }
- {$ENDIF}
- {$ENDIF}
- {$IFDEF BIT_32} { 32 BIT CODE }
- MOV EAX, [EBP]; { Get previous frame }
- {$ENDIF}
- END;
- {$ELSE} { FPC COMPILER }
- ASM
- {$IFDEF i386} { 80x PROCESSOR }
- MOVL (%EBP), %EAX; { Get previous frame }
- {$ENDIF}
- {$IFDEF m68k} { 68x PROCESSOR }
- MOVE.L A6, D0; { Get previous frame }
- {$ENDIF}
- END ['EAX'];
- {$ENDIF}
- { ******************************* REMARK ****************************** }
- { This routine is serverely COMPILER SPECIFIC if you have a different }
- { compiler you will probably have to work this out. }
- { ****************************** END REMARK *** Leon de Boer, 08Jul99 * }
- {---------------------------------------------------------------------------}
- { CallPointerLocal -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- {$IFDEF PPC_VIRTUAL} { VIRTUAL COMPILER }
- FUNCTION CallTestLocal (Func: Pointer; Param1: Pointer): Boolean;
- BEGIN
- CallTestLocal := FuncCallPtr(Func)(Param1); { Function call to ptr }
- END;
- {$ELSE} { OTHER COMPILERS }
- FUNCTION CallTestLocal (Func: Pointer; Frame: FramePointer;
- Param1: Pointer): Boolean;
- BEGIN
- {$IFNDEF PPC_FPC} { NON FPC COMPILERS }
- CallTestLocal := FuncCallPtr(Func)(Param1, Frame); { Function call to ptr }
- {$ELSE} { FPC COMPILER }
- CallTestLocal := FuncCallPtr(Func)(Frame, Param1); { Function call to ptr }
- {$ENDIF}
- END;
- {$ENDIF}
- {---------------------------------------------------------------------------}
- { RegisterError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE RegisterError;
- BEGIN
- RunError(212); { Register error }
- END;
- {***************************************************************************}
- { OBJECT METHODS }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TRect OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- PROCEDURE CheckEmpty (Var Rect: TRect);
- BEGIN
- With Rect Do Begin
- If (A.X >= B.X) OR (A.Y >= B.Y) Then Begin { Zero or reversed }
- A.X := 0; { Clear a.x }
- A.Y := 0; { Clear a.y }
- B.X := 0; { Clear b.x }
- B.Y := 0; { Clear b.y }
- End;
- End;
- END;
- {--TRect--------------------------------------------------------------------}
- { Empty -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TRect.Empty: Boolean;
- BEGIN
- Empty := (A.X >= B.X) OR (A.Y >= B.Y); { Empty result }
- END;
- {--TRect--------------------------------------------------------------------}
- { Equals -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TRect.Equals (R: TRect): Boolean;
- BEGIN
- Equals := (A.X = R.A.X) AND (A.Y = R.A.Y) AND
- (B.X = R.B.X) AND (B.Y = R.B.Y); { Equals result }
- END;
- {--TRect--------------------------------------------------------------------}
- { Contains -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TRect.Contains (P: TPoint): Boolean;
- BEGIN
- Contains := (P.X >= A.X) AND (P.X <= B.X) AND
- (P.Y >= A.Y) AND (P.Y <= B.Y); { Contains result }
- END;
- {--TRect--------------------------------------------------------------------}
- { Copy -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Copy (R: TRect);
- BEGIN
- A := R.A; { Copy point a }
- B := R.B; { Copy point b }
- END;
- {--TRect--------------------------------------------------------------------}
- { Union -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Union (R: TRect);
- BEGIN
- If (R.A.X < A.X) Then A.X := R.A.X; { Take if smaller }
- If (R.A.Y < A.Y) Then A.Y := R.A.Y; { Take if smaller }
- If (R.B.X > B.X) Then B.X := R.B.X; { Take if larger }
- If (R.B.Y > B.Y) Then B.Y := R.B.Y; { Take if larger }
- END;
- {--TRect--------------------------------------------------------------------}
- { Intersect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Intersect (R: TRect);
- BEGIN
- If (R.A.X > A.X) Then A.X := R.A.X; { Take if larger }
- If (R.A.Y > A.Y) Then A.Y := R.A.Y; { Take if larger }
- If (R.B.X < B.X) Then B.X := R.B.X; { Take if smaller }
- If (R.B.Y < B.Y) Then B.Y := R.B.Y; { Take if smaller }
- CheckEmpty(Self); { Check if empty }
- END;
- {--TRect--------------------------------------------------------------------}
- { Move -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Move (ADX, ADY: Integer);
- BEGIN
- Inc(A.X, ADX); { Adjust A.X }
- Inc(A.Y, ADY); { Adjust A.Y }
- Inc(B.X, ADX); { Adjust B.X }
- Inc(B.Y, ADY); { Adjust B.Y }
- END;
- {--TRect--------------------------------------------------------------------}
- { Grow -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Grow (ADX, ADY: Integer);
- BEGIN
- Dec(A.X, ADX); { Adjust A.X }
- Dec(A.Y, ADY); { Adjust A.Y }
- Inc(B.X, ADX); { Adjust B.X }
- Inc(B.Y, ADY); { Adjust B.Y }
- CheckEmpty(Self); { Check if empty }
- END;
- {--TRect--------------------------------------------------------------------}
- { Assign -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TRect.Assign (XA, YA, XB, YB: Integer);
- BEGIN
- A.X := XA; { Hold A.X value }
- A.Y := YA; { Hold A.Y value }
- B.X := XB; { Hold B.X value }
- B.Y := YB; { Hold B.Y value }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TObject OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- TYPE
- DummyObject = OBJECT (TObject) { Internal object }
- Data: RECORD END; { Helps size VMT link }
- END;
- { ******************************* REMARK ****************************** }
- { I Prefer this code because it self sizes VMT link rather than using a }
- { fixed record structure thus it should work on all compilers without a }
- { specific record to match each compiler. }
- { ****************************** END REMARK *** Leon de Boer, 10May96 * }
- {--TObject------------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TObject.Init;
- VAR LinkSize: LongInt; Dummy: DummyObject; P: Pointer;
- BEGIN
- LinkSize := LongInt(@Dummy.Data)-LongInt(@Dummy); { Calc VMT link size }
- P := Pointer(LongInt(@Self)+LinkSize); { Pointer to data }
- FillChar(P^, SizeOf(Self)-LinkSize, #0); { Clear data fields }
- END;
- {--TObject------------------------------------------------------------------}
- { Free -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TObject.Free;
- BEGIN
- Dispose(PObject(@Self), Done); { Dispose of self }
- END;
- {--TObject------------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TObject.Done;
- BEGIN { Abstract method }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TStream OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TStream------------------------------------------------------------------}
- { Get -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14Aug98 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStream.Get: PObject;
- TYPE LoadPtr = FUNCTION (Var S: TStream; Link: Sw_Word; Iv: Pointer): PObject;
- VAR ObjType: Word; P: PStreamRec;
- BEGIN
- ObjType := 0; { Zero the value }
- Read(ObjType, 2); { Read object type }
- If (ObjType <> 0) Then Begin { Object registered }
- P := StreamTypes; { Current reg list }
- While (P <> Nil) AND (P^.ObjType <> ObjType) { Find object type OR }
- Do P := P^.Next; { Find end of chain }
- If (P = Nil) Then Begin { Not registered }
- Error(stGetError, ObjType); { Obj not registered }
- Get := Nil; { Return nil pointer }
- End Else
- {$IFDEF BP_VMTLink} { BP like VMT link }
- Get := LoadPtr(P^.Load)(Self, P^.VMTLink, Nil) { Call constructor }
- {$ELSE} { FPC/DELPHI3 VMT link }
- Get := LoadPtr(P^.Load)(Self,
- Sw_Word(P^.VMTLink^), Nil) { Call constructor }
- {$ENDIF}
- End Else Get := Nil; { Return nil pointer }
- END;
- {--TStream------------------------------------------------------------------}
- { StrRead -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStream.StrRead: PChar;
- VAR W: Word; P: PChar;
- BEGIN
- W := 0; { Zero the value }
- Read(W, 2); { Read string length }
- If (W = 0) Then StrRead := Nil Else Begin { Check for empty }
- If (MaxAvail >= (W+1)) Then Begin { Check avail memory }
- GetMem(P, W + 1); { Allocate memory }
- Read(P[0], W); { Read the data }
- P[W] := #0; { Terminate with #0 }
- End Else P := Nil; { Not enough memory }
- StrRead := P; { PChar returned }
- End;
- END;
- {--TStream------------------------------------------------------------------}
- { ReadStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Aug98 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStream.ReadStr: PString;
- VAR B: Byte; P: PString;
- BEGIN
- Read(B, 1); { Read string length }
- If (B > 0) AND (MaxAvail >= (B+1)) Then Begin { Check enough memory }
- GetMem(P, B + 1); { Allocate memory }
- {$IFDEF PPC_DELPHI3} { DELPHI 3+ COMPILER }
- SetLength(P^, B); { Hold new length }
- {$ELSE} { OTHER COMPILERS }
- P^[0] := Chr(B); { Hold new length }
- {$ENDIF}
- Read(P^[1], B); { Read string data }
- ReadStr := P; { Return string ptr }
- End Else ReadStr := Nil;
- END;
- {--TStream------------------------------------------------------------------}
- { GetPos -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStream.GetPos: LongInt;
- BEGIN
- If (Status = stOk) Then GetPos := Position { Return position }
- Else GetPos := -1; { Stream in error }
- END;
- {--TStream------------------------------------------------------------------}
- { GetSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStream.GetSize: LongInt;
- BEGIN
- If (Status = stOk) Then GetSize := StreamSize { Return stream size }
- Else GetSize := -1; { Stream in error }
- END;
- {--TStream------------------------------------------------------------------}
- { Close -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Close;
- BEGIN { Abstract method }
- END;
- {--TStream------------------------------------------------------------------}
- { Reset -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Reset;
- BEGIN
- Status := 0; { Clear status }
- ErrorInfo := 0; { Clear error info }
- END;
- {--TStream------------------------------------------------------------------}
- { Flush -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Flush;
- BEGIN { Abstract method }
- END;
- {--TStream------------------------------------------------------------------}
- { Truncate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Truncate;
- BEGIN
- Abstract; { Abstract error }
- END;
- {--TStream------------------------------------------------------------------}
- { Get -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14Aug98 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Put (P: PObject);
- TYPE StorePtr = PROCEDURE (Var S: TStream; AnObject: PObject);
- VAR ObjType: Word; Link: Sw_Word; Q: PStreamRec; VmtPtr: ^Sw_Word;
- BEGIN
- ObjType := 0; { Set objtype to zero }
- If (P <> Nil) Then Begin { Non nil object }
- VmtPtr := Pointer(P); { Xfer object to ptr }
- Link := VmtPtr^; { VMT link }
- If (Link <> 0) Then Begin { We have a VMT link }
- Q := StreamTypes; { Current reg list }
- {$IFDEF BP_VMTLink} { BP like VMT link }
- While (Q <> Nil) AND (Q^.VMTLink <> Link) { Find link match OR }
- {$ELSE} { FPC/DELHI3 VMT link }
- While (Q <> Nil) AND (Sw_Word(Q^.VMTLink^) <>
- Link) { Find link match OR }
- {$ENDIF}
- Do Q := Q^.Next; { Find end of chain }
- If (Q = Nil) Then Begin { End of chain found }
- Error(stPutError, 0); { Not registered error }
- Exit; { Now exit }
- End Else ObjType := Q^.ObjType; { Update object type }
- End;
- End;
- Write(ObjType, 2); { Write object type }
- If (ObjType <> 0) Then { Registered object }
- StorePtr(Q^.Store)(Self, P); { Store object }
- END;
- {--TStream------------------------------------------------------------------}
- { Seek -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Seek (Pos: LongInt);
- BEGIN
- If (Status = stOk) Then Begin { Check status }
- If (Pos < 0) Then Pos := 0; { Remove negatives }
- If (Pos <= StreamSize) Then Position := Pos { If valid set pos }
- Else Error(stSeekError, Pos); { Position error }
- End;
- END;
- {--TStream------------------------------------------------------------------}
- { StrWrite -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.StrWrite (P: PChar);
- VAR W: Word; Q: PByteArray;
- BEGIN
- W := 0; { Preset zero size }
- Q := PByteArray(P); { Transfer type }
- If (Q <> Nil) Then While (Q^[W] <> 0) Do Inc(W); { PChar length }
- Write(W, SizeOf(W)); { Store length }
- If (P <> Nil) Then Write(P[0], W); { Write data }
- END;
- {--TStream------------------------------------------------------------------}
- { WriteStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.WriteStr (P: PString);
- CONST Empty: String[1] = '';
- BEGIN
- If (P <> Nil) Then Write(P^, Length(P^) + 1) { Write string }
- Else Write(Empty, 1); { Write empty string }
- END;
- {--TStream------------------------------------------------------------------}
- { Open -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Open (OpenMode: Word);
- BEGIN { Abstract method }
- END;
- {--TStream------------------------------------------------------------------}
- { Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Error (Code, Info: Integer);
- TYPE TErrorProc = Procedure (Var S: TStream);
- BEGIN
- Status := Code; { Hold error code }
- ErrorInfo := Info; { Hold error info }
- If (StreamError <> Nil) Then
- TErrorProc(StreamError)(Self); { Call error ptr }
- END;
- {--TStream------------------------------------------------------------------}
- { Read -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Read (Var Buf; Count: Word);
- BEGIN
- Abstract; { Abstract error }
- END;
- {--TStream------------------------------------------------------------------}
- { Write -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.Write (Var Buf; Count: Word);
- BEGIN
- Abstract; { Abstract error }
- END;
- {--TStream------------------------------------------------------------------}
- { CopyFrom -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStream.CopyFrom (Var S: TStream; Count: LongInt);
- VAR W: Word; Buffer: Array[0..1023] of Byte;
- BEGIN
- While (Count > 0) Do Begin
- If (Count > SizeOf(Buffer)) Then { To much data }
- W := SizeOf(Buffer) Else W := Count; { Size to transfer }
- S.Read(Buffer, W); { Read from stream }
- Write(Buffer, W); { Write to stream }
- Dec(Count, W); { Dec write count }
- End;
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TDosStream OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TDosStream---------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TDosStream.Init (FileName: FNameStr; Mode: Word);
- VAR Success: Integer; {$IFDEF OS_OS2} Info: FILEFINDBUF; {$ENDIF}
- BEGIN
- Inherited Init; { Call ancestor }
- {$IFDEF OS_WINDOWS} { WIN/NT CODE }
- {$IFDEF BIT_16} { 16 BIT WINDOWS CODE }
- AnsiToOEM(FileName, FName); { Ansi to OEM }
- {$ENDIF}
- {$IFDEF BIT_32} { 32 BIT WINDOWS CODE }
- {$IFNDEF PPC_SPEED} { NON SPEED COMPILER }
- CharToOEM(FileName, FName); { Ansi to OEM }
- {$ELSE} { SPEEDSOFT SYBIL 2+ }
- CharToOEM(CString(FileName), CString(FName)); { Ansi to OEM }
- {$ENDIF}
- {$ENDIF}
- {$ELSE} { DOS/DPMI/OS2 CODE }
- FileName := FileName+#0; { Make asciiz }
- Move(FileName[1], FName, Length(FileName)); { Create asciiz name }
- {$ENDIF}
- Handle := FileOpen(FName, Mode); { Open the file }
- If (Handle <> 0) Then Begin { Handle valid }
- Success := SetFilePos(Handle, 0, 2, StreamSize); { Locate end of file }
- If (Success = 0) Then
- Success := SetFilePos(Handle, 0, 0, Position); { Reset to file start }
- End Else Success := 103; { Open file failed }
- If (Handle = 0) OR (Success <> 0) Then Begin { Open failed }
- Handle := -1; { Reset invalid handle }
- Error(stInitError, Success); { Call stream error }
- End;
- END;
- {--TDosStream---------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 16May96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TDosStream.Done;
- BEGIN
- If (Handle <> -1) Then FileClose(Handle); { Close the file }
- Inherited Done; { Call ancestor }
- END;
- {--TDosStream---------------------------------------------------------------}
- { Close -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 16May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Close;
- BEGIN
- If (Handle <> -1) Then FileClose(Handle); { Close the file }
- Position := 0; { Zero the position }
- Handle := -1; { Handle now invalid }
- END;
- {--TDosStream---------------------------------------------------------------}
- { Truncate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 16May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Truncate;
- VAR Success: Integer;
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- Success := SetFileSize(Handle, Position); { Truncate file }
- If (Success = 0) Then StreamSize := Position { Adjust size }
- Else Error(stError, Success); { Identify error }
- End;
- END;
- {--TDosStream---------------------------------------------------------------}
- { Seek -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 16May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Seek (Pos: LongInt);
- VAR Success: Integer; Li: LongInt;
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Pos < 0) Then Pos := 0; { Negatives removed }
- If (Handle = -1) Then Success := 103 Else { File not open }
- Success := SetFilePos(Handle, Pos, 0, Li); { Set file position }
- If ((Success = -1) OR (Li <> Pos)) Then Begin { We have an error }
- If (Success = -1) Then Error(stSeekError, 0) { General seek error }
- Else Error(stSeekError, Success); { Specific seek error }
- End Else Position := Li; { Adjust position }
- End;
- END;
- {--TDosStream---------------------------------------------------------------}
- { Open -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 16May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Open (OpenMode: Word);
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Handle = -1) Then Begin { File not open }
- Handle := FileOpen(FName, OpenMode); { Open the file }
- Position := 0; { Reset position }
- If (Handle = 0) Then Begin { File open failed }
- Handle := -1; { Reset handle }
- Error(stOpenError, 103); { Call stream error }
- End;
- End Else Error(stOpenError, 104); { File already open }
- End;
- END;
- {--TDosStream---------------------------------------------------------------}
- { Read -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Read (Var Buf; Count: Word);
- VAR Success: Integer; Ri, W: Word; Moved: Sw_Word; P: PByteArray;
- BEGIN
- If (Position + Count > StreamSize) Then { Insufficient data }
- Error(stReadError, 0); { Read beyond end!!! }
- If (Handle = -1) Then Error(stReadError, 103); { File not open }
- P := @Buf; { Transfer address }
- Ri := 0; { Zero read index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := FileRead(Handle, P^[Ri], W, Moved); { Read from file }
- If ((Success <> 0) OR (Moved <> W)) { Error was detected }
- Then Begin
- Moved := 0; { Clear bytes moved }
- If (Success <> 0) Then
- Error(stReadError, Success) { Specific read error }
- Else Error(stReadError, 0); { Non specific error }
- End;
- Inc(Position, Moved); { Adjust position }
- Inc(Ri, Moved); { Adjust read index }
- Dec(Count, Moved); { Adjust count left }
- End;
- If (Count <> 0) Then FillChar(P^[Ri], Count, #0); { Error clear buffer }
- END;
- {--TDosStream---------------------------------------------------------------}
- { Write -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TDosStream.Write (Var Buf; Count: Word);
- VAR Success: Integer; W, Wi: Word; Moved: Sw_Word; P: PByteArray;
- BEGIN
- If (Handle = -1) Then Error(stWriteError, 103); { File not open }
- P := @Buf; { Transfer address }
- Wi := 0; { Zero write index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := FileWrite(Handle, P^[Wi], W, Moved); { Write to file }
- If ((Success <> 0) OR (Moved <> W)) { Error was detected }
- Then Begin
- Moved := 0; { Clear bytes moved }
- If (Success <> 0) Then
- Error(stWriteError, Success) { Specific write error }
- Else Error(stWriteError, 0); { Non specific error }
- End;
- Inc(Position, Moved); { Adjust position }
- Inc(Wi, Moved); { Adjust write index }
- Dec(Count, Moved); { Adjust count left }
- If (Position > StreamSize) Then { File expanded }
- StreamSize := Position; { Adjust stream size }
- End;
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TBufStream OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TBufStream---------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TBufStream.Init (FileName: FNameStr; Mode, Size: Word);
- BEGIN
- Inherited Init(FileName, Mode); { Call ancestor }
- If (Size <> 0) AND (MaxAvail >= Size) Then Begin
- GetMem(Buffer, Size); { Allocate buffer }
- BufSize := Size; { Hold buffer size }
- End;
- If (Buffer = Nil) Then Error(stInitError, 0); { Buffer allocate fail }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TBufStream.Done;
- BEGIN
- Flush; { Flush the file }
- Inherited Done; { Call ancestor }
- If (Buffer <> Nil) Then FreeMem(Buffer, BufSize); { Release buffer }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Close -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Close;
- BEGIN
- Flush; { Flush the buffer }
- Inherited Close; { Call ancestor }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Flush -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Flush;
- VAR Success: Integer; W: Sw_Word;
- BEGIN
- If (LastMode = 2) AND (BufPtr <> 0) Then Begin { Must update file }
- If (Handle = -1) Then Success := 103 { File is not open }
- Else Success := FileWrite(Handle, Buffer^,
- BufPtr, W); { Write to file }
- If (Success <> 0) OR (W <> BufPtr) Then { We have an error }
- If (Success = 0) Then Error(stWriteError, 0) { Unknown write error }
- Else Error(stError, Success); { Specific write error }
- End;
- BufPtr := 0; { Reset buffer ptr }
- BufEnd := 0; { Reset buffer end }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Truncate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Truncate;
- BEGIN
- Flush; { Flush buffer }
- Inherited Truncate; { Truncate file }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Seek -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Seek (Pos: LongInt);
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Position <> Pos) Then Begin { Move required }
- Flush; { Flush the buffer }
- Inherited Seek(Pos); { Call ancestor }
- End;
- End;
- END;
- {--TBufStream---------------------------------------------------------------}
- { Open -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Open (OpenMode: Word);
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- BufPtr := 0; { Clear buffer start }
- BufEnd := 0; { Clear buffer end }
- Inherited Open(OpenMode); { Call ancestor }
- End;
- END;
- {--TBufStream---------------------------------------------------------------}
- { Read -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Read (Var Buf; Count: Word);
- VAR Success: Integer; W, Bw, Ri: Word; Br: Sw_Word; P: PByteArray;
- BEGIN
- If (Position + Count > StreamSize) Then { Read pas stream end }
- Error(stReadError, 0); { Call stream error }
- If (Handle = -1) Then Error(stReadError, 103); { File not open }
- P := @Buf; { Transfer address }
- Ri := 0; { Zero read index }
- If (LastMode = 2) Then Flush; { Flush write buffer }
- LastMode := 1; { Now set read mode }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- If (BufPtr = BufEnd) Then Begin { Buffer is empty }
- If (Position + BufSize > StreamSize) Then
- Bw := StreamSize - Position { Amount of file left }
- Else Bw := BufSize; { Full buffer size }
- Success := FileRead(Handle, Buffer^, Bw, Br); { Read from file }
- If ((Success <> 0) OR (Bw <> Br)) Then Begin { Error was detected }
- If (Success <> 0) Then
- Error(stReadError, Success) { Specific read error }
- Else Error(stReadError, 0); { Non specific error }
- End Else Begin
- BufPtr := 0; { Reset BufPtr }
- BufEnd := Bw; { End of buffer }
- End;
- End;
- If (Status = stOk) Then Begin { Status still okay }
- W := BufEnd - BufPtr; { Space in buffer }
- If (Count < W) Then W := Count; { Set transfer size }
- Move(Buffer^[BufPtr], P^[Ri], W); { Data from buffer }
- Dec(Count, W); { Reduce count }
- Inc(BufPtr, W); { Advance buffer ptr }
- Inc(Ri, W); { Increase read index }
- Inc(Position, W); { Advance position }
- End;
- End;
- If (Status <> stOk) AND (Count > 0) Then
- FillChar(P^[Ri], Count, #0); { Error clear buffer }
- END;
- {--TBufStream---------------------------------------------------------------}
- { Write -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TBufStream.Write (Var Buf; Count: Word);
- VAR Success: Integer; W, Wi: Word; Bw: Sw_Word; P: PByteArray;
- BEGIN
- If (Handle = -1) Then Error(stWriteError, 103); { File not open }
- If (LastMode = 1) Then Flush; { Flush read buffer }
- LastMode := 2; { Now set write mode }
- P := @Buf; { Transfer address }
- Wi := 0; { Zero write index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- If (BufPtr = BufSize) Then Begin { Buffer is full }
- Success := FileWrite(Handle, Buffer^, BufSize,
- Bw); { Write to file }
- If (Success <> 0) OR (Bw <> BufSize) Then { We have an error }
- If (Success=0) Then Error(stWriteError, 0) { Unknown write error }
- Else Error(stError, Success); { Specific write error }
- BufPtr := 0; { Reset BufPtr }
- End;
- If (Status = stOk) Then Begin { Status still okay }
- W := BufSize - BufPtr; { Space in buffer }
- If (Count < W) Then W := Count; { Transfer size }
- Move(P^[Wi], Buffer^[BufPtr], W); { Data to buffer }
- Dec(Count, W); { Reduce count }
- Inc(BufPtr, W); { Advance buffer ptr }
- Inc(Wi, W); { Advance write index }
- Inc(Position, W); { Advance position }
- If (Position > StreamSize) Then { File has expanded }
- StreamSize := Position; { Update new size }
- End;
- End;
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TMemoryStream OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TMemoryStream------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TMemoryStream.Init (ALimit: LongInt; ABlockSize: Word);
- VAR W: Word;
- BEGIN
- Inherited Init; { Call ancestor }
- If (ABlockSize = 0) Then BlkSize := 8192 Else { Default blocksize }
- BlkSize := ABlockSize; { Set blocksize }
- If (ALimit = 0) Then W := 1 Else { At least 1 block }
- W := (ALimit + BlkSize - 1) DIV BlkSize; { Blocks needed }
- If NOT ChangeListSize(W) Then { Try allocate blocks }
- Error(stInitError, 0); { Initialize error }
- END;
- {--TMemoryStream------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TMemoryStream.Done;
- BEGIN
- ChangeListSize(0); { Release all memory }
- Inherited Done; { Call ancestor }
- END;
- {--TMemoryStream------------------------------------------------------------}
- { Truncate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TMemoryStream.Truncate;
- VAR W: Word;
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Position = 0) Then W := 1 Else { At least one block }
- W := (Position + BlkSize - 1) DIV BlkSize; { Blocks needed }
- If ChangeListSize(W) Then StreamSize := Position { Set stream size }
- Else Error(stError, 0); { Error truncating }
- End;
- END;
- {--TMemoryStream------------------------------------------------------------}
- { Read -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TMemoryStream.Read (Var Buf; Count: Word);
- VAR W, CurBlock, BlockPos, Op: Word; Li: LongInt; P, Q: PByteArray;
- BEGIN
- If (Position + Count > StreamSize) Then { Insufficient data }
- Error(stReadError, 0); { Read beyond end!!! }
- P := @Buf; { Transfer address }
- Op := 0; { Zero offset position }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- CurBlock := Position DIV BlkSize; { Current block }
- { * REMARK * - Do not shorten this, result can be > 64K }
- Li := CurBlock; { Transfer current block }
- Li := Li * BlkSize; { Current position }
- { * REMARK END * - Leon de Boer }
- BlockPos := Position - Li; { Current position }
- W := BlkSize - BlockPos; { Current block space }
- If (W > Count) Then W := Count; { Adjust read size }
- Q := BlkList^[CurBlock]; { Calc pointer }
- Move(Q^[BlockPos], P^[Op], W); { Move data to buffer }
- Inc(Position, W); { Adjust position }
- Inc(Op, W); { Increase offset }
- Dec(Count, W); { Adjust count left }
- End;
- If (Count <> 0) Then FillChar(P^[Op], Count, #0); { Error clear buffer }
- END;
- {--TMemoryStream------------------------------------------------------------}
- { Write -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TMemoryStream.Write (Var Buf; Count: Word);
- VAR W, CurBlock, BlockPos, Op: Word; Li: LongInt; P, Q: PByteArray;
- BEGIN
- If (Position + Count > MemSize) Then Begin { Expansion needed }
- If (Position + Count = 0) Then W := 1 Else { At least 1 block }
- W := (Position+Count+BlkSize-1) DIV BlkSize; { Blocks needed }
- If NOT ChangeListSize(W) Then
- Error(stWriteError, 0); { Expansion failed!!! }
- End;
- P := @Buf; { Transfer address }
- Op := 0; { Zero offset position }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- CurBlock := Position DIV BlkSize; { Current segment }
- { * REMARK * - Do not shorten this, result can be > 64K }
- Li := CurBlock; { Transfer current block }
- Li := Li * BlkSize; { Current position }
- { * REMARK END * - Leon de Boer }
- BlockPos := Position - Li; { Current position }
- W := BlkSize - BlockPos; { Current block space }
- If (W > Count) Then W := Count; { Adjust write size }
- Q := BlkList^[CurBlock]; { Calc pointer }
- Move(P^[Op], Q^[BlockPos], W); { Transfer data }
- Inc(Position, W); { Adjust position }
- Inc(Op, W); { Increase offset }
- Dec(Count, W); { Adjust count left }
- If (Position > StreamSize) Then { File expanded }
- StreamSize := Position; { Adjust stream size }
- End;
- END;
- {***************************************************************************}
- { TMemoryStream PRIVATE METHODS }
- {***************************************************************************}
- {--TMemoryStream------------------------------------------------------------}
- { ChangeListSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TMemoryStream.ChangeListSize (ALimit: Word): Boolean;
- VAR I, W, Bas: Word; P: PPointerArray;
- BEGIN
- If (ALimit <> BlkCount) Then Begin { Change is needed }
- ChangeListSize := False; { Preset failure }
- If (ALimit > MaxPtrs) Then Exit; { To many blocks req }
- If (ALimit <> 0) Then Begin { Create segment list }
- Bas := ALimit * SizeOf(Pointer); { Block array size }
- If (MaxAvail > Bas) Then Begin
- GetMem(P, Bas); { Allocate memory }
- FillChar(P^, Bas, #0); { Clear the memory }
- End Else Exit; { Insufficient memory }
- If (BlkCount <> 0) AND (BlkList <> Nil) Then { Current list valid }
- If (BlkCount <= ALimit) Then Move(BlkList^,
- P^, BlkCount * SizeOf(Pointer)) Else { Move whole old list }
- Move(BlkList^, P^, Bas); { Move partial list }
- End Else P := Nil; { No new block list }
- If (ALimit < BlkCount) Then { Shrink stream size }
- For W := BlkCount-1 DownTo ALimit Do
- FreeMem(BlkList^[W], BlkSize); { Release memory block }
- If (P <> Nil) AND (ALimit > BlkCount) Then Begin { Expand stream size }
- For W := BlkCount To ALimit-1 Do Begin
- If (MaxAvail < BlkSize) Then Begin { Check enough memory }
- For I := BlkCount To W-1 Do
- FreeMem(P^[I], BlkSize); { Free mem allocated }
- FreeMem(P, Bas); { Release memory }
- Exit; { Now exit }
- End Else GetMem(P^[W], BlkSize); { Allocate memory }
- End;
- End;
- If (BlkCount <> 0) AND (BlkList<>Nil) Then
- FreeMem(BlkList, BlkCount * SizeOf(Pointer)); { Release old list }
- BlkList := P; { Hold new block list }
- BlkCount := ALimit; { Hold new count }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := BlkCount; { Block count }
- MemSize := MemSize * BlkSize; { Current position }
- { * REMARK END * - Leon de Boer }
- End;
- ChangeListSize := True; { Successful }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TEmsStream OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TEmsStream---------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TEmsStream.Init (MinSize, MaxSize: LongInt);
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- VAR Success: Integer; MinPg, MaxPg: Word;
- BEGIN
- Inherited Init; { Call ancestor }
- If (EMS_MemAvail >= MaxSize) Then Begin { Sufficient memory }
- If (MaxSize = 0) Then MaxPg := 1 Else { At least one page }
- MaxPg := (MaxSize + 16383) DIV 16384; { Max pages needed }
- If (MinSize = 0) Then MinPg := 1 Else { At least one page }
- MinPg := (MinSize + 16383) DIV 16384; { Min pages needed }
- Handle := EMS_GetMem(MaxPg); { Allocate EMS pages }
- If (Handle <> 0) Then Begin
- Success := 0; { Preset success }
- PageCount := MaxPg; { Pages used }
- If (MaxPg <> MinPg) Then { Sizes differ }
- If (EMS_ResizeMem(MinPg, Handle)=0) { Resize to minimum }
- Then PageCount := MinPg; { Hold new page count }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := PageCount;
- MemSize := MemSize * 16384;
- { * REMARK END * - Leon de Boer }
- End Else Success := 403; { Failed to allocate }
- End Else Success := 400; { Insufficent EMS }
- If (Handle = 0) OR (Success <> 0) Then { EMS failed }
- Error(stInitError, Success); { Call stream error }
- END;
- {$ELSE} { ALL OTHER OS SYSTEMS }
- BEGIN
- Inherited Init(MaxSize, 16384); { For compatability }
- END;
- {$ENDIF}
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- {***************************************************************************}
- { TEMSStream DOS REAL MODE ONLY METHODS }
- {***************************************************************************}
- {--TEmsStream---------------------------------------------------------------}
- { Done -> Platforms DOS REAL MODE - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TEmsStream.Done;
- BEGIN
- If (Handle <> 0) Then EMS_FreeMem(Handle); { Release EMS blocks }
- Inherited Done; { Call ancestor }
- END;
- {--TEmsStream---------------------------------------------------------------}
- { Truncate -> Platforms DOS REAL MODE - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TEmsStream.Truncate;
- VAR Success: Integer; W: Word;
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Position = 0) Then W := 1 Else { At least one page }
- W := (Position + 16383) DIV 16384; { Pages to use }
- Success := 0; { Preset success }
- If (W <> PageCount) Then { Sizes differ }
- If (EMS_ResizeMem(W, Handle)=0) Then { Resize to this }
- PageCount := W Else Success := 401; { Adjust blocks used }
- If (Success = 0) Then StreamSize := Position { Adjust size }
- Else Error(stError, Success); { Identify error }
- End;
- END;
- {--TEmsStream---------------------------------------------------------------}
- { Read -> Platforms DOS REAL MODE - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TEmsStream.Read (Var Buf; Count: Word);
- VAR Success: Integer; W, Ri: Word; P: PByteArray;
- BEGIN
- If (Position + Count > StreamSize) Then { Insufficient data }
- Error(stReadError, 0); { Read beyond end!!! }
- If (Handle = 0) Then Error(stReadError, 403); { EMS not available }
- P := @Buf; { Transfer address }
- Ri := 0; { Zero read index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := EMS_MoveMem(LongInt(P^[Ri]), 0,
- Position, Handle, W); { Move the data }
- If (Success <> 0) Then Begin { Error was detected }
- W := 0; { Clear bytes moved }
- Error(stReadError, Success) { Specific read error }
- End;
- Inc(Position, W); { Adjust position }
- Inc(Ri, W); { Adjust read index }
- Dec(Count, W); { Adjust count left }
- End;
- If (Count <> 0) Then FillChar(P^[Ri], Count, #0); { Error clear buffer }
- END;
- {--TEmsStream---------------------------------------------------------------}
- { Write -> Platforms DOS REAL MODE - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TEmsStream.Write (Var Buf; Count: Word);
- VAR Success: Integer; W, Wi: Word; P: PByteArray;
- BEGIN
- If (Position + Count > MemSize) Then Begin { Expansion needed }
- If (Position + Count = 0) Then W := 1 Else { At least one page }
- W := (Position+Count + 16383) DIV 16384; { Pages needed }
- If (EMS_ResizeMem(W, Handle)=0) Then Begin { Resize memory }
- PageCount := W; { Adjust page count }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := PageCount;
- MemSize := MemSize * 1024; { New memory size }
- { * REMARK END * - Leon de Boer }
- End Else Error(stWriteError, 0); { We have an error }
- End;
- If (Handle = 0) Then Error(stWriteError, 403); { EMS not available }
- P := @Buf; { Transfer address }
- Wi := 0; { Zero write index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := EMS_MoveMem(Position, Handle,
- LongInt(P^[Wi]), 0, W); { Move the memory }
- If (Success <> 0) Then Begin { Error was detected }
- W := 0; { Clear bytes moved }
- Error(stWriteError, Success); { Specific write error }
- End;
- Inc(Position, W); { Adjust position }
- Inc(Wi, W); { Adjust write index }
- Dec(Count, W); { Adjust count left }
- If (Position > StreamSize) Then { File expanded }
- StreamSize := Position; { Adjust stream size }
- End;
- END;
- {$ENDIF}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TXmsStream OBJECT ANCESTOR }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TXmsStream---------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TXmsStream.Init (MinSize, MaxSize: LongInt);
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- VAR Success: Integer; MinBlk, MaxBlk: Word;
- BEGIN
- Inherited Init; { Call ancestor }
- If (XMS_MemAvail >= MaxSize) Then Begin { Sufficient memory }
- If (MaxSize = 0) Then MaxBlk := 1 Else { At least one block }
- MaxBlk := (MaxSize + 1023) DIV 1024; { Max blocks needed }
- If (MinSize = 0) Then MinBlk := 1 Else { At least one block }
- MinBlk := (MinSize + 1023) DIV 1024; { Min blocks needed }
- Handle := XMS_GetMem(MaxBlk); { Allocate XMS blocks }
- If (Handle <> 0) Then Begin
- Success := 0; { Preset success }
- BlocksUsed := MaxBlk; { Blocks used }
- If (MaxBlk <> MinBlk) Then { Sizes differ }
- If (XMS_ResizeMem(MaxBlk, MinBlk, Handle)=0) { Resize to minimum }
- Then BlocksUsed := MinBlk; { Hold block size }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := BlocksUsed;
- MemSize := MemSize * 1024;
- { * REMARK END * - Leon de Boer }
- End Else Success := 303; { Failed to allocate }
- End Else Success := 300; { Insufficent XMS }
- If (Handle = 0) OR (Success <> 0) Then { XMS failed }
- Error(stInitError, Success); { Call stream error }
- END;
- {$ELSE} { ALL OTHER OP SYSTEMS }
- BEGIN
- Inherited Init(MaxSize, 16384); { For compatability }
- END;
- {$ENDIF}
- {$IFDEF PROC_Real} { DOS REAL MODE CODE }
- {***************************************************************************}
- { TXMSStream DOS REAL MODE ONLY METHODS }
- {***************************************************************************}
- {--TXmsStream---------------------------------------------------------------}
- { Done -> Platforms DOS REAL MODE - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TXmsStream.Done;
- BEGIN
- If (Handle <> 0) Then XMS_FreeMem(Handle); { Release XMS blocks }
- Inherited Done; { Call ancestor }
- END;
- {--TXmsStream---------------------------------------------------------------}
- { Truncate -> Platforms DOS REAL MODE - Updated 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TXmsStream.Truncate;
- VAR Success: Integer; W: Word;
- BEGIN
- If (Status = stOk) Then Begin { Check status okay }
- If (Position = 0) Then W := 1 Else { At least 1 block }
- W := (Position + 1023) DIV 1024; { Blocks to use }
- Success := 0; { Preset success }
- If (W <> BlocksUsed) Then { Sizes differ }
- If (XMS_ResizeMem(BlocksUsed, W, Handle)=0) { Resize to this }
- Then Begin
- BlocksUsed := W; { Adjust blocks used }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := BlocksUsed; { Blocks used }
- MemSize := MemSize * 1024; { Mult by block size }
- { * REMARK END * - Leon de Boer }
- End Else Success := 301; { Resize failed }
- If (Success = 0) Then StreamSize := Position { Adjust size }
- Else Error(stError, Success); { Identify error }
- End;
- END;
- {--TXmsStream---------------------------------------------------------------}
- { Read -> Platforms DOS REAL MODE - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TXmsStream.Read (Var Buf; Count: Word);
- VAR Success: Integer; W, Ri: Word; P: PByteArray;
- BEGIN
- If (Position + Count > StreamSize) Then { Insufficient data }
- Error(stReadError, 0); { Read beyond end!!! }
- If (Handle = 0) Then Error(stReadError, 303); { XMS not available }
- P := @Buf; { Transfer address }
- Ri := 0; { Zero read index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := XMS_MoveMem(LongInt(P^[Ri]), 0,
- Position, Handle, W); { Move the data }
- If (Success <> 0) Then Begin { Error was detected }
- W := 0; { Clear bytes moved }
- Error(stReadError, Success) { Specific read error }
- End;
- Inc(Position, W); { Adjust position }
- Inc(Ri, W); { Adjust read index }
- Dec(Count, W); { Adjust count left }
- End;
- If (Count <> 0) Then FillChar(P^[Ri], Count, #0); { Error clear buffer }
- END;
- {--TXmsStream---------------------------------------------------------------}
- { Write -> Platforms DOS REAL MODE - Updated 27Oct99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TXmsStream.Write (Var Buf; Count: Sw_Word);
- VAR Success: Integer; W, Wi: Word; P: PByteArray;
- BEGIN
- { * REMARK * - Because XMS must move even bytes we expand if within }
- { one byte of allocated size so we can read/write the }
- { last byte with an even access using a dummy end byte. }
- { * REMARK * - Leon de Boer }
- If (Position + Count > (MemSize-1)) Then Begin { Expansion needed }
- If (Position + Count = 0) Then W := 1 Else Begin { At least one }
- W := (Position + Count + 1023) DIV 1024; { Blocks needed }
- If ((Position + Count) MOD 1024 = 0) Then
- Inc(W); { Fix for even access }
- End;
- If (XMS_ResizeMem(BlocksUsed, W, Handle)=0) { Resize memory }
- Then Begin
- BlocksUsed := W; { Adjust block count }
- { * REMARK * - Do not shorten this, result can be > 64K }
- MemSize := BlocksUsed;
- MemSize := MemSize * 1024; { New memory size }
- { * REMARK END * - Leon de Boer }
- End Else Error(stWriteError, 0); { We have an error }
- End;
- If (Handle = 0) Then Error(stWriteError, 303); { XMS not available }
- P := @Buf; { Transfer address }
- Wi := 0; { Zero write index }
- While (Count > 0) AND (Status = stOk) Do Begin { Check status & count }
- W := Count; { Transfer read size }
- If (Count > $FFFE) Then W := $FFFE; { Cant read >64K bytes }
- Success := XMS_MoveMem(Position, Handle,
- LongInt(P^[Wi]), 0, W); { Move the memory }
- If (Success <> 0) Then Begin { Error was detected }
- W := 0; { Clear bytes moved }
- Error(stWriteError, Success); { Specific write error }
- End;
- Inc(Position, W); { Adjust position }
- Inc(Wi, W); { Adjust write index }
- Dec(Count, W); { Adjust count left }
- If (Position > StreamSize) Then { File expanded }
- StreamSize := Position; { Adjust stream size }
- End;
- END;
- {$ENDIF}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TCollection--------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TCollection.Init (ALimit, ADelta: Integer);
- BEGIN
- Inherited Init; { Call ancestor }
- Delta := ADelta; { Set increment }
- SetLimit(ALimit); { Set limit }
- END;
- {--TCollection--------------------------------------------------------------}
- { Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TCollection.Load (Var S: TStream);
- VAR C, I: Integer;
- BEGIN
- S.Read(Count, 2); { Read count }
- S.Read(Limit, 2); { Read limit }
- S.Read(Delta, 2); { Read delta }
- Items := Nil; { Clear item pointer }
- C := Count; { Hold count }
- I := Limit; { Hold limit }
- Count := 0; { Clear count }
- Limit := 0; { Clear limit }
- SetLimit(I); { Set requested limit }
- Count := C; { Set count }
- For I := 0 To C-1 Do AtPut(I, GetItem(S)); { Get each item }
- END;
- {--TCollection--------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TCollection.Done;
- BEGIN
- FreeAll; { Free all items }
- SetLimit(0); { Release all memory }
- END;
- {--TCollection--------------------------------------------------------------}
- { At -> Platforms DOS/DPMI/WIN/NT/OS2 -Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TCollection.At (Index: Integer): Pointer;
- BEGIN
- If (Index < 0) OR (Index >= Count) Then Begin { Invalid index }
- Error(coIndexError, Index); { Call error }
- At := Nil; { Return nil }
- End Else At := Items^[Index]; { Return item }
- END;
- {--TCollection--------------------------------------------------------------}
- { IndexOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TCollection.IndexOf (Item: Pointer): Integer;
- VAR I: Integer;
- BEGIN
- If (Count > 0) Then Begin { Count is positive }
- For I := 0 To Count-1 Do { For each item }
- If (Items^[I] = Item) Then Begin { Look for match }
- IndexOf := I; { Return index }
- Exit; { Now exit }
- End;
- End;
- IndexOf := -1; { Return index }
- END;
- {--TCollection--------------------------------------------------------------}
- { GetItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TCollection.GetItem (Var S: TStream): Pointer;
- BEGIN
- GetItem := S.Get; { Item off stream }
- END;
- {--TCollection--------------------------------------------------------------}
- { LastThat -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TCollection.LastThat (Test: Pointer): Pointer;
- VAR I: Integer;
- BEGIN
- For I := Count DownTo 1 Do Begin { Down from last item }
- {$IFDEF PPC_VIRTUAL} { VIRTUAL COMPILER }
- If CallTestLocal(Test, Items^[I-1]) { Test each item }
- {$ELSE} { OTHER COMPILERS }
- If CallTestLocal(Test, PrevFramePtr, Items^[I-1]){ Test each item }
- {$ENDIF}
- Then Begin { Test each item }
- LastThat := Items^[I-1]; { Return successful }
- Exit; { Now exit }
- End;
- End;
- LastThat := Nil; { None passed test }
- END;
- {--TCollection--------------------------------------------------------------}
- { FirstThat -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TCollection.FirstThat (Test: Pointer): Pointer;
- VAR I: Integer;
- BEGIN
- For I := 1 To Count Do Begin { Up from first item }
- {$IFDEF PPC_VIRTUAL} { VIRTUAL COMPILER }
- If CallTestLocal(Test, Items^[I-1]) { Test each item }
- {$ELSE} { OTHER COMPILERS }
- If CallTestLocal(Test, PrevFramePtr, Items^[I-1]){ Test each item }
- {$ENDIF}
- Then Begin { Test each item }
- FirstThat := Items^[I-1]; { Return successful }
- Exit; { Now exit }
- End;
- End;
- FirstThat := Nil; { None passed test }
- END;
- {--TCollection--------------------------------------------------------------}
- { Pack -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Pack;
- VAR I, J: Integer;
- BEGIN
- I := 0; { Initialize dest }
- J := 0; { Intialize test }
- While (I < Count) AND (J < Limit) Do Begin { Check fully packed }
- If (Items^[J] <> Nil) Then Begin { Found a valid item }
- If (I <> J) Then Begin
- Items^[I] := Items^[J]; { Transfer item }
- Items^[J] := Nil; { Now clear old item }
- End;
- Inc(I); { One item packed }
- End;
- Inc(J); { Next item to test }
- End;
- If (I < Count) Then Count := I; { New packed count }
- END;
- {--TCollection--------------------------------------------------------------}
- { FreeAll -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.FreeAll;
- VAR I: Integer;
- BEGIN
- For I := 0 To Count-1 Do FreeItem(At(I)); { Release each item }
- Count := 0; { Clear item count }
- END;
- {--TCollection--------------------------------------------------------------}
- { DeleteAll -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.DeleteAll;
- BEGIN
- Count := 0; { Clear item count }
- END;
- {--TCollection--------------------------------------------------------------}
- { Free -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Free (Item: Pointer);
- BEGIN
- Delete(Item); { Delete from list }
- FreeItem(Item); { Free the item }
- END;
- {--TCollection--------------------------------------------------------------}
- { Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Insert (Item: Pointer);
- BEGIN
- AtInsert(Count, Item); { Insert item }
- END;
- {--TCollection--------------------------------------------------------------}
- { Delete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Delete (Item: Pointer);
- BEGIN
- AtDelete(IndexOf(Item)); { Delete from list }
- END;
- {--TCollection--------------------------------------------------------------}
- { AtFree -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.AtFree (Index: Integer);
- VAR Item: Pointer;
- BEGIN
- Item := At(Index); { Retreive item ptr }
- AtDelete(Index); { Delete item }
- FreeItem(Item); { Free the item }
- END;
- {--TCollection--------------------------------------------------------------}
- { FreeItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.FreeItem (Item: Pointer);
- VAR P: PObject;
- BEGIN
- P := PObject(Item); { Convert pointer }
- If (P <> Nil) Then Dispose(P, Done); { Dispose of object }
- END;
- {--TCollection--------------------------------------------------------------}
- { AtDelete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.AtDelete (Index: Integer);
- BEGIN
- If (Index >= 0) AND (Index < Count) Then Begin { Valid index }
- Dec(Count); { One less item }
- If (Count > Index) Then Move(Items^[Index+1],
- Items^[Index], (Count-Index)*Sizeof(Pointer)); { Shuffle items down }
- End Else Error(coIndexError, Index); { Index error }
- END;
- {--TCollection--------------------------------------------------------------}
- { ForEach -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.ForEach (Action: Pointer);
- VAR I: Integer;
- BEGIN
- For I := 1 To Count Do { Up from first item }
- {$IFDEF PPC_VIRTUAL} { VIRTUAL COMPILER }
- CallTestLocal(Action, Items^[I-1]); { Call with each item }
- {$ELSE} { OTHER COMPILERS }
- CallTestLocal(Action, PrevFramePtr, Items^[I-1]); { Call with each item }
- {$ENDIF}
- END;
- {--TCollection--------------------------------------------------------------}
- { SetLimit -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.SetLimit (ALimit: Integer);
- VAR AItems: PItemList;
- BEGIN
- If (ALimit < Count) Then ALimit := Count; { Stop underflow }
- If (ALimit > MaxCollectionSize) Then
- ALimit := MaxCollectionSize; { Stop overflow }
- {$IFNDEF PPC_SPEED} { NON SPEED COMPILERS }
- If (MaxAvail < (ALimit*SizeOf(Pointer))) Then { Check enough memory }
- ALimit := Limit; { Insufficient memory }
- {$ENDIF}
- If (ALimit <> Limit) Then Begin { Limits differ }
- If (ALimit = 0) Then AItems := Nil Else Begin { Alimit=0 nil entry }
- GetMem(AItems, ALimit * SizeOf(Pointer)); { Allocate memory }
- If (AItems <> Nil) Then FillChar(AItems^,
- ALimit * SizeOf(Pointer), #0); { Clear the memory }
- End;
- If (AItems <> Nil) OR (ALimit = 0) Then Begin { Check success }
- If (AItems <> Nil) AND (Items <> Nil) Then { Check both valid }
- Move(Items^, AItems^, Count*SizeOf(Pointer));{ Move existing items }
- If (Limit <> 0) AND (Items <> Nil) Then { Check old allocation }
- FreeMem(Items, Limit * SizeOf(Pointer)); { Release memory }
- Items := AItems; { Update items }
- Limit := ALimit; { Set limits }
- End;
- End;
- END;
- {--TCollection--------------------------------------------------------------}
- { Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Error (Code, Info: Integer);
- BEGIN
- RunError(212 - Code); { Run error }
- END;
- {--TCollection--------------------------------------------------------------}
- { AtPut -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.AtPut (Index: Integer; Item: Pointer);
- BEGIN
- If (Index >= 0) AND (Index < Count) Then { Index valid }
- Items^[Index] := Item { Put item in index }
- Else Error(coIndexError, Index); { Index error }
- END;
- {--TCollection--------------------------------------------------------------}
- { AtInsert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May99 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.AtInsert (Index: Integer; Item: Pointer);
- VAR I: Integer;
- BEGIN
- If (Index >= 0) AND (Index <= Count) Then Begin { Valid index }
- If (Count=Limit) Then SetLimit(Limit+Delta); { Expand size if able }
- If (Limit>Count) Then Begin
- If (Index < Count) Then Begin { Not last item }
- For I := Count-1 DownTo Index Do { Start from back }
- Items^[I+1] := Items^[I]; { Move each item }
- End;
- Items^[Index] := Item; { Put item in list }
- Inc(Count); { Inc count }
- End Else Error(coOverflow, Index); { Expand failed }
- End Else Error(coIndexError, Index); { Index error }
- END;
- {--TCollection--------------------------------------------------------------}
- { Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.Store (Var S: TStream);
- PROCEDURE DoPutItem (P: Pointer); {$IFNDEF FPC} FAR;{$ENDIF}
- BEGIN
- PutItem(S, P); { Put item on stream }
- END;
- BEGIN
- S.Write(Count, 2); { Write count }
- S.Write(Limit, 2); { Write limit }
- S.Write(Delta, 2); { Write delta }
- ForEach(@DoPutItem); { Each item to stream }
- END;
- {--TCollection--------------------------------------------------------------}
- { PutItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TCollection.PutItem (Var S: TStream; Item: Pointer);
- BEGIN
- S.Put(Item); { Put item on stream }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TSortedCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TSortedCollection--------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TSortedCollection.Init (ALimit, ADelta: Integer);
- BEGIN
- Inherited Init(ALimit, ADelta); { Call ancestor }
- Duplicates := False; { Clear flag }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TSortedCollection.Load (Var S: TStream);
- BEGIN
- Inherited Load(S); { Call ancestor }
- S.Read(Duplicates, 1); { Read duplicate flag }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { KeyOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TSortedCollection.KeyOf (Item: Pointer): Pointer;
- BEGIN
- KeyOf := Item; { Return item as key }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { IndexOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TSortedCollection.IndexOf (Item: Pointer): Integer;
- VAR I, J: Integer;
- BEGIN
- J := -1; { Preset result }
- If Search(KeyOf(Item), I) Then Begin { Search for item }
- If Duplicates Then { Duplicates allowed }
- While (I < Count) AND (Item <> Items^[I]) Do
- Inc(I); { Count duplicates }
- If (I < Count) Then J := I; { Index result }
- End;
- IndexOf := J; { Return result }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { Compare -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TSortedCollection.Compare (Key1, Key2: Pointer): Integer;
- BEGIN
- Abstract; { Abstract method }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { Search -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TSortedCollection.Search (Key: Pointer; Var Index: Integer): Boolean;
- VAR L, H, I, C: Integer;
- BEGIN
- Search := False; { Preset failure }
- L := 0; { Start count }
- H := Count - 1; { End count }
- While (L <= H) Do Begin
- I := (L + H) SHR 1; { Mid point }
- C := Compare(KeyOf(Items^[I]), Key); { Compare with key }
- If (C < 0) Then L := I + 1 Else Begin { Item to left }
- H := I - 1; { Item to right }
- If C = 0 Then Begin { Item match found }
- Search := True; { Result true }
- If NOT Duplicates Then L := I; { Force kick out }
- End;
- End;
- End;
- Index := L; { Return result }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TSortedCollection.Insert (Item: Pointer);
- VAR I: Integer;
- BEGIN
- If NOT Search(KeyOf(Item), I) OR Duplicates Then { Item valid }
- AtInsert(I, Item); { Insert the item }
- END;
- {--TSortedCollection--------------------------------------------------------}
- { Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TSortedCollection.Store (Var S: TStream);
- BEGIN
- TCollection.Store(S); { Call ancestor }
- S.Write(Duplicates, 1); { Write duplicate flag }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TStringCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TStringCollection--------------------------------------------------------}
- { GetItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStringCollection.GetItem (Var S: TStream): Pointer;
- BEGIN
- GetItem := S.ReadStr; { Get new item }
- END;
- {--TStringCollection--------------------------------------------------------}
- { Compare -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 21Aug97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStringCollection.Compare (Key1, Key2: Pointer): Integer;
- VAR I, J: Integer; P1, P2: PString;
- BEGIN
- P1 := PString(Key1); { String 1 pointer }
- P2 := PString(Key2); { String 2 pointer }
- If (Length(P1^)<Length(P2^)) Then J := Length(P1^)
- Else J := Length(P2^); { Shortest length }
- I := 1; { First character }
- While (I<J) AND (P1^[I]=P2^[I]) Do Inc(I); { Scan till fail }
- If (I=J) Then Begin { Possible match }
- { * REMARK * - Bug fix 21 August 1997 }
- If (P1^[I]<P2^[I]) Then Compare := -1 Else { String1 < String2 }
- If (P1^[I]>P2^[I]) Then Compare := 1 Else { String1 > String2 }
- If (Length(P1^)>Length(P2^)) Then Compare := 1 { String1 > String2 }
- Else If (Length(P1^)<Length(P2^)) Then { String1 < String2 }
- Compare := -1 Else Compare := 0; { String1 = String2 }
- { * REMARK END * - Leon de Boer }
- End Else If (P1^[I]<P2^[I]) Then Compare := -1 { String1 < String2 }
- Else Compare := 1; { String1 > String2 }
- END;
- {--TStringCollection--------------------------------------------------------}
- { FreeItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStringCollection.FreeItem (Item: Pointer);
- BEGIN
- DisposeStr(Item); { Dispose item }
- END;
- {--TStringCollection--------------------------------------------------------}
- { PutItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStringCollection.PutItem (Var S: TStream; Item: Pointer);
- BEGIN
- S.WriteStr(Item); { Write string }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TStrCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TStrCollection-----------------------------------------------------------}
- { Compare -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStrCollection.Compare (Key1, Key2: Pointer): Integer;
- VAR I, J: Integer; P1, P2: PByteArray;
- BEGIN
- P1 := PByteArray(Key1); { PChar 1 pointer }
- P2 := PByteArray(Key2); { PChar 2 pointer }
- I := 0; { Preset no size }
- If (P1 <> Nil) Then While (P1^[I] <> 0) Do Inc(I); { PChar 1 length }
- J := 0; { Preset no size }
- If (P2 <> Nil) Then While (P2^[J] <> 0) Do Inc(J); { PChar 2 length }
- If (I < J) Then J := I; { Shortest length }
- I := 0; { First character }
- While (I < J) AND (P1^[I] = P2^[I]) Do Inc(I); { Scan till fail }
- If (P1^[I] = P2^[I]) Then Compare := 0 Else { Strings matched }
- If (P1^[I] < P2^[I]) Then Compare := -1 Else { String1 < String2 }
- Compare := 1; { String1 > String2 }
- END;
- {--TStrCollection-----------------------------------------------------------}
- { GetItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStrCollection.GetItem (Var S: TStream): Pointer;
- BEGIN
- GetItem := S.StrRead; { Get string item }
- END;
- {--TStrCollection-----------------------------------------------------------}
- { FreeItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStrCollection.FreeItem (Item: Pointer);
- VAR I: Integer; P: PByteArray;
- BEGIN
- If (Item <> Nil) Then Begin { Item is valid }
- P := PByteArray(Item); { Create byte pointer }
- I := 0; { Preset no size }
- While (P^[I] <> 0) Do Inc(I); { Find PChar end }
- FreeMem(Item, I+1); { Release memory }
- End;
- END;
- {--TStrCollection-----------------------------------------------------------}
- { PutItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStrCollection.PutItem (Var S: TStream; Item: Pointer);
- BEGIN
- S.StrWrite(Item); { Write the string }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TUnSortedStrCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TUnSortedCollection------------------------------------------------------}
- { Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TUnSortedStrCollection.Insert (Item: Pointer);
- BEGIN
- AtInsert(Count, Item); { Insert - NO sorting }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TResourceItem RECORD }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- TYPE
- TResourceItem = PACKED RECORD
- Posn: LongInt; { Resource position }
- Size: LongInt; { Resource size }
- Key : String; { Resource key }
- End;
- PResourceItem = ^TResourceItem;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TResourceCollection OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TResourceCollection------------------------------------------------------}
- { KeyOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceCollection.KeyOf (Item: Pointer): Pointer;
- BEGIN
- KeyOf := @PResourceItem(Item)^.Key; { Pointer to key }
- END;
- {--TResourceCollection------------------------------------------------------}
- { GetItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24May96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceCollection.GetItem (Var S: TStream): Pointer;
- VAR B: Byte; Pos, Size: LongInt; P: PResourceItem; Ts: String;
- BEGIN
- S.Read(Pos, 4); { Read position }
- S.Read(Size, 4); { Read size }
- S.Read(B, 1); { Read key length }
- If (MaxAvail > (SizeOf(TResourceItem)-SizeOf(Ts)))
- Then Begin
- GetMem(P, B + (SizeOf(TResourceItem) -
- SizeOf(Ts) + 1)); { Allocate min memory }
- P^.Posn := Pos; { Xfer position }
- P^.Size := Size; { Xfer size }
- {$IFDEF PPC_DELPHI3} { DELPHI 3+ COMPILER }
- SetLength(P^.Key, B); { Xfer string length }
- {$ELSE} { OTHER COMPILERS }
- P^.Key[0] := Chr(B); { Xfer string length }
- {$ENDIF}
- S.Read(P^.Key[1], B); { Xfer string data }
- End Else P := Nil; { Insufficient memory }
- GetItem := P; { Return pointer }
- END;
- {--TResourceCollection------------------------------------------------------}
- { FreeItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TResourceCollection.FreeItem (Item: Pointer);
- VAR S: String;
- BEGIN
- If (Item <> Nil) Then FreeMem(Item,
- SizeOf(TResourceItem) - SizeOf(S) +
- Length(PResourceItem(Item)^.Key) + 1); { Release memory }
- END;
- {--TResourceCollection------------------------------------------------------}
- { PutItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24May96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TResourceCollection.PutItem (Var S: TStream; Item: Pointer);
- VAR Ts: String;
- BEGIN
- If (Item <> Nil) Then S.Write(PResourceItem(Item)^,
- SizeOf(TResourceItem) - SizeOf(Ts) +
- Length(PResourceItem(Item)^.Key) + 1); { Write to stream }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { PRIVATE RESOURCE MANAGER CONSTANTS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- CONST
- RStreamMagic: LongInt = $52504246; { 'FBPR' }
- RStreamBackLink: LongInt = $4C424246; { 'FBBL' }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { PRIVATE RESOURCE MANAGER TYPES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- TYPE
- {$IFDEF NewExeFormat} { New EXE format }
- TExeHeader = PACKED RECORD
- eHdrSize: Word;
- eMinAbove: Word;
- eMaxAbove: Word;
- eInitSS: Word;
- eInitSP: Word;
- eCheckSum: Word;
- eInitPC: Word;
- eInitCS: Word;
- eRelocOfs: Word;
- eOvlyNum: Word;
- eRelocTab: Word;
- eSpace: Array[1..30] of Byte;
- eNewHeader: Word;
- END;
- {$ENDIF}
- THeader = PACKED RECORD
- Signature: Word;
- Case Integer Of
- 0: (
- LastCount: Word;
- PageCount: Word;
- ReloCount: Word);
- 1: (
- InfoType: Word;
- InfoSize: Longint);
- End;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TResourceFile OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TResourceFile------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TResourceFile.Init(AStream: PStream);
- VAR Found, Stop: Boolean; Header: THeader;
- {$IFDEF NewExeFormat} ExeHeader: TExeHeader; {$ENDIF}
- BEGIN
- TObject.Init; { Initialize object }
- Found := False; { Preset false }
- If (AStream <> Nil) Then Begin
- Stream := AStream; { Hold stream }
- BasePos := Stream^.GetPos; { Get position }
- Repeat
- Stop := True; { Preset stop }
- If (BasePos <= Stream^.GetSize-SizeOf(THeader))
- Then Begin { Valid file header }
- Stream^.Seek(BasePos); { Seek to position }
- Stream^.Read(Header, SizeOf(THeader)); { Read header }
- Case Header.Signature Of
- {$IFDEF NewExeFormat} { New format file }
- $5A4D: Begin
- Stream^.Read(ExeHeader, SizeOf(TExeHeader));
- BasePos := ExeHeader.eNewHeader; { Hold position }
- Stop := False; { Clear stop flag }
- End;
- $454E: Begin
- BasePos := Stream^.GetSize - 8; { Hold position }
- Stop := False; { Clear stop flag }
- End;
- $4246: Begin
- Stop := False; { Clear stop flag }
- Case Header.Infotype Of
- $5250: Begin { Found Resource }
- Found := True; { Found flag is true }
- Stop := True; { Set stop flag }
- End;
- $4C42: Dec(BasePos, Header.InfoSize-8);{ Found BackLink }
- $4648: Dec(BasePos, SizeOf(THeader)*2);{ Found HelpFile }
- Else Stop := True; { Set stop flag }
- End;
- End;
- $424E: If Header.InfoType = $3230 { Found Debug Info }
- Then Begin
- Dec(BasePos, Header.InfoSize); { Adjust position }
- Stop := False; { Clear stop flag }
- End;
- {$ELSE} { Old EXE format }
- $5A4D: Begin
- Inc(BasePos, LongInt(Header.PageCount)*512
- - (-Header.LastCount AND 511)); { Calc position }
- Stop := False; { Clear stop flag }
- End;
- $4246: If Header.InfoType = $5250 Then { Header was found }
- Found := True Else Begin
- Inc(BasePos, Header.InfoSize + 8); { Adjust position }
- Stop := False; { Clear stop flag }
- End;
- {$ENDIF}
- End;
- End;
- Until Stop; { Until flag is set }
- End;
- If Found Then Begin { Resource was found }
- Stream^.Seek(BasePos + SizeOf(LongInt) * 2); { Seek to position }
- Stream^.Read(IndexPos, SizeOf(LongInt)); { Read index position }
- Stream^.Seek(BasePos + IndexPos); { Seek to resource }
- Index.Load(Stream^); { Load resource }
- End Else Begin
- IndexPos := SizeOf(LongInt) * 3; { Set index position }
- Index.Init(0, 8); { Set index }
- End;
- END;
- {--TResourceFile------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TResourceFile.Done;
- BEGIN
- Flush; { Flush the file }
- Index.Done; { Dispose of index }
- If (Stream <> Nil) Then Dispose(Stream, Done); { Dispose of stream }
- END;
- {--TResourceFile------------------------------------------------------------}
- { Count -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceFile.Count: Integer;
- BEGIN
- Count := Index.Count; { Return index count }
- END;
- {--TResourceFile------------------------------------------------------------}
- { KeyAt -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceFile.KeyAt (I: Integer): String;
- BEGIN
- KeyAt := PResourceItem(Index.At(I))^.Key; { Return key }
- END;
- {--TResourceFile------------------------------------------------------------}
- { Get -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceFile.Get (Key: String): PObject;
- VAR I: Integer;
- BEGIN
- If (Stream = Nil) OR (NOT Index.Search(@Key, I)) { No match on key }
- Then Get := Nil Else Begin
- Stream^.Seek(BasePos +
- PResourceItem(Index.At(I))^.Posn); { Seek to position }
- Get := Stream^.Get; { Get item }
- End;
- END;
- {--TResourceFile------------------------------------------------------------}
- { SwitchTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TResourceFile.SwitchTo (AStream: PStream; Pack: Boolean): PStream;
- VAR NewBasePos: LongInt;
- PROCEDURE DoCopyResource (Item: PResourceItem); {$IFNDEF FPC} FAR; {$ENDIF}
- BEGIN
- Stream^.Seek(BasePos + Item^.Posn); { Move stream position }
- Item^.Posn := AStream^.GetPos - NewBasePos; { Hold new position }
- AStream^.CopyFrom(Stream^, Item^.Size); { Copy the item }
- END;
- BEGIN
- SwitchTo := Stream; { Preset return }
- If (AStream <> Nil) AND (Stream <> Nil) Then Begin { Both streams valid }
- NewBasePos := AStream^.GetPos; { Get position }
- If Pack Then Begin
- AStream^.Seek(NewBasePos + SizeOf(LongInt)*3); { Seek to position }
- Index.ForEach(@DoCopyResource); { Copy each resource }
- IndexPos := AStream^.GetPos - NewBasePos; { Hold index position }
- End Else Begin
- Stream^.Seek(BasePos); { Seek to position }
- AStream^.CopyFrom(Stream^, IndexPos); { Copy the resource }
- End;
- Stream := AStream; { Hold new stream }
- BasePos := NewBasePos; { New base position }
- Modified := True; { Set modified flag }
- End;
- END;
- {--TResourceFile------------------------------------------------------------}
- { Flush -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TResourceFile.Flush;
- VAR ResSize: LongInt; LinkSize: LongInt;
- BEGIN
- If (Modified) AND (Stream <> Nil) Then Begin { We have modification }
- Stream^.Seek(BasePos + IndexPos); { Seek to position }
- Index.Store(Stream^); { Store the item }
- ResSize := Stream^.GetPos - BasePos; { Hold position }
- LinkSize := ResSize + SizeOf(LongInt) * 2; { Hold link size }
- Stream^.Write(RStreamBackLink, SizeOf(LongInt)); { Write link back }
- Stream^.Write(LinkSize, SizeOf(LongInt)); { Write link size }
- Stream^.Seek(BasePos); { Move stream position }
- Stream^.Write(RStreamMagic, SizeOf(LongInt)); { Write number }
- Stream^.Write(ResSize, SizeOf(LongInt)); { Write record size }
- Stream^.Write(IndexPos, SizeOf(LongInt)); { Write index position }
- Stream^.Flush; { Flush the stream }
- End;
- Modified := False; { Clear modified flag }
- END;
- {--TResourceFile------------------------------------------------------------}
- { Delete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TResourceFile.Delete (Key: String);
- VAR I: Integer;
- BEGIN
- If Index.Search(@Key, I) Then Begin { Search for key }
- Index.Free(Index.At(I)); { Delete from index }
- Modified := True; { Set modified flag }
- End;
- END;
- {--TResourceFile------------------------------------------------------------}
- { Put -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TResourceFile.Put (Item: PObject; Key: String);
- VAR I: Integer; P: PResourceItem;
- BEGIN
- If (Stream = Nil) Then Exit; { Stream not valid }
- If Index.Search(@Key, I) Then P := Index.At(I) { Search for item }
- Else Begin
- If (MaxAvail > SizeOf(TResourceItem)-SizeOf(Key)){ Check free memory }
- Then Begin
- GetMem(P, Length(Key) + (SizeOf(TResourceItem)
- - SizeOf(Key) + 1)); { Allocate memory }
- P^.Key := Key; { Store key }
- Index.AtInsert(I, P); { Insert item }
- End Else P := Nil; { Insufficient memory }
- End;
- If (P <> Nil) Then Begin { Allocate worked }
- P^.Posn := IndexPos; { Set index position }
- Stream^.Seek(BasePos + IndexPos); { Seek file position }
- Stream^.Put(Item); { Put item on stream }
- IndexPos := Stream^.GetPos - BasePos; { Hold index position }
- P^.Size := IndexPos - P^.Posn; { Calc size }
- Modified := True; { Set modified flag }
- End;
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TStringList OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TStringList--------------------------------------------------------------}
- { Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TStringList.Load (Var S: TStream);
- VAR Size: Word;
- BEGIN
- Stream := @S; { Hold stream pointer }
- S.Read(Size, SizeOf(Word)); { Read size }
- BasePos := S.GetPos; { Hold position }
- S.Seek(BasePos + Size); { Seek to position }
- S.Read(IndexSize, SizeOf(Integer)); { Read index size }
- If (MaxAvail >= IndexSize * SizeOf(TStrIndexRec)) { Check free memory }
- Then Begin
- GetMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Allocate memory }
- S.Read(Index^, IndexSize * SizeOf(TStrIndexRec));{ Read indexes }
- End Else IndexSize := 0; { Insufficient memory }
- END;
- {--TStringList--------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TStringList.Done;
- BEGIN
- FreeMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Release memory }
- END;
- {--TStringList--------------------------------------------------------------}
- { Get -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION TStringList.Get (Key: Word): String;
- VAR I: Word; S: String;
- BEGIN
- S := ''; { Preset empty string }
- If (IndexSize > 0) Then Begin { We must have strings }
- I := 0; { First entry }
- While (I < IndexSize) AND (S = '') Do Begin
- If ((Key - Index^[I].Key) < Index^[I].Count) { Diff less than count }
- Then ReadStr(S, Index^[I].Offset,
- Key-Index^[I].Key); { Read the string }
- Inc(I); { Next entry }
- End;
- End;
- Get := S; { Return empty string }
- END;
- {***************************************************************************}
- { TStringList PRIVATE METHODS }
- {***************************************************************************}
- {--TStringList--------------------------------------------------------------}
- { ReadStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStringList.ReadStr (Var S: String; Offset, Skip: Word);
- VAR B: Byte;
- BEGIN
- Stream^.Seek(BasePos + Offset); { Seek to position }
- Inc(Skip); { Adjust skip }
- Repeat
- Stream^.Read(B, 1); { Read string size }
- {$IFDEF PPC_DELPHI3} { DELPHI 3+ COMPILER }
- SetLength(S, B); { Xfer string length }
- {$ELSE} { OTHER COMPILERS }
- S[0] := Chr(B); { Xfer string size }
- {$ENDIF}
- Stream^.Read(S[1], B); { Read string data }
- Dec(Skip); { One string read }
- Until (Skip = 0);
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { TStrListMaker OBJECT METHODS }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {--TStrListMaker------------------------------------------------------------}
- { Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- CONSTRUCTOR TStrListMaker.Init (AStrSize, AIndexSize: Word);
- BEGIN
- Inherited Init; { Call ancestor }
- StrSize := AStrSize; { Hold size }
- If (MaxAvail >= AStrSize) Then
- GetMem(Strings, AStrSize); { Allocate memory }
- If (MaxAvail >= AIndexSize * SizeOf(TStrIndexRec)) { Check free memory }
- Then Begin
- IndexSize := AIndexSize; { Hold index size }
- GetMem(Index, AIndexSize * SizeOf(TStrIndexRec));{ Allocate memory }
- End;
- END;
- {--TStrListMaker------------------------------------------------------------}
- { Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- DESTRUCTOR TStrListMaker.Done;
- BEGIN
- FreeMem(Index, IndexSize * SizeOf(TStrIndexRec)); { Free index memory }
- FreeMem(Strings, StrSize); { Free data memory }
- END;
- {--TStrListMaker------------------------------------------------------------}
- { Put -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStrListMaker.Put (Key: Word; S: String);
- BEGIN
- If (Cur.Count = 16) OR (Key <> Cur.Key + Cur.Count)
- Then CloseCurrent; { Close current }
- If (Cur.Count = 0) Then Begin
- Cur.Key := Key; { Set key }
- Cur.Offset := StrPos; { Set offset }
- End;
- Inc(Cur.Count); { Inc count }
- Move(S, Strings^[StrPos], Length(S) + 1); { Move string data }
- Inc(StrPos, Length(S) + 1); { Adjust position }
- END;
- {--TStrListMaker------------------------------------------------------------}
- { Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStrListMaker.Store (Var S: TStream);
- BEGIN
- CloseCurrent; { Close all current }
- S.Write(StrPos, SizeOf(Word)); { Write position }
- S.Write(Strings^, StrPos); { Write string data }
- S.Write(IndexPos, SizeOf(Word)); { Write index position }
- S.Write(Index^, IndexPos * SizeOf(TStrIndexRec)); { Write indexes }
- END;
- {***************************************************************************}
- { TStrListMaker PRIVATE METHODS }
- {***************************************************************************}
- {--TStrListMaker------------------------------------------------------------}
- { CloseCurrent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE TStrListMaker.CloseCurrent;
- BEGIN
- If (Cur.Count <> 0) Then Begin
- Index^[IndexPos] := Cur; { Hold index position }
- Inc(IndexPos); { Next index }
- Cur.Count := 0; { Adjust count }
- End;
- END;
- {***************************************************************************}
- { INTERFACE ROUTINES }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { STREAM INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {---------------------------------------------------------------------------}
- { Abstract -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE Abstract;
- BEGIN
- RunError(211); { Abstract error }
- END;
- {---------------------------------------------------------------------------}
- { RegisterObjects -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 02Sep97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE RegisterObjects;
- BEGIN
- RegisterType(RCollection); { Register object }
- RegisterType(RStringCollection); { Register object }
- RegisterType(RStrCollection); { Register object }
- END;
- {---------------------------------------------------------------------------}
- { RegisterType -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 02Sep97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE RegisterType (Var S: TStreamRec);
- VAR P: PStreamRec;
- BEGIN
- P := StreamTypes; { Current reg list }
- While (P <> Nil) AND (P^.ObjType <> S.ObjType)
- Do P := P^.Next; { Find end of chain }
- If (P = Nil) AND (S.ObjType <> 0) Then Begin { Valid end found }
- S.Next := StreamTypes; { Chain the list }
- StreamTypes := @S; { We are now first }
- End Else RegisterError; { Register the error }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { GENERAL FUNCTION INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {---------------------------------------------------------------------------}
- { LongMul -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Feb98 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION LongMul (X, Y: Integer): LongInt;
- BEGIN
- LongMul := LongInt(X*Y); { Multiply integers }
- END;
- {---------------------------------------------------------------------------}
- { LongDiv -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Feb98 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION LongDiv (X: LongInt; Y: Integer): Integer;
- BEGIN
- LongDiv := Integer(X DIV Y); { Divid longint }
- END;
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { DYNAMIC STRING INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {---------------------------------------------------------------------------}
- { NewStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Jun96 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION NewStr (S: String): PString;
- VAR P: PString;
- BEGIN
- If (S = '') Then P := Nil Else Begin { Empty returns nil }
- If (MaxAvail > Length(S)) Then Begin { Check free memory }
- GetMem(P, Length(S) + 1); { Allocate memory }
- If (P <> Nil) Then P^ := S; { Transfer string }
- End Else P := Nil; { Insufficient memory }
- End;
- NewStr := P; { Return result }
- END;
- {---------------------------------------------------------------------------}
- { DisposeStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Jun96 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE DisposeStr (P: PString);
- BEGIN
- If (P <> Nil) Then FreeMem(P, Length(P^) + 1); { Release memory }
- END;
- END.
- {
- $Log$
- Revision 1.2 2000-08-24 12:00:22 marco
- * CVS log and ID tags
- }
|