classes.pas 124 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307
  1. {
  2. This file is part of the Pas2JS run time library.
  3. Copyright (c) 2017 by Mattias Gaertner
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit Classes;
  11. {$mode objfpc}
  12. interface
  13. uses
  14. RTLConsts, Types, SysUtils, JS;
  15. type
  16. TNotifyEvent = procedure(Sender: TObject) of object;
  17. // Notification operations :
  18. // Observer has changed, is freed, item added to/deleted from list, custom event.
  19. TFPObservedOperation = (ooChange,ooFree,ooAddItem,ooDeleteItem,ooCustom);
  20. EStreamError = class(Exception);
  21. EFCreateError = class(EStreamError);
  22. EFOpenError = class(EStreamError);
  23. EFilerError = class(EStreamError);
  24. EReadError = class(EFilerError);
  25. EWriteError = class(EFilerError);
  26. EClassNotFound = class(EFilerError);
  27. EMethodNotFound = class(EFilerError);
  28. EInvalidImage = class(EFilerError);
  29. EResNotFound = class(Exception);
  30. EListError = class(Exception);
  31. EBitsError = class(Exception);
  32. EStringListError = class(EListError);
  33. EComponentError = class(Exception);
  34. EParserError = class(Exception);
  35. EOutOfResources = class(EOutOfMemory);
  36. EInvalidOperation = class(Exception);
  37. TListAssignOp = (laCopy, laAnd, laOr, laXor, laSrcUnique, laDestUnique);
  38. TListSortCompare = function(Item1, Item2: JSValue): Integer;
  39. TListCallback = Types.TListCallback;
  40. TListStaticCallback = Types.TListStaticCallback;
  41. TAlignment = (taLeftJustify, taRightJustify, taCenter);
  42. { TFPListEnumerator }
  43. TFPList = Class;
  44. TFPListEnumerator = class
  45. private
  46. FList: TFPList;
  47. FPosition: Integer;
  48. public
  49. constructor Create(AList: TFPList); reintroduce;
  50. function GetCurrent: JSValue;
  51. function MoveNext: Boolean;
  52. property Current: JSValue read GetCurrent;
  53. end;
  54. { TFPList }
  55. TFPList = class(TObject)
  56. private
  57. FList: TJSValueDynArray;
  58. FCount: Integer;
  59. FCapacity: Integer;
  60. procedure CopyMove(aList: TFPList);
  61. procedure MergeMove(aList: TFPList);
  62. procedure DoCopy(ListA, ListB: TFPList);
  63. procedure DoSrcUnique(ListA, ListB: TFPList);
  64. procedure DoAnd(ListA, ListB: TFPList);
  65. procedure DoDestUnique(ListA, ListB: TFPList);
  66. procedure DoOr(ListA, ListB: TFPList);
  67. procedure DoXOr(ListA, ListB: TFPList);
  68. protected
  69. function Get(Index: Integer): JSValue; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  70. procedure Put(Index: Integer; Item: JSValue); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  71. procedure SetCapacity(NewCapacity: Integer);
  72. procedure SetCount(NewCount: Integer);
  73. Procedure RaiseIndexError(Index: Integer);
  74. public
  75. //Type
  76. // TDirection = (FromBeginning, FromEnd);
  77. destructor Destroy; override;
  78. procedure AddList(AList: TFPList);
  79. function Add(Item: JSValue): Integer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  80. procedure Clear;
  81. procedure Delete(Index: Integer); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  82. class procedure Error(const Msg: string; const Data: String);
  83. procedure Exchange(Index1, Index2: Integer);
  84. function Expand: TFPList; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  85. function Extract(Item: JSValue): JSValue;
  86. function First: JSValue;
  87. function GetEnumerator: TFPListEnumerator;
  88. function IndexOf(Item: JSValue): Integer;
  89. function IndexOfItem(Item: JSValue; Direction: TDirection): Integer;
  90. procedure Insert(Index: Integer; Item: JSValue); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  91. function Last: JSValue;
  92. procedure Move(CurIndex, NewIndex: Integer);
  93. procedure Assign (ListA: TFPList; AOperator: TListAssignOp=laCopy; ListB: TFPList=nil);
  94. function Remove(Item: JSValue): Integer;
  95. procedure Pack;
  96. procedure Sort(const Compare: TListSortCompare);
  97. procedure ForEachCall(const proc2call: TListCallback; const arg: JSValue);
  98. procedure ForEachCall(const proc2call: TListStaticCallback; const arg: JSValue);
  99. property Capacity: Integer read FCapacity write SetCapacity;
  100. property Count: Integer read FCount write SetCount;
  101. property Items[Index: Integer]: JSValue read Get write Put; default;
  102. property List: TJSValueDynArray read FList;
  103. end;
  104. TListNotification = (lnAdded, lnExtracted, lnDeleted);
  105. TList = class;
  106. { TListEnumerator }
  107. TListEnumerator = class
  108. private
  109. FList: TList;
  110. FPosition: Integer;
  111. public
  112. constructor Create(AList: TList); reintroduce;
  113. function GetCurrent: JSValue;
  114. function MoveNext: Boolean;
  115. property Current: JSValue read GetCurrent;
  116. end;
  117. { TList }
  118. TList = class(TObject)
  119. private
  120. FList: TFPList;
  121. procedure CopyMove (aList : TList);
  122. procedure MergeMove (aList : TList);
  123. procedure DoCopy(ListA, ListB : TList);
  124. procedure DoSrcUnique(ListA, ListB : TList);
  125. procedure DoAnd(ListA, ListB : TList);
  126. procedure DoDestUnique(ListA, ListB : TList);
  127. procedure DoOr(ListA, ListB : TList);
  128. procedure DoXOr(ListA, ListB : TList);
  129. protected
  130. function Get(Index: Integer): JSValue;
  131. procedure Put(Index: Integer; Item: JSValue);
  132. procedure Notify(aValue: JSValue; Action: TListNotification); virtual;
  133. procedure SetCapacity(NewCapacity: Integer);
  134. function GetCapacity: integer;
  135. procedure SetCount(NewCount: Integer);
  136. function GetCount: integer;
  137. function GetList: TJSValueDynArray;
  138. property FPList : TFPList Read FList;
  139. public
  140. constructor Create; reintroduce;
  141. destructor Destroy; override;
  142. Procedure AddList(AList : TList);
  143. function Add(Item: JSValue): Integer;
  144. procedure Clear; virtual;
  145. procedure Delete(Index: Integer);
  146. class procedure Error(const Msg: string; Data: String); virtual;
  147. procedure Exchange(Index1, Index2: Integer);
  148. function Expand: TList;
  149. function Extract(Item: JSValue): JSValue;
  150. function First: JSValue;
  151. function GetEnumerator: TListEnumerator;
  152. function IndexOf(Item: JSValue): Integer;
  153. procedure Insert(Index: Integer; Item: JSValue);
  154. function Last: JSValue;
  155. procedure Move(CurIndex, NewIndex: Integer);
  156. procedure Assign (ListA: TList; AOperator: TListAssignOp=laCopy; ListB: TList=nil);
  157. function Remove(Item: JSValue): Integer;
  158. procedure Pack;
  159. procedure Sort(const Compare: TListSortCompare);
  160. property Capacity: Integer read GetCapacity write SetCapacity;
  161. property Count: Integer read GetCount write SetCount;
  162. property Items[Index: Integer]: JSValue read Get write Put; default;
  163. property List: TJSValueDynArray read GetList;
  164. end;
  165. { TPersistent }
  166. {$M+}
  167. TPersistent = class(TObject)
  168. private
  169. //FObservers : TFPList;
  170. procedure AssignError(Source: TPersistent);
  171. protected
  172. procedure AssignTo(Dest: TPersistent); virtual;
  173. function GetOwner: TPersistent; virtual;
  174. public
  175. procedure Assign(Source: TPersistent); virtual;
  176. //procedure FPOAttachObserver(AObserver : TObject);
  177. //procedure FPODetachObserver(AObserver : TObject);
  178. //procedure FPONotifyObservers(ASender : TObject; AOperation: TFPObservedOperation; Data: TObject);
  179. function GetNamePath: string; virtual;
  180. end;
  181. TPersistentClass = Class of TPersistent;
  182. { TInterfacedPersistent }
  183. TInterfacedPersistent = class(TPersistent, IInterface)
  184. private
  185. FOwnerInterface: IInterface;
  186. protected
  187. function _AddRef: Integer;
  188. function _Release: Integer;
  189. public
  190. function QueryInterface(const IID: TGUID; out Obj): integer; virtual;
  191. procedure AfterConstruction; override;
  192. end;
  193. TStrings = Class;
  194. { TStringsEnumerator class }
  195. TStringsEnumerator = class
  196. private
  197. FStrings: TStrings;
  198. FPosition: Integer;
  199. public
  200. constructor Create(AStrings: TStrings); reintroduce;
  201. function GetCurrent: String;
  202. function MoveNext: Boolean;
  203. property Current: String read GetCurrent;
  204. end;
  205. { TStrings class }
  206. TStrings = class(TPersistent)
  207. private
  208. FSpecialCharsInited : boolean;
  209. FAlwaysQuote: Boolean;
  210. FQuoteChar : Char;
  211. FDelimiter : Char;
  212. FNameValueSeparator : Char;
  213. FUpdateCount: Integer;
  214. FLBS : TTextLineBreakStyle;
  215. FSkipLastLineBreak : Boolean;
  216. FStrictDelimiter : Boolean;
  217. FLineBreak : String;
  218. function GetCommaText: string;
  219. function GetName(Index: Integer): string;
  220. function GetValue(const Name: string): string;
  221. Function GetLBS : TTextLineBreakStyle;
  222. Procedure SetLBS (AValue : TTextLineBreakStyle);
  223. procedure SetCommaText(const Value: string);
  224. procedure SetValue(const Name, Value: string);
  225. procedure SetDelimiter(c:Char);
  226. procedure SetQuoteChar(c:Char);
  227. procedure SetNameValueSeparator(c:Char);
  228. procedure DoSetTextStr(const Value: string; DoClear : Boolean);
  229. Function GetDelimiter : Char;
  230. Function GetNameValueSeparator : Char;
  231. Function GetQuoteChar: Char;
  232. Function GetLineBreak : String;
  233. procedure SetLineBreak(const S : String);
  234. Function GetSkipLastLineBreak : Boolean;
  235. procedure SetSkipLastLineBreak(const AValue : Boolean);
  236. protected
  237. procedure Error(const Msg: string; Data: Integer);
  238. function Get(Index: Integer): string; virtual; abstract;
  239. function GetCapacity: Integer; virtual;
  240. function GetCount: Integer; virtual; abstract;
  241. function GetObject(Index: Integer): TObject; virtual;
  242. function GetTextStr: string; virtual;
  243. procedure Put(Index: Integer; const S: string); virtual;
  244. procedure PutObject(Index: Integer; AObject: TObject); virtual;
  245. procedure SetCapacity(NewCapacity: Integer); virtual;
  246. procedure SetTextStr(const Value: string); virtual;
  247. procedure SetUpdateState(Updating: Boolean); virtual;
  248. property UpdateCount: Integer read FUpdateCount;
  249. Function DoCompareText(const s1,s2 : string) : PtrInt; virtual;
  250. Function GetDelimitedText: string;
  251. Procedure SetDelimitedText(Const AValue: string);
  252. Function GetValueFromIndex(Index: Integer): string;
  253. Procedure SetValueFromIndex(Index: Integer; const Value: string);
  254. Procedure CheckSpecialChars;
  255. // Class Function GetNextLine (Const Value : String; Var S : String; Var P : Integer) : Boolean;
  256. Function GetNextLinebreak (Const Value : String; Out S : String; Var P : Integer) : Boolean;
  257. public
  258. constructor Create; reintroduce;
  259. destructor Destroy; override;
  260. function Add(const S: string): Integer; virtual; overload;
  261. // function AddFmt(const Fmt : string; const Args : Array of const): Integer; overload;
  262. function AddObject(const S: string; AObject: TObject): Integer; virtual; overload;
  263. // function AddObject(const Fmt: string; Args : Array of const; AObject: TObject): Integer; overload;
  264. procedure Append(const S: string);
  265. procedure AddStrings(TheStrings: TStrings); overload; virtual;
  266. procedure AddStrings(TheStrings: TStrings; ClearFirst : Boolean); overload;
  267. procedure AddStrings(const TheStrings: array of string); overload; virtual;
  268. procedure AddStrings(const TheStrings: array of string; ClearFirst : Boolean); overload;
  269. function AddPair(const AName, AValue: string): TStrings; overload;
  270. function AddPair(const AName, AValue: string; AObject: TObject): TStrings; overload;
  271. Procedure AddText(Const S : String); virtual;
  272. procedure Assign(Source: TPersistent); override;
  273. procedure BeginUpdate;
  274. procedure Clear; virtual; abstract;
  275. procedure Delete(Index: Integer); virtual; abstract;
  276. procedure EndUpdate;
  277. function Equals(Obj: TObject): Boolean; override; overload;
  278. function Equals(TheStrings: TStrings): Boolean; overload;
  279. procedure Exchange(Index1, Index2: Integer); virtual;
  280. function GetEnumerator: TStringsEnumerator;
  281. function IndexOf(const S: string): Integer; virtual;
  282. function IndexOfName(const Name: string): Integer; virtual;
  283. function IndexOfObject(AObject: TObject): Integer; virtual;
  284. procedure Insert(Index: Integer; const S: string); virtual; abstract;
  285. procedure InsertObject(Index: Integer; const S: string; AObject: TObject);
  286. procedure Move(CurIndex, NewIndex: Integer); virtual;
  287. procedure GetNameValue(Index : Integer; Out AName,AValue : String);
  288. function ExtractName(Const S:String):String;
  289. Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS;
  290. property Delimiter: Char read GetDelimiter write SetDelimiter;
  291. property DelimitedText: string read GetDelimitedText write SetDelimitedText;
  292. property LineBreak : string Read GetLineBreak write SetLineBreak;
  293. Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
  294. property AlwaysQuote: Boolean read FAlwaysQuote write FAlwaysQuote;
  295. property QuoteChar: Char read GetQuoteChar write SetQuoteChar;
  296. Property NameValueSeparator : Char Read GetNameValueSeparator Write SetNameValueSeparator;
  297. property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
  298. property Capacity: Integer read GetCapacity write SetCapacity;
  299. property CommaText: string read GetCommaText write SetCommaText;
  300. property Count: Integer read GetCount;
  301. property Names[Index: Integer]: string read GetName;
  302. property Objects[Index: Integer]: TObject read GetObject write PutObject;
  303. property Values[const Name: string]: string read GetValue write SetValue;
  304. property Strings[Index: Integer]: string read Get write Put; default;
  305. property Text: string read GetTextStr write SetTextStr;
  306. Property SkipLastLineBreak : Boolean Read GetSkipLastLineBreak Write SetSkipLastLineBreak;
  307. end;
  308. { TStringList}
  309. TStringItem = record
  310. FString: string;
  311. FObject: TObject;
  312. end;
  313. TStringItemArray = Array of TStringItem;
  314. TStringList = class;
  315. TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
  316. TStringsSortStyle = (sslNone,sslUser,sslAuto);
  317. TStringsSortStyles = Set of TStringsSortStyle;
  318. TStringList = class(TStrings)
  319. private
  320. FList: TStringItemArray;
  321. FCount: Integer;
  322. FOnChange: TNotifyEvent;
  323. FOnChanging: TNotifyEvent;
  324. FDuplicates: TDuplicates;
  325. FCaseSensitive : Boolean;
  326. FForceSort : Boolean;
  327. FOwnsObjects : Boolean;
  328. FSortStyle: TStringsSortStyle;
  329. procedure ExchangeItemsInt(Index1, Index2: Integer);
  330. function GetSorted: Boolean;
  331. procedure Grow;
  332. procedure InternalClear(FromIndex : Integer = 0; ClearOnly : Boolean = False);
  333. procedure QuickSort(L, R: Integer; CompareFn: TStringListSortCompare);
  334. procedure SetSorted(Value: Boolean);
  335. procedure SetCaseSensitive(b : boolean);
  336. procedure SetSortStyle(AValue: TStringsSortStyle);
  337. protected
  338. Procedure CheckIndex(AIndex : Integer);
  339. procedure ExchangeItems(Index1, Index2: Integer); virtual;
  340. procedure Changed; virtual;
  341. procedure Changing; virtual;
  342. function Get(Index: Integer): string; override;
  343. function GetCapacity: Integer; override;
  344. function GetCount: Integer; override;
  345. function GetObject(Index: Integer): TObject; override;
  346. procedure Put(Index: Integer; const S: string); override;
  347. procedure PutObject(Index: Integer; AObject: TObject); override;
  348. procedure SetCapacity(NewCapacity: Integer); override;
  349. procedure SetUpdateState(Updating: Boolean); override;
  350. procedure InsertItem(Index: Integer; const S: string); virtual;
  351. procedure InsertItem(Index: Integer; const S: string; O: TObject); virtual;
  352. Function DoCompareText(const s1,s2 : string) : PtrInt; override;
  353. function CompareStrings(const s1,s2 : string) : Integer; virtual;
  354. public
  355. destructor Destroy; override;
  356. function Add(const S: string): Integer; override;
  357. procedure Clear; override;
  358. procedure Delete(Index: Integer); override;
  359. procedure Exchange(Index1, Index2: Integer); override;
  360. function Find(const S: string; Out Index: Integer): Boolean; virtual;
  361. function IndexOf(const S: string): Integer; override;
  362. procedure Insert(Index: Integer; const S: string); override;
  363. procedure Sort; virtual;
  364. procedure CustomSort(CompareFn: TStringListSortCompare); virtual;
  365. property Duplicates: TDuplicates read FDuplicates write FDuplicates;
  366. property Sorted: Boolean read GetSorted write SetSorted;
  367. property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
  368. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  369. property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
  370. property OwnsObjects : boolean read FOwnsObjects write FOwnsObjects;
  371. Property SortStyle : TStringsSortStyle Read FSortStyle Write SetSortStyle;
  372. end;
  373. TCollection = class;
  374. { TCollectionItem }
  375. TCollectionItem = class(TPersistent)
  376. private
  377. FCollection: TCollection;
  378. FID: Integer;
  379. FUpdateCount: Integer;
  380. function GetIndex: Integer;
  381. protected
  382. procedure SetCollection(Value: TCollection);virtual;
  383. procedure Changed(AllItems: Boolean);
  384. function GetOwner: TPersistent; override;
  385. function GetDisplayName: string; virtual;
  386. procedure SetIndex(Value: Integer); virtual;
  387. procedure SetDisplayName(const Value: string); virtual;
  388. property UpdateCount: Integer read FUpdateCount;
  389. public
  390. constructor Create(ACollection: TCollection); virtual; reintroduce;
  391. destructor Destroy; override;
  392. function GetNamePath: string; override;
  393. property Collection: TCollection read FCollection write SetCollection;
  394. property ID: Integer read FID;
  395. property Index: Integer read GetIndex write SetIndex;
  396. property DisplayName: string read GetDisplayName write SetDisplayName;
  397. end;
  398. TCollectionEnumerator = class
  399. private
  400. FCollection: TCollection;
  401. FPosition: Integer;
  402. public
  403. constructor Create(ACollection: TCollection); reintroduce;
  404. function GetCurrent: TCollectionItem;
  405. function MoveNext: Boolean;
  406. property Current: TCollectionItem read GetCurrent;
  407. end;
  408. TCollectionItemClass = class of TCollectionItem;
  409. TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);
  410. TCollectionSortCompare = function (Item1, Item2: TCollectionItem): Integer;
  411. TCollection = class(TPersistent)
  412. private
  413. FItemClass: TCollectionItemClass;
  414. FItems: TFpList;
  415. FUpdateCount: Integer;
  416. FNextID: Integer;
  417. FPropName: string;
  418. function GetCount: Integer;
  419. function GetPropName: string;
  420. procedure InsertItem(Item: TCollectionItem);
  421. procedure RemoveItem(Item: TCollectionItem);
  422. procedure DoClear;
  423. protected
  424. { Design-time editor support }
  425. function GetAttrCount: Integer; virtual;
  426. function GetAttr(Index: Integer): string; virtual;
  427. function GetItemAttr(Index, ItemIndex: Integer): string; virtual;
  428. procedure Changed;
  429. function GetItem(Index: Integer): TCollectionItem;
  430. procedure SetItem(Index: Integer; Value: TCollectionItem);
  431. procedure SetItemName(Item: TCollectionItem); virtual;
  432. procedure SetPropName; virtual;
  433. procedure Update(Item: TCollectionItem); virtual;
  434. procedure Notify(Item: TCollectionItem;Action: TCollectionNotification); virtual;
  435. property PropName: string read GetPropName write FPropName;
  436. property UpdateCount: Integer read FUpdateCount;
  437. public
  438. constructor Create(AItemClass: TCollectionItemClass); reintroduce;
  439. destructor Destroy; override;
  440. function Owner: TPersistent;
  441. function Add: TCollectionItem;
  442. procedure Assign(Source: TPersistent); override;
  443. procedure BeginUpdate; virtual;
  444. procedure Clear;
  445. procedure EndUpdate; virtual;
  446. procedure Delete(Index: Integer);
  447. function GetEnumerator: TCollectionEnumerator;
  448. function GetNamePath: string; override;
  449. function Insert(Index: Integer): TCollectionItem;
  450. function FindItemID(ID: Integer): TCollectionItem;
  451. procedure Exchange(Const Index1, index2: integer);
  452. procedure Sort(Const Compare : TCollectionSortCompare);
  453. property Count: Integer read GetCount;
  454. property ItemClass: TCollectionItemClass read FItemClass;
  455. property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
  456. end;
  457. TOwnedCollection = class(TCollection)
  458. private
  459. FOwner: TPersistent;
  460. protected
  461. Function GetOwner: TPersistent; override;
  462. public
  463. Constructor Create(AOwner: TPersistent; AItemClass: TCollectionItemClass); reintroduce;
  464. end;
  465. TComponent = Class;
  466. TOperation = (opInsert, opRemove);
  467. TComponentStateItem = ( csLoading, csReading, csWriting, csDestroying,
  468. csDesigning, csAncestor, csUpdating, csFixups, csFreeNotification,
  469. csInline, csDesignInstance);
  470. TComponentState = set of TComponentStateItem;
  471. TComponentStyleItem = (csInheritable, csCheckPropAvail, csSubComponent, csTransient);
  472. TComponentStyle = set of TComponentStyleItem;
  473. TGetChildProc = procedure (Child: TComponent) of object;
  474. TComponentName = string;
  475. { TComponentEnumerator }
  476. TComponentEnumerator = class
  477. private
  478. FComponent: TComponent;
  479. FPosition: Integer;
  480. public
  481. constructor Create(AComponent: TComponent); reintroduce;
  482. function GetCurrent: TComponent;
  483. function MoveNext: Boolean;
  484. property Current: TComponent read GetCurrent;
  485. end;
  486. TComponent = class(TPersistent, IInterface)
  487. private
  488. FOwner: TComponent;
  489. FName: TComponentName;
  490. FTag: Ptrint;
  491. FComponents: TFpList;
  492. FFreeNotifies: TFpList;
  493. FDesignInfo: Longint;
  494. FComponentState: TComponentState;
  495. function GetComponent(AIndex: Integer): TComponent;
  496. function GetComponentCount: Integer;
  497. function GetComponentIndex: Integer;
  498. procedure Insert(AComponent: TComponent);
  499. procedure Remove(AComponent: TComponent);
  500. procedure RemoveNotification(AComponent: TComponent);
  501. procedure SetComponentIndex(Value: Integer);
  502. protected
  503. FComponentStyle: TComponentStyle;
  504. procedure ChangeName(const NewName: TComponentName);
  505. procedure GetChildren(Proc: TGetChildProc; Root: TComponent); virtual;
  506. function GetChildOwner: TComponent; virtual;
  507. function GetChildParent: TComponent; virtual;
  508. function GetOwner: TPersistent; override;
  509. procedure Loaded; virtual;
  510. procedure Loading; virtual;
  511. procedure SetWriting(Value: Boolean); virtual;
  512. procedure SetReading(Value: Boolean); virtual;
  513. procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
  514. procedure PaletteCreated; virtual;
  515. procedure SetAncestor(Value: Boolean);
  516. procedure SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  517. procedure SetDesignInstance(Value: Boolean);
  518. procedure SetInline(Value: Boolean);
  519. procedure SetName(const NewName: TComponentName); virtual;
  520. procedure SetChildOrder(Child: TComponent; Order: Integer); virtual;
  521. procedure SetParentComponent(Value: TComponent); virtual;
  522. procedure Updating; virtual;
  523. procedure Updated; virtual;
  524. procedure ValidateRename(AComponent: TComponent; const CurName, NewName: string); virtual;
  525. procedure ValidateContainer(AComponent: TComponent); virtual;
  526. procedure ValidateInsert(AComponent: TComponent); virtual;
  527. protected
  528. function _AddRef: Integer;
  529. function _Release: Integer;
  530. public
  531. constructor Create(AOwner: TComponent); virtual; reintroduce;
  532. destructor Destroy; override;
  533. procedure BeforeDestruction; override;
  534. procedure DestroyComponents;
  535. procedure Destroying;
  536. function QueryInterface(const IID: TGUID; out Obj): integer; virtual;
  537. // function ExecuteAction(Action: TBasicAction): Boolean; virtual;
  538. function FindComponent(const AName: string): TComponent;
  539. procedure FreeNotification(AComponent: TComponent);
  540. procedure RemoveFreeNotification(AComponent: TComponent);
  541. function GetNamePath: string; override;
  542. function GetParentComponent: TComponent; virtual;
  543. function HasParent: Boolean; virtual;
  544. procedure InsertComponent(AComponent: TComponent);
  545. procedure RemoveComponent(AComponent: TComponent);
  546. procedure SetSubComponent(ASubComponent: Boolean);
  547. function GetEnumerator: TComponentEnumerator;
  548. // function UpdateAction(Action: TBasicAction): Boolean; dynamic;
  549. property Components[Index: Integer]: TComponent read GetComponent;
  550. property ComponentCount: Integer read GetComponentCount;
  551. property ComponentIndex: Integer read GetComponentIndex write SetComponentIndex;
  552. property ComponentState: TComponentState read FComponentState;
  553. property ComponentStyle: TComponentStyle read FComponentStyle;
  554. property DesignInfo: Longint read FDesignInfo write FDesignInfo;
  555. property Owner: TComponent read FOwner;
  556. published
  557. property Name: TComponentName read FName write SetName stored False;
  558. property Tag: PtrInt read FTag write FTag {default 0};
  559. end;
  560. TComponentClass = Class of TComponent;
  561. TSeekOrigin = (soBeginning, soCurrent, soEnd);
  562. { TStream }
  563. TStream = class(TObject)
  564. private
  565. FEndian: TEndian;
  566. function MakeInt(B: TBytes; aSize: Integer; Signed: Boolean): NativeInt;
  567. function MakeBytes(B: NativeInt; aSize: Integer; Signed: Boolean): TBytes;
  568. protected
  569. procedure InvalidSeek; virtual;
  570. procedure Discard(const Count: NativeInt);
  571. procedure DiscardLarge(Count: NativeInt; const MaxBufferSize: Longint);
  572. procedure FakeSeekForward(Offset: NativeInt; const Origin: TSeekOrigin; const Pos: NativeInt);
  573. function GetPosition: NativeInt; virtual;
  574. procedure SetPosition(const Pos: NativeInt); virtual;
  575. function GetSize: NativeInt; virtual;
  576. procedure SetSize(const NewSize: NativeInt); virtual;
  577. procedure SetSize64(const NewSize: NativeInt); virtual;
  578. procedure ReadNotImplemented;
  579. procedure WriteNotImplemented;
  580. function ReadMaxSizeData(Buffer : TBytes; aSize,aCount : NativeInt) : NativeInt;
  581. Procedure ReadExactSizeData(Buffer : TBytes; aSize,aCount : NativeInt);
  582. function WriteMaxSizeData(Const Buffer : TBytes; aSize,aCount : NativeInt) : NativeInt;
  583. Procedure WriteExactSizeData(Const Buffer : TBytes; aSize,aCount : NativeInt);
  584. public
  585. function Read(var Buffer: TBytes; Count: Longint): Longint; overload;
  586. function Read(Buffer : TBytes; aOffset, Count: Longint): Longint; virtual; abstract; overload;
  587. function Write(const Buffer: TBytes; Count: Longint): Longint; virtual; overload;
  588. function Write(const Buffer: TBytes; Offset, Count: Longint): Longint; virtual; abstract; overload;
  589. function Seek(const Offset: NativeInt; Origin: TSeekOrigin): NativeInt; virtual; abstract; overload;
  590. function ReadData(Buffer: TBytes; Count: NativeInt): NativeInt; overload;
  591. function ReadData(var Buffer: Boolean): NativeInt; overload;
  592. function ReadData(var Buffer: Boolean; Count: NativeInt): NativeInt; overload;
  593. function ReadData(var Buffer: WideChar): NativeInt; overload;
  594. function ReadData(var Buffer: WideChar; Count: NativeInt): NativeInt; overload;
  595. function ReadData(var Buffer: Int8): NativeInt; overload;
  596. function ReadData(var Buffer: Int8; Count: NativeInt): NativeInt; overload;
  597. function ReadData(var Buffer: UInt8): NativeInt; overload;
  598. function ReadData(var Buffer: UInt8; Count: NativeInt): NativeInt; overload;
  599. function ReadData(var Buffer: Int16): NativeInt; overload;
  600. function ReadData(var Buffer: Int16; Count: NativeInt): NativeInt; overload;
  601. function ReadData(var Buffer: UInt16): NativeInt; overload;
  602. function ReadData(var Buffer: UInt16; Count: NativeInt): NativeInt; overload;
  603. function ReadData(var Buffer: Int32): NativeInt; overload;
  604. function ReadData(var Buffer: Int32; Count: NativeInt): NativeInt; overload;
  605. function ReadData(var Buffer: UInt32): NativeInt; overload;
  606. function ReadData(var Buffer: UInt32; Count: NativeInt): NativeInt; overload;
  607. // NativeLargeint. Stored as a float64, Read as float64.
  608. function ReadData(var Buffer: NativeLargeInt): NativeInt; overload;
  609. function ReadData(var Buffer: NativeLargeInt; Count: NativeInt): NativeInt; overload;
  610. function ReadData(var Buffer: NativeLargeUInt): NativeInt; overload;
  611. function ReadData(var Buffer: NativeLargeUInt; Count: NativeInt): NativeInt; overload;
  612. function ReadData(var Buffer: Double): NativeInt; overload;
  613. function ReadData(var Buffer: Double; Count: NativeInt): NativeInt; overload;
  614. procedure ReadBuffer(var Buffer: TBytes; Count: NativeInt); overload;
  615. procedure ReadBuffer(var Buffer: TBytes; Offset, Count: NativeInt); overload;
  616. procedure ReadBufferData(var Buffer: Boolean); overload;
  617. procedure ReadBufferData(var Buffer: Boolean; Count: NativeInt); overload;
  618. procedure ReadBufferData(var Buffer: WideChar); overload;
  619. procedure ReadBufferData(var Buffer: WideChar; Count: NativeInt); overload;
  620. procedure ReadBufferData(var Buffer: Int8); overload;
  621. procedure ReadBufferData(var Buffer: Int8; Count: NativeInt); overload;
  622. procedure ReadBufferData(var Buffer: UInt8); overload;
  623. procedure ReadBufferData(var Buffer: UInt8; Count: NativeInt); overload;
  624. procedure ReadBufferData(var Buffer: Int16); overload;
  625. procedure ReadBufferData(var Buffer: Int16; Count: NativeInt); overload;
  626. procedure ReadBufferData(var Buffer: UInt16); overload;
  627. procedure ReadBufferData(var Buffer: UInt16; Count: NativeInt); overload;
  628. procedure ReadBufferData(var Buffer: Int32); overload;
  629. procedure ReadBufferData(var Buffer: Int32; Count: NativeInt); overload;
  630. procedure ReadBufferData(var Buffer: UInt32); overload;
  631. procedure ReadBufferData(var Buffer: UInt32; Count: NativeInt); overload;
  632. // NativeLargeint. Stored as a float64, Read as float64.
  633. procedure ReadBufferData(var Buffer: NativeLargeInt); overload;
  634. procedure ReadBufferData(var Buffer: NativeLargeInt; Count: NativeInt); overload;
  635. procedure ReadBufferData(var Buffer: NativeLargeUInt); overload;
  636. procedure ReadBufferData(var Buffer: NativeLargeUInt; Count: NativeInt); overload;
  637. procedure ReadBufferData(var Buffer: Double); overload;
  638. procedure ReadBufferData(var Buffer: Double; Count: NativeInt); overload;
  639. procedure WriteBuffer(const Buffer: TBytes; Count: NativeInt); overload;
  640. procedure WriteBuffer(const Buffer: TBytes; Offset, Count: NativeInt); overload;
  641. function WriteData(const Buffer: TBytes; Count: NativeInt): NativeInt; overload;
  642. function WriteData(const Buffer: Boolean): NativeInt; overload;
  643. function WriteData(const Buffer: Boolean; Count: NativeInt): NativeInt; overload;
  644. function WriteData(const Buffer: WideChar): NativeInt; overload;
  645. function WriteData(const Buffer: WideChar; Count: NativeInt): NativeInt; overload;
  646. function WriteData(const Buffer: Int8): NativeInt; overload;
  647. function WriteData(const Buffer: Int8; Count: NativeInt): NativeInt; overload;
  648. function WriteData(const Buffer: UInt8): NativeInt; overload;
  649. function WriteData(const Buffer: UInt8; Count: NativeInt): NativeInt; overload;
  650. function WriteData(const Buffer: Int16): NativeInt; overload;
  651. function WriteData(const Buffer: Int16; Count: NativeInt): NativeInt; overload;
  652. function WriteData(const Buffer: UInt16): NativeInt; overload;
  653. function WriteData(const Buffer: UInt16; Count: NativeInt): NativeInt; overload;
  654. function WriteData(const Buffer: Int32): NativeInt; overload;
  655. function WriteData(const Buffer: Int32; Count: NativeInt): NativeInt; overload;
  656. function WriteData(const Buffer: UInt32): NativeInt; overload;
  657. function WriteData(const Buffer: UInt32; Count: NativeInt): NativeInt; overload;
  658. // NativeLargeint. Stored as a float64, Read as float64.
  659. function WriteData(const Buffer: NativeLargeInt): NativeInt; overload;
  660. function WriteData(const Buffer: NativeLargeInt; Count: NativeInt): NativeInt; overload;
  661. function WriteData(const Buffer: NativeLargeUInt): NativeInt; overload;
  662. function WriteData(const Buffer: NativeLargeUInt; Count: NativeInt): NativeInt; overload;
  663. function WriteData(const Buffer: Double): NativeInt; overload;
  664. function WriteData(const Buffer: Double; Count: NativeInt): NativeInt; overload;
  665. {$IFDEF FPC_HAS_TYPE_EXTENDED}
  666. function WriteData(const Buffer: Extended): NativeInt; overload;
  667. function WriteData(const Buffer: Extended; Count: NativeInt): NativeInt; overload;
  668. function WriteData(const Buffer: TExtended80Rec): NativeInt; overload;
  669. function WriteData(const Buffer: TExtended80Rec; Count: NativeInt): NativeInt; overload;
  670. {$ENDIF}
  671. procedure WriteBufferData(Buffer: Int32); overload;
  672. procedure WriteBufferData(Buffer: Int32; Count: NativeInt); overload;
  673. procedure WriteBufferData(Buffer: Boolean); overload;
  674. procedure WriteBufferData(Buffer: Boolean; Count: NativeInt); overload;
  675. procedure WriteBufferData(Buffer: WideChar); overload;
  676. procedure WriteBufferData(Buffer: WideChar; Count: NativeInt); overload;
  677. procedure WriteBufferData(Buffer: Int8); overload;
  678. procedure WriteBufferData(Buffer: Int8; Count: NativeInt); overload;
  679. procedure WriteBufferData(Buffer: UInt8); overload;
  680. procedure WriteBufferData(Buffer: UInt8; Count: NativeInt); overload;
  681. procedure WriteBufferData(Buffer: Int16); overload;
  682. procedure WriteBufferData(Buffer: Int16; Count: NativeInt); overload;
  683. procedure WriteBufferData(Buffer: UInt16); overload;
  684. procedure WriteBufferData(Buffer: UInt16; Count: NativeInt); overload;
  685. procedure WriteBufferData(Buffer: UInt32); overload;
  686. procedure WriteBufferData(Buffer: UInt32; Count: NativeInt); overload;
  687. // NativeLargeint. Stored as a float64, Read as float64.
  688. procedure WriteBufferData(Buffer: NativeLargeInt); overload;
  689. procedure WriteBufferData(Buffer: NativeLargeInt; Count: NativeInt); overload;
  690. procedure WriteBufferData(Buffer: NativeLargeUInt); overload;
  691. procedure WriteBufferData(Buffer: NativeLargeUInt; Count: NativeInt); overload;
  692. procedure WriteBufferData(Buffer: Double); overload;
  693. procedure WriteBufferData(Buffer: Double; Count: NativeInt); overload;
  694. function CopyFrom(Source: TStream; Count: NativeInt): NativeInt;
  695. { function ReadComponent(Instance: TComponent): TComponent;
  696. function ReadComponentRes(Instance: TComponent): TComponent;
  697. procedure WriteComponent(Instance: TComponent);
  698. procedure WriteComponentRes(const ResName: string; Instance: TComponent);
  699. procedure WriteDescendent(Instance, Ancestor: TComponent);
  700. procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
  701. procedure WriteResourceHeader(const ResName: string; {!!!:out} var FixupInfo: Longint);
  702. procedure FixupResourceHeader(FixupInfo: Longint);
  703. procedure ReadResHeader; }
  704. function ReadByte : Byte;
  705. function ReadWord : Word;
  706. function ReadDWord : Cardinal;
  707. function ReadQWord : NativeLargeUInt;
  708. procedure WriteByte(b : Byte);
  709. procedure WriteWord(w : Word);
  710. procedure WriteDWord(d : Cardinal);
  711. procedure WriteQWord(q : NativeLargeUInt);
  712. property Position: NativeInt read GetPosition write SetPosition;
  713. property Size: NativeInt read GetSize write SetSize64;
  714. Property Endian: TEndian Read FEndian Write FEndian;
  715. end;
  716. { TCustomMemoryStream abstract class }
  717. TCustomMemoryStream = class(TStream)
  718. private
  719. FMemory: TJSArrayBuffer;
  720. FDataView : TJSDataView;
  721. FDataArray : TJSUint8Array;
  722. FSize, FPosition: PtrInt;
  723. FSizeBoundsSeek : Boolean;
  724. function GetDataArray: TJSUint8Array;
  725. function GetDataView: TJSDataview;
  726. protected
  727. Function GetSize : NativeInt; Override;
  728. function GetPosition: NativeInt; Override;
  729. procedure SetPointer(Ptr: TJSArrayBuffer; ASize: PtrInt);
  730. Property DataView : TJSDataview Read GetDataView;
  731. Property DataArray : TJSUint8Array Read GetDataArray;
  732. public
  733. Class Function MemoryToBytes(Mem : TJSArrayBuffer) : TBytes; overload;
  734. Class Function MemoryToBytes(Mem : TJSUint8Array) : TBytes; overload;
  735. Class Function BytesToMemory(aBytes : TBytes) : TJSArrayBuffer;
  736. function Read(Buffer : TBytes; Offset, Count: LongInt): LongInt; override;
  737. function Seek(const Offset: NativeInt; Origin: TSeekOrigin): NativeInt; override;
  738. procedure SaveToStream(Stream: TStream);
  739. property Memory: TJSArrayBuffer read FMemory;
  740. Property SizeBoundsSeek : Boolean Read FSizeBoundsSeek Write FSizeBoundsSeek;
  741. end;
  742. { TMemoryStream }
  743. TMemoryStream = class(TCustomMemoryStream)
  744. private
  745. FCapacity: PtrInt;
  746. procedure SetCapacity(NewCapacity: PtrInt);
  747. protected
  748. function Realloc(var NewCapacity: PtrInt): TJSArrayBuffer; virtual;
  749. property Capacity: PtrInt read FCapacity write SetCapacity;
  750. public
  751. destructor Destroy; override;
  752. procedure Clear;
  753. procedure LoadFromStream(Stream: TStream);
  754. procedure SetSize(const NewSize: NativeInt); override;
  755. function Write(const Buffer: TBytes; Offset, Count: LongInt): LongInt; override;
  756. end;
  757. { TBytesStream }
  758. TBytesStream = class(TMemoryStream)
  759. private
  760. function GetBytes: TBytes;
  761. public
  762. constructor Create(const ABytes: TBytes); virtual; overload;
  763. property Bytes: TBytes read GetBytes;
  764. end;
  765. Procedure RegisterClass(AClass : TPersistentClass);
  766. Function GetClass(AClassName : string) : TPersistentClass;
  767. implementation
  768. { TInterfacedPersistent }
  769. function TInterfacedPersistent._AddRef: Integer;
  770. begin
  771. Result:=-1;
  772. if Assigned(FOwnerInterface) then
  773. Result:=FOwnerInterface._AddRef;
  774. end;
  775. function TInterfacedPersistent._Release: Integer;
  776. begin
  777. Result:=-1;
  778. if Assigned(FOwnerInterface) then
  779. Result:=FOwnerInterface._Release;
  780. end;
  781. function TInterfacedPersistent.QueryInterface(const IID: TGUID; out Obj): integer;
  782. begin
  783. Result:=E_NOINTERFACE;
  784. if GetInterface(IID, Obj) then
  785. Result:=0;
  786. end;
  787. procedure TInterfacedPersistent.AfterConstruction;
  788. begin
  789. inherited AfterConstruction;
  790. if (GetOwner<>nil) then
  791. GetOwner.GetInterface(IInterface, FOwnerInterface);
  792. end;
  793. { TComponentEnumerator }
  794. constructor TComponentEnumerator.Create(AComponent: TComponent);
  795. begin
  796. inherited Create;
  797. FComponent := AComponent;
  798. FPosition := -1;
  799. end;
  800. function TComponentEnumerator.GetCurrent: TComponent;
  801. begin
  802. Result := FComponent.Components[FPosition];
  803. end;
  804. function TComponentEnumerator.MoveNext: Boolean;
  805. begin
  806. Inc(FPosition);
  807. Result := FPosition < FComponent.ComponentCount;
  808. end;
  809. { TListEnumerator }
  810. constructor TListEnumerator.Create(AList: TList);
  811. begin
  812. inherited Create;
  813. FList := AList;
  814. FPosition := -1;
  815. end;
  816. function TListEnumerator.GetCurrent: JSValue;
  817. begin
  818. Result := FList[FPosition];
  819. end;
  820. function TListEnumerator.MoveNext: Boolean;
  821. begin
  822. Inc(FPosition);
  823. Result := FPosition < FList.Count;
  824. end;
  825. { TFPListEnumerator }
  826. constructor TFPListEnumerator.Create(AList: TFPList);
  827. begin
  828. inherited Create;
  829. FList := AList;
  830. FPosition := -1;
  831. end;
  832. function TFPListEnumerator.GetCurrent: JSValue;
  833. begin
  834. Result := FList[FPosition];
  835. end;
  836. function TFPListEnumerator.MoveNext: Boolean;
  837. begin
  838. Inc(FPosition);
  839. Result := FPosition < FList.Count;
  840. end;
  841. { TFPList }
  842. procedure TFPList.CopyMove(aList: TFPList);
  843. var r : integer;
  844. begin
  845. Clear;
  846. for r := 0 to aList.count-1 do
  847. Add(aList[r]);
  848. end;
  849. procedure TFPList.MergeMove(aList: TFPList);
  850. var r : integer;
  851. begin
  852. For r := 0 to aList.count-1 do
  853. if IndexOf(aList[r]) < 0 then
  854. Add(aList[r]);
  855. end;
  856. procedure TFPList.DoCopy(ListA, ListB: TFPList);
  857. begin
  858. if Assigned(ListB) then
  859. CopyMove(ListB)
  860. else
  861. CopyMove(ListA);
  862. end;
  863. procedure TFPList.DoSrcUnique(ListA, ListB: TFPList);
  864. var r : integer;
  865. begin
  866. if Assigned(ListB) then
  867. begin
  868. Clear;
  869. for r := 0 to ListA.Count-1 do
  870. if ListB.IndexOf(ListA[r]) < 0 then
  871. Add(ListA[r]);
  872. end
  873. else
  874. begin
  875. for r := Count-1 downto 0 do
  876. if ListA.IndexOf(Self[r]) >= 0 then
  877. Delete(r);
  878. end;
  879. end;
  880. procedure TFPList.DoAnd(ListA, ListB: TFPList);
  881. var r : integer;
  882. begin
  883. if Assigned(ListB) then
  884. begin
  885. Clear;
  886. for r := 0 to ListA.count-1 do
  887. if ListB.IndexOf(ListA[r]) >= 0 then
  888. Add(ListA[r]);
  889. end
  890. else
  891. begin
  892. for r := Count-1 downto 0 do
  893. if ListA.IndexOf(Self[r]) < 0 then
  894. Delete(r);
  895. end;
  896. end;
  897. procedure TFPList.DoDestUnique(ListA, ListB: TFPList);
  898. procedure MoveElements(Src, Dest: TFPList);
  899. var r : integer;
  900. begin
  901. Clear;
  902. for r := 0 to Src.count-1 do
  903. if Dest.IndexOf(Src[r]) < 0 then
  904. self.Add(Src[r]);
  905. end;
  906. var Dest : TFPList;
  907. begin
  908. if Assigned(ListB) then
  909. MoveElements(ListB, ListA)
  910. else
  911. Dest := TFPList.Create;
  912. try
  913. Dest.CopyMove(Self);
  914. MoveElements(ListA, Dest)
  915. finally
  916. Dest.Destroy;
  917. end;
  918. end;
  919. procedure TFPList.DoOr(ListA, ListB: TFPList);
  920. begin
  921. if Assigned(ListB) then
  922. begin
  923. CopyMove(ListA);
  924. MergeMove(ListB);
  925. end
  926. else
  927. MergeMove(ListA);
  928. end;
  929. procedure TFPList.DoXOr(ListA, ListB: TFPList);
  930. var
  931. r : integer;
  932. l : TFPList;
  933. begin
  934. if Assigned(ListB) then
  935. begin
  936. Clear;
  937. for r := 0 to ListA.Count-1 do
  938. if ListB.IndexOf(ListA[r]) < 0 then
  939. Add(ListA[r]);
  940. for r := 0 to ListB.Count-1 do
  941. if ListA.IndexOf(ListB[r]) < 0 then
  942. Add(ListB[r]);
  943. end
  944. else
  945. begin
  946. l := TFPList.Create;
  947. try
  948. l.CopyMove(Self);
  949. for r := Count-1 downto 0 do
  950. if listA.IndexOf(Self[r]) >= 0 then
  951. Delete(r);
  952. for r := 0 to ListA.Count-1 do
  953. if l.IndexOf(ListA[r]) < 0 then
  954. Add(ListA[r]);
  955. finally
  956. l.Destroy;
  957. end;
  958. end;
  959. end;
  960. function TFPList.Get(Index: Integer): JSValue;
  961. begin
  962. If (Index < 0) or (Index >= FCount) then
  963. RaiseIndexError(Index);
  964. Result:=FList[Index];
  965. end;
  966. procedure TFPList.Put(Index: Integer; Item: JSValue);
  967. begin
  968. if (Index < 0) or (Index >= FCount) then
  969. RaiseIndexError(Index);
  970. FList[Index] := Item;
  971. end;
  972. procedure TFPList.SetCapacity(NewCapacity: Integer);
  973. begin
  974. If (NewCapacity < FCount) then
  975. Error (SListCapacityError, str(NewCapacity));
  976. if NewCapacity = FCapacity then
  977. exit;
  978. SetLength(FList,NewCapacity);
  979. FCapacity := NewCapacity;
  980. end;
  981. procedure TFPList.SetCount(NewCount: Integer);
  982. begin
  983. if (NewCount < 0) then
  984. Error(SListCountError, str(NewCount));
  985. If NewCount > FCount then
  986. begin
  987. If NewCount > FCapacity then
  988. SetCapacity(NewCount);
  989. end;
  990. FCount := NewCount;
  991. end;
  992. procedure TFPList.RaiseIndexError(Index: Integer);
  993. begin
  994. Error(SListIndexError, str(Index));
  995. end;
  996. destructor TFPList.Destroy;
  997. begin
  998. Clear;
  999. inherited Destroy;
  1000. end;
  1001. procedure TFPList.AddList(AList: TFPList);
  1002. Var
  1003. I : Integer;
  1004. begin
  1005. If (Capacity<Count+AList.Count) then
  1006. Capacity:=Count+AList.Count;
  1007. For I:=0 to AList.Count-1 do
  1008. Add(AList[i]);
  1009. end;
  1010. function TFPList.Add(Item: JSValue): Integer;
  1011. begin
  1012. if FCount = FCapacity then
  1013. Expand;
  1014. FList[FCount] := Item;
  1015. Result := FCount;
  1016. Inc(FCount);
  1017. end;
  1018. procedure TFPList.Clear;
  1019. begin
  1020. if Assigned(FList) then
  1021. begin
  1022. SetCount(0);
  1023. SetCapacity(0);
  1024. end;
  1025. end;
  1026. procedure TFPList.Delete(Index: Integer);
  1027. begin
  1028. If (Index<0) or (Index>=FCount) then
  1029. Error (SListIndexError, str(Index));
  1030. FCount := FCount-1;
  1031. System.Delete(FList,Index,1);
  1032. Dec(FCapacity);
  1033. end;
  1034. class procedure TFPList.Error(const Msg: string; const Data: String);
  1035. begin
  1036. Raise EListError.CreateFmt(Msg,[Data]);
  1037. end;
  1038. procedure TFPList.Exchange(Index1, Index2: Integer);
  1039. var
  1040. Temp : JSValue;
  1041. begin
  1042. If (Index1 >= FCount) or (Index1 < 0) then
  1043. Error(SListIndexError, str(Index1));
  1044. If (Index2 >= FCount) or (Index2 < 0) then
  1045. Error(SListIndexError, str(Index2));
  1046. Temp := FList[Index1];
  1047. FList[Index1] := FList[Index2];
  1048. FList[Index2] := Temp;
  1049. end;
  1050. function TFPList.Expand: TFPList;
  1051. var
  1052. IncSize : Integer;
  1053. begin
  1054. if FCount < FCapacity then exit(self);
  1055. IncSize := 4;
  1056. if FCapacity > 3 then IncSize := IncSize + 4;
  1057. if FCapacity > 8 then IncSize := IncSize+8;
  1058. if FCapacity > 127 then Inc(IncSize, FCapacity shr 2);
  1059. SetCapacity(FCapacity + IncSize);
  1060. Result := Self;
  1061. end;
  1062. function TFPList.Extract(Item: JSValue): JSValue;
  1063. var
  1064. i : Integer;
  1065. begin
  1066. i := IndexOf(Item);
  1067. if i >= 0 then
  1068. begin
  1069. Result := Item;
  1070. Delete(i);
  1071. end
  1072. else
  1073. Result := nil;
  1074. end;
  1075. function TFPList.First: JSValue;
  1076. begin
  1077. If FCount = 0 then
  1078. Result := Nil
  1079. else
  1080. Result := Items[0];
  1081. end;
  1082. function TFPList.GetEnumerator: TFPListEnumerator;
  1083. begin
  1084. Result:=TFPListEnumerator.Create(Self);
  1085. end;
  1086. function TFPList.IndexOf(Item: JSValue): Integer;
  1087. Var
  1088. C : Integer;
  1089. begin
  1090. Result:=0;
  1091. C:=Count;
  1092. while (Result<C) and (FList[Result]<>Item) do
  1093. Inc(Result);
  1094. If Result>=C then
  1095. Result:=-1;
  1096. end;
  1097. function TFPList.IndexOfItem(Item: JSValue; Direction: TDirection): Integer;
  1098. begin
  1099. if Direction=fromBeginning then
  1100. Result:=IndexOf(Item)
  1101. else
  1102. begin
  1103. Result:=Count-1;
  1104. while (Result >=0) and (Flist[Result]<>Item) do
  1105. Result:=Result - 1;
  1106. end;
  1107. end;
  1108. procedure TFPList.Insert(Index: Integer; Item: JSValue);
  1109. begin
  1110. if (Index < 0) or (Index > FCount )then
  1111. Error(SlistIndexError, str(Index));
  1112. TJSArray(FList).splice(Index, 0, Item);
  1113. inc(FCapacity);
  1114. inc(FCount);
  1115. end;
  1116. function TFPList.Last: JSValue;
  1117. begin
  1118. If FCount = 0 then
  1119. Result := nil
  1120. else
  1121. Result := Items[FCount - 1];
  1122. end;
  1123. procedure TFPList.Move(CurIndex, NewIndex: Integer);
  1124. var
  1125. Temp: JSValue;
  1126. begin
  1127. if (CurIndex < 0) or (CurIndex > Count - 1) then
  1128. Error(SListIndexError, str(CurIndex));
  1129. if (NewIndex < 0) or (NewIndex > Count -1) then
  1130. Error(SlistIndexError, str(NewIndex));
  1131. if CurIndex=NewIndex then exit;
  1132. Temp:=FList[CurIndex];
  1133. // ToDo: use TJSArray.copyWithin if available
  1134. TJSArray(FList).splice(CurIndex,1);
  1135. TJSArray(FList).splice(NewIndex,0,Temp);
  1136. end;
  1137. procedure TFPList.Assign(ListA: TFPList; AOperator: TListAssignOp;
  1138. ListB: TFPList);
  1139. begin
  1140. case AOperator of
  1141. laCopy : DoCopy (ListA, ListB); // replace dest with src
  1142. laSrcUnique : DoSrcUnique (ListA, ListB); // replace dest with src that are not in dest
  1143. laAnd : DoAnd (ListA, ListB); // remove from dest that are not in src
  1144. laDestUnique: DoDestUnique (ListA, ListB);// remove from dest that are in src
  1145. laOr : DoOr (ListA, ListB); // add to dest from src and not in dest
  1146. laXOr : DoXOr (ListA, ListB); // add to dest from src and not in dest, remove from dest that are in src
  1147. end;
  1148. end;
  1149. function TFPList.Remove(Item: JSValue): Integer;
  1150. begin
  1151. Result := IndexOf(Item);
  1152. If Result <> -1 then
  1153. Delete(Result);
  1154. end;
  1155. procedure TFPList.Pack;
  1156. var
  1157. Dst, i: Integer;
  1158. V: JSValue;
  1159. begin
  1160. Dst:=0;
  1161. for i:=0 to Count-1 do
  1162. begin
  1163. V:=FList[i];
  1164. if not Assigned(V) then continue;
  1165. FList[Dst]:=V;
  1166. inc(Dst);
  1167. end;
  1168. end;
  1169. // Needed by Sort method.
  1170. Procedure QuickSort(aList: TJSValueDynArray; L, R : Longint;
  1171. const Compare: TListSortCompare);
  1172. var
  1173. I, J : Longint;
  1174. P, Q : JSValue;
  1175. begin
  1176. repeat
  1177. I := L;
  1178. J := R;
  1179. P := aList[ (L + R) div 2 ];
  1180. repeat
  1181. while Compare(P, aList[i]) > 0 do
  1182. I := I + 1;
  1183. while Compare(P, aList[J]) < 0 do
  1184. J := J - 1;
  1185. If I <= J then
  1186. begin
  1187. Q := aList[I];
  1188. aList[I] := aList[J];
  1189. aList[J] := Q;
  1190. I := I + 1;
  1191. J := J - 1;
  1192. end;
  1193. until I > J;
  1194. // sort the smaller range recursively
  1195. // sort the bigger range via the loop
  1196. // Reasons: memory usage is O(log(n)) instead of O(n) and loop is faster than recursion
  1197. if J - L < R - I then
  1198. begin
  1199. if L < J then
  1200. QuickSort(aList, L, J, Compare);
  1201. L := I;
  1202. end
  1203. else
  1204. begin
  1205. if I < R then
  1206. QuickSort(aList, I, R, Compare);
  1207. R := J;
  1208. end;
  1209. until L >= R;
  1210. end;
  1211. procedure TFPList.Sort(const Compare: TListSortCompare);
  1212. begin
  1213. if Not Assigned(FList) or (FCount < 2) then exit;
  1214. QuickSort(Flist, 0, FCount-1, Compare);
  1215. end;
  1216. procedure TFPList.ForEachCall(const proc2call: TListCallback; const arg: JSValue
  1217. );
  1218. var
  1219. i : integer;
  1220. v : JSValue;
  1221. begin
  1222. For I:=0 To Count-1 Do
  1223. begin
  1224. v:=FList[i];
  1225. if Assigned(v) then
  1226. proc2call(v,arg);
  1227. end;
  1228. end;
  1229. procedure TFPList.ForEachCall(const proc2call: TListStaticCallback;
  1230. const arg: JSValue);
  1231. var
  1232. i : integer;
  1233. v : JSValue;
  1234. begin
  1235. For I:=0 To Count-1 Do
  1236. begin
  1237. v:=FList[i];
  1238. if Assigned(v) then
  1239. proc2call(v,arg);
  1240. end;
  1241. end;
  1242. { TList }
  1243. procedure TList.CopyMove(aList: TList);
  1244. var
  1245. r : integer;
  1246. begin
  1247. Clear;
  1248. for r := 0 to aList.count-1 do
  1249. Add(aList[r]);
  1250. end;
  1251. procedure TList.MergeMove(aList: TList);
  1252. var r : integer;
  1253. begin
  1254. For r := 0 to aList.count-1 do
  1255. if IndexOf(aList[r]) < 0 then
  1256. Add(aList[r]);
  1257. end;
  1258. procedure TList.DoCopy(ListA, ListB: TList);
  1259. begin
  1260. if Assigned(ListB) then
  1261. CopyMove(ListB)
  1262. else
  1263. CopyMove(ListA);
  1264. end;
  1265. procedure TList.DoSrcUnique(ListA, ListB: TList);
  1266. var r : integer;
  1267. begin
  1268. if Assigned(ListB) then
  1269. begin
  1270. Clear;
  1271. for r := 0 to ListA.Count-1 do
  1272. if ListB.IndexOf(ListA[r]) < 0 then
  1273. Add(ListA[r]);
  1274. end
  1275. else
  1276. begin
  1277. for r := Count-1 downto 0 do
  1278. if ListA.IndexOf(Self[r]) >= 0 then
  1279. Delete(r);
  1280. end;
  1281. end;
  1282. procedure TList.DoAnd(ListA, ListB: TList);
  1283. var r : integer;
  1284. begin
  1285. if Assigned(ListB) then
  1286. begin
  1287. Clear;
  1288. for r := 0 to ListA.Count-1 do
  1289. if ListB.IndexOf(ListA[r]) >= 0 then
  1290. Add(ListA[r]);
  1291. end
  1292. else
  1293. begin
  1294. for r := Count-1 downto 0 do
  1295. if ListA.IndexOf(Self[r]) < 0 then
  1296. Delete(r);
  1297. end;
  1298. end;
  1299. procedure TList.DoDestUnique(ListA, ListB: TList);
  1300. procedure MoveElements(Src, Dest : TList);
  1301. var r : integer;
  1302. begin
  1303. Clear;
  1304. for r := 0 to Src.Count-1 do
  1305. if Dest.IndexOf(Src[r]) < 0 then
  1306. Add(Src[r]);
  1307. end;
  1308. var Dest : TList;
  1309. begin
  1310. if Assigned(ListB) then
  1311. MoveElements(ListB, ListA)
  1312. else
  1313. try
  1314. Dest := TList.Create;
  1315. Dest.CopyMove(Self);
  1316. MoveElements(ListA, Dest)
  1317. finally
  1318. Dest.Destroy;
  1319. end;
  1320. end;
  1321. procedure TList.DoOr(ListA, ListB: TList);
  1322. begin
  1323. if Assigned(ListB) then
  1324. begin
  1325. CopyMove(ListA);
  1326. MergeMove(ListB);
  1327. end
  1328. else
  1329. MergeMove(ListA);
  1330. end;
  1331. procedure TList.DoXOr(ListA, ListB: TList);
  1332. var
  1333. r : integer;
  1334. l : TList;
  1335. begin
  1336. if Assigned(ListB) then
  1337. begin
  1338. Clear;
  1339. for r := 0 to ListA.Count-1 do
  1340. if ListB.IndexOf(ListA[r]) < 0 then
  1341. Add(ListA[r]);
  1342. for r := 0 to ListB.Count-1 do
  1343. if ListA.IndexOf(ListB[r]) < 0 then
  1344. Add(ListB[r]);
  1345. end
  1346. else
  1347. try
  1348. l := TList.Create;
  1349. l.CopyMove (Self);
  1350. for r := Count-1 downto 0 do
  1351. if listA.IndexOf(Self[r]) >= 0 then
  1352. Delete(r);
  1353. for r := 0 to ListA.Count-1 do
  1354. if l.IndexOf(ListA[r]) < 0 then
  1355. Add(ListA[r]);
  1356. finally
  1357. l.Destroy;
  1358. end;
  1359. end;
  1360. function TList.Get(Index: Integer): JSValue;
  1361. begin
  1362. Result := FList.Get(Index);
  1363. end;
  1364. procedure TList.Put(Index: Integer; Item: JSValue);
  1365. var V : JSValue;
  1366. begin
  1367. V := Get(Index);
  1368. FList.Put(Index, Item);
  1369. if Assigned(V) then
  1370. Notify(V, lnDeleted);
  1371. if Assigned(Item) then
  1372. Notify(Item, lnAdded);
  1373. end;
  1374. procedure TList.Notify(aValue: JSValue; Action: TListNotification);
  1375. begin
  1376. if Assigned(aValue) then ;
  1377. if Action=lnExtracted then ;
  1378. end;
  1379. procedure TList.SetCapacity(NewCapacity: Integer);
  1380. begin
  1381. FList.SetCapacity(NewCapacity);
  1382. end;
  1383. function TList.GetCapacity: integer;
  1384. begin
  1385. Result := FList.Capacity;
  1386. end;
  1387. procedure TList.SetCount(NewCount: Integer);
  1388. begin
  1389. if NewCount < FList.Count then
  1390. while FList.Count > NewCount do
  1391. Delete(FList.Count - 1)
  1392. else
  1393. FList.SetCount(NewCount);
  1394. end;
  1395. function TList.GetCount: integer;
  1396. begin
  1397. Result := FList.Count;
  1398. end;
  1399. function TList.GetList: TJSValueDynArray;
  1400. begin
  1401. Result := FList.List;
  1402. end;
  1403. constructor TList.Create;
  1404. begin
  1405. inherited Create;
  1406. FList := TFPList.Create;
  1407. end;
  1408. destructor TList.Destroy;
  1409. begin
  1410. if Assigned(FList) then
  1411. Clear;
  1412. FreeAndNil(FList);
  1413. end;
  1414. procedure TList.AddList(AList: TList);
  1415. var
  1416. I: Integer;
  1417. begin
  1418. { this only does FList.AddList(AList.FList), avoiding notifications }
  1419. FList.AddList(AList.FList);
  1420. { make lnAdded notifications }
  1421. for I := 0 to AList.Count - 1 do
  1422. if Assigned(AList[I]) then
  1423. Notify(AList[I], lnAdded);
  1424. end;
  1425. function TList.Add(Item: JSValue): Integer;
  1426. begin
  1427. Result := FList.Add(Item);
  1428. if Assigned(Item) then
  1429. Notify(Item, lnAdded);
  1430. end;
  1431. procedure TList.Clear;
  1432. begin
  1433. While (FList.Count>0) do
  1434. Delete(Count-1);
  1435. end;
  1436. procedure TList.Delete(Index: Integer);
  1437. var V : JSValue;
  1438. begin
  1439. V:=FList.Get(Index);
  1440. FList.Delete(Index);
  1441. if assigned(V) then
  1442. Notify(V, lnDeleted);
  1443. end;
  1444. class procedure TList.Error(const Msg: string; Data: String);
  1445. begin
  1446. Raise EListError.CreateFmt(Msg,[Data]);
  1447. end;
  1448. procedure TList.Exchange(Index1, Index2: Integer);
  1449. begin
  1450. FList.Exchange(Index1, Index2);
  1451. end;
  1452. function TList.Expand: TList;
  1453. begin
  1454. FList.Expand;
  1455. Result:=Self;
  1456. end;
  1457. function TList.Extract(Item: JSValue): JSValue;
  1458. var c : integer;
  1459. begin
  1460. c := FList.Count;
  1461. Result := FList.Extract(Item);
  1462. if c <> FList.Count then
  1463. Notify (Result, lnExtracted);
  1464. end;
  1465. function TList.First: JSValue;
  1466. begin
  1467. Result := FList.First;
  1468. end;
  1469. function TList.GetEnumerator: TListEnumerator;
  1470. begin
  1471. Result:=TListEnumerator.Create(Self);
  1472. end;
  1473. function TList.IndexOf(Item: JSValue): Integer;
  1474. begin
  1475. Result := FList.IndexOf(Item);
  1476. end;
  1477. procedure TList.Insert(Index: Integer; Item: JSValue);
  1478. begin
  1479. FList.Insert(Index, Item);
  1480. if Assigned(Item) then
  1481. Notify(Item,lnAdded);
  1482. end;
  1483. function TList.Last: JSValue;
  1484. begin
  1485. Result := FList.Last;
  1486. end;
  1487. procedure TList.Move(CurIndex, NewIndex: Integer);
  1488. begin
  1489. FList.Move(CurIndex, NewIndex);
  1490. end;
  1491. procedure TList.Assign(ListA: TList; AOperator: TListAssignOp; ListB: TList);
  1492. begin
  1493. case AOperator of
  1494. laCopy : DoCopy (ListA, ListB); // replace dest with src
  1495. laSrcUnique : DoSrcUnique (ListA, ListB); // replace dest with src that are not in dest
  1496. laAnd : DoAnd (ListA, ListB); // remove from dest that are not in src
  1497. laDestUnique: DoDestUnique (ListA, ListB);// remove from dest that are in src
  1498. laOr : DoOr (ListA, ListB); // add to dest from src and not in dest
  1499. laXOr : DoXOr (ListA, ListB); // add to dest from src and not in dest, remove from dest that are in src
  1500. end;
  1501. end;
  1502. function TList.Remove(Item: JSValue): Integer;
  1503. begin
  1504. Result := IndexOf(Item);
  1505. if Result <> -1 then
  1506. Self.Delete(Result);
  1507. end;
  1508. procedure TList.Pack;
  1509. begin
  1510. FList.Pack;
  1511. end;
  1512. procedure TList.Sort(const Compare: TListSortCompare);
  1513. begin
  1514. FList.Sort(Compare);
  1515. end;
  1516. { TPersistent }
  1517. procedure TPersistent.AssignError(Source: TPersistent);
  1518. var
  1519. SourceName: String;
  1520. begin
  1521. if Source<>Nil then
  1522. SourceName:=Source.ClassName
  1523. else
  1524. SourceName:='Nil';
  1525. raise EConvertError.Create('Cannot assign a '+SourceName+' to a '+ClassName+'.');
  1526. end;
  1527. procedure TPersistent.AssignTo(Dest: TPersistent);
  1528. begin
  1529. Dest.AssignError(Self);
  1530. end;
  1531. function TPersistent.GetOwner: TPersistent;
  1532. begin
  1533. Result:=nil;
  1534. end;
  1535. procedure TPersistent.Assign(Source: TPersistent);
  1536. begin
  1537. If Source<>Nil then
  1538. Source.AssignTo(Self)
  1539. else
  1540. AssignError(Nil);
  1541. end;
  1542. function TPersistent.GetNamePath: string;
  1543. var
  1544. OwnerName: String;
  1545. TheOwner: TPersistent;
  1546. begin
  1547. Result:=ClassName;
  1548. TheOwner:=GetOwner;
  1549. if TheOwner<>Nil then
  1550. begin
  1551. OwnerName:=TheOwner.GetNamePath;
  1552. if OwnerName<>'' then Result:=OwnerName+'.'+Result;
  1553. end;
  1554. end;
  1555. {
  1556. This file is part of the Free Component Library (FCL)
  1557. Copyright (c) 1999-2000 by the Free Pascal development team
  1558. See the file COPYING.FPC, included in this distribution,
  1559. for details about the copyright.
  1560. This program is distributed in the hope that it will be useful,
  1561. but WITHOUT ANY WARRANTY; without even the implied warranty of
  1562. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1563. **********************************************************************}
  1564. {****************************************************************************}
  1565. {* TStringsEnumerator *}
  1566. {****************************************************************************}
  1567. constructor TStringsEnumerator.Create(AStrings: TStrings);
  1568. begin
  1569. inherited Create;
  1570. FStrings := AStrings;
  1571. FPosition := -1;
  1572. end;
  1573. function TStringsEnumerator.GetCurrent: String;
  1574. begin
  1575. Result := FStrings[FPosition];
  1576. end;
  1577. function TStringsEnumerator.MoveNext: Boolean;
  1578. begin
  1579. Inc(FPosition);
  1580. Result := FPosition < FStrings.Count;
  1581. end;
  1582. {****************************************************************************}
  1583. {* TStrings *}
  1584. {****************************************************************************}
  1585. // Function to quote text. Should move maybe to sysutils !!
  1586. // Also, it is not clear at this point what exactly should be done.
  1587. { //!! is used to mark unsupported things. }
  1588. {
  1589. For compatibility we can't add a Constructor to TSTrings to initialize
  1590. the special characters. Therefore we add a routine which is called whenever
  1591. the special chars are needed.
  1592. }
  1593. Procedure Tstrings.CheckSpecialChars;
  1594. begin
  1595. If Not FSpecialCharsInited then
  1596. begin
  1597. FQuoteChar:='"';
  1598. FDelimiter:=',';
  1599. FNameValueSeparator:='=';
  1600. FLBS:=DefaultTextLineBreakStyle;
  1601. FSpecialCharsInited:=true;
  1602. FLineBreak:=sLineBreak;
  1603. end;
  1604. end;
  1605. Function TStrings.GetSkipLastLineBreak : Boolean;
  1606. begin
  1607. CheckSpecialChars;
  1608. Result:=FSkipLastLineBreak;
  1609. end;
  1610. procedure TStrings.SetSkipLastLineBreak(const AValue : Boolean);
  1611. begin
  1612. CheckSpecialChars;
  1613. FSkipLastLineBreak:=AValue;
  1614. end;
  1615. Function TStrings.GetLBS : TTextLineBreakStyle;
  1616. begin
  1617. CheckSpecialChars;
  1618. Result:=FLBS;
  1619. end;
  1620. Procedure TStrings.SetLBS (AValue : TTextLineBreakStyle);
  1621. begin
  1622. CheckSpecialChars;
  1623. FLBS:=AValue;
  1624. end;
  1625. procedure TStrings.SetDelimiter(c:Char);
  1626. begin
  1627. CheckSpecialChars;
  1628. FDelimiter:=c;
  1629. end;
  1630. Function TStrings.GetDelimiter : Char;
  1631. begin
  1632. CheckSpecialChars;
  1633. Result:=FDelimiter;
  1634. end;
  1635. procedure TStrings.SetLineBreak(Const S : String);
  1636. begin
  1637. CheckSpecialChars;
  1638. FLineBreak:=S;
  1639. end;
  1640. Function TStrings.GetLineBreak : String;
  1641. begin
  1642. CheckSpecialChars;
  1643. Result:=FLineBreak;
  1644. end;
  1645. procedure TStrings.SetQuoteChar(c:Char);
  1646. begin
  1647. CheckSpecialChars;
  1648. FQuoteChar:=c;
  1649. end;
  1650. Function TStrings.GetQuoteChar :Char;
  1651. begin
  1652. CheckSpecialChars;
  1653. Result:=FQuoteChar;
  1654. end;
  1655. procedure TStrings.SetNameValueSeparator(c:Char);
  1656. begin
  1657. CheckSpecialChars;
  1658. FNameValueSeparator:=c;
  1659. end;
  1660. Function TStrings.GetNameValueSeparator :Char;
  1661. begin
  1662. CheckSpecialChars;
  1663. Result:=FNameValueSeparator;
  1664. end;
  1665. function TStrings.GetCommaText: string;
  1666. Var
  1667. C1,C2 : Char;
  1668. FSD : Boolean;
  1669. begin
  1670. CheckSpecialChars;
  1671. FSD:=StrictDelimiter;
  1672. C1:=Delimiter;
  1673. C2:=QuoteChar;
  1674. Delimiter:=',';
  1675. QuoteChar:='"';
  1676. StrictDelimiter:=False;
  1677. Try
  1678. Result:=GetDelimitedText;
  1679. Finally
  1680. Delimiter:=C1;
  1681. QuoteChar:=C2;
  1682. StrictDelimiter:=FSD;
  1683. end;
  1684. end;
  1685. Function TStrings.GetDelimitedText: string;
  1686. Var
  1687. I: integer;
  1688. RE : string;
  1689. S : String;
  1690. doQuote : Boolean;
  1691. begin
  1692. CheckSpecialChars;
  1693. result:='';
  1694. RE:=QuoteChar+'|'+Delimiter;
  1695. if not StrictDelimiter then
  1696. RE:=' |'+RE;
  1697. RE:='/'+RE+'/';
  1698. // Check for break characters and quote if required.
  1699. For i:=0 to count-1 do
  1700. begin
  1701. S:=Strings[i];
  1702. doQuote:=FAlwaysQuote or (TJSString(s).search(RE)<>-1);
  1703. if DoQuote then
  1704. Result:=Result+QuoteString(S,QuoteChar)
  1705. else
  1706. Result:=Result+S;
  1707. if I<Count-1 then
  1708. Result:=Result+Delimiter;
  1709. end;
  1710. // Quote empty string:
  1711. If (Length(Result)=0) and (Count=1) then
  1712. Result:=QuoteChar+QuoteChar;
  1713. end;
  1714. procedure TStrings.GetNameValue(Index : Integer; Out AName,AValue : String);
  1715. Var L : longint;
  1716. begin
  1717. CheckSpecialChars;
  1718. AValue:=Strings[Index];
  1719. L:=Pos(FNameValueSeparator,AValue);
  1720. If L<>0 then
  1721. begin
  1722. AName:=Copy(AValue,1,L-1);
  1723. // System.Delete(AValue,1,L);
  1724. AValue:=Copy(AValue,L+1,length(AValue)-L);
  1725. end
  1726. else
  1727. AName:='';
  1728. end;
  1729. function TStrings.ExtractName(const s:String):String;
  1730. var
  1731. L: Longint;
  1732. begin
  1733. CheckSpecialChars;
  1734. L:=Pos(FNameValueSeparator,S);
  1735. If L<>0 then
  1736. Result:=Copy(S,1,L-1)
  1737. else
  1738. Result:='';
  1739. end;
  1740. function TStrings.GetName(Index: Integer): string;
  1741. Var
  1742. V : String;
  1743. begin
  1744. GetNameValue(Index,Result,V);
  1745. end;
  1746. Function TStrings.GetValue(const Name: string): string;
  1747. Var
  1748. L : longint;
  1749. N : String;
  1750. begin
  1751. Result:='';
  1752. L:=IndexOfName(Name);
  1753. If L<>-1 then
  1754. GetNameValue(L,N,Result);
  1755. end;
  1756. Function TStrings.GetValueFromIndex(Index: Integer): string;
  1757. Var
  1758. N : String;
  1759. begin
  1760. GetNameValue(Index,N,Result);
  1761. end;
  1762. Procedure TStrings.SetValueFromIndex(Index: Integer; const Value: string);
  1763. begin
  1764. If (Value='') then
  1765. Delete(Index)
  1766. else
  1767. begin
  1768. If (Index<0) then
  1769. Index:=Add('');
  1770. CheckSpecialChars;
  1771. Strings[Index]:=GetName(Index)+FNameValueSeparator+Value;
  1772. end;
  1773. end;
  1774. Procedure TStrings.SetDelimitedText(const AValue: string);
  1775. var i,j:integer;
  1776. aNotFirst:boolean;
  1777. begin
  1778. CheckSpecialChars;
  1779. BeginUpdate;
  1780. i:=1;
  1781. j:=1;
  1782. aNotFirst:=false;
  1783. { Paraphrased from Delphi XE2 help:
  1784. Strings must be separated by Delimiter characters or spaces.
  1785. They may be enclosed in QuoteChars.
  1786. QuoteChars in the string must be repeated to distinguish them from the QuoteChars enclosing the string.
  1787. }
  1788. try
  1789. Clear;
  1790. If StrictDelimiter then
  1791. begin
  1792. while i<=length(AValue) do begin
  1793. // skip delimiter
  1794. if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i);
  1795. // read next string
  1796. if i<=length(AValue) then begin
  1797. if AValue[i]=FQuoteChar then begin
  1798. // next string is quoted
  1799. j:=i+1;
  1800. while (j<=length(AValue)) and
  1801. ( (AValue[j]<>FQuoteChar) or
  1802. ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin
  1803. if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2)
  1804. else inc(j);
  1805. end;
  1806. // j is position of closing quote
  1807. Add( StringReplace (Copy(AValue,i+1,j-i-1),
  1808. FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll]));
  1809. i:=j+1;
  1810. end else begin
  1811. // next string is not quoted; read until delimiter
  1812. j:=i;
  1813. while (j<=length(AValue)) and
  1814. (AValue[j]<>FDelimiter) do inc(j);
  1815. Add( Copy(AValue,i,j-i));
  1816. i:=j;
  1817. end;
  1818. end else begin
  1819. if aNotFirst then Add('');
  1820. end;
  1821. aNotFirst:=true;
  1822. end;
  1823. end
  1824. else
  1825. begin
  1826. while i<=length(AValue) do begin
  1827. // skip delimiter
  1828. if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i);
  1829. // skip spaces
  1830. while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
  1831. // read next string
  1832. if i<=length(AValue) then begin
  1833. if AValue[i]=FQuoteChar then begin
  1834. // next string is quoted
  1835. j:=i+1;
  1836. while (j<=length(AValue)) and
  1837. ( (AValue[j]<>FQuoteChar) or
  1838. ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin
  1839. if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2)
  1840. else inc(j);
  1841. end;
  1842. // j is position of closing quote
  1843. Add( StringReplace (Copy(AValue,i+1,j-i-1),
  1844. FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll]));
  1845. i:=j+1;
  1846. end else begin
  1847. // next string is not quoted; read until control character/space/delimiter
  1848. j:=i;
  1849. while (j<=length(AValue)) and
  1850. (Ord(AValue[j])>Ord(' ')) and
  1851. (AValue[j]<>FDelimiter) do inc(j);
  1852. Add( Copy(AValue,i,j-i));
  1853. i:=j;
  1854. end;
  1855. end else begin
  1856. if aNotFirst then Add('');
  1857. end;
  1858. // skip spaces
  1859. while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
  1860. aNotFirst:=true;
  1861. end;
  1862. end;
  1863. finally
  1864. EndUpdate;
  1865. end;
  1866. end;
  1867. Procedure TStrings.SetCommaText(const Value: string);
  1868. Var
  1869. C1,C2 : Char;
  1870. begin
  1871. CheckSpecialChars;
  1872. C1:=Delimiter;
  1873. C2:=QuoteChar;
  1874. Delimiter:=',';
  1875. QuoteChar:='"';
  1876. Try
  1877. SetDelimitedText(Value);
  1878. Finally
  1879. Delimiter:=C1;
  1880. QuoteChar:=C2;
  1881. end;
  1882. end;
  1883. Procedure TStrings.SetValue(const Name, Value: string);
  1884. Var L : longint;
  1885. begin
  1886. CheckSpecialChars;
  1887. L:=IndexOfName(Name);
  1888. if L=-1 then
  1889. Add (Name+FNameValueSeparator+Value)
  1890. else
  1891. Strings[L]:=Name+FNameValueSeparator+value;
  1892. end;
  1893. Procedure TStrings.Error(const Msg: string; Data: Integer);
  1894. begin
  1895. Raise EStringListError.CreateFmt(Msg,[IntToStr(Data)]);
  1896. end;
  1897. Function TStrings.GetCapacity: Integer;
  1898. begin
  1899. Result:=Count;
  1900. end;
  1901. Function TStrings.GetObject(Index: Integer): TObject;
  1902. begin
  1903. if Index=0 then ;
  1904. Result:=Nil;
  1905. end;
  1906. Function TStrings.GetTextStr: string;
  1907. Var
  1908. I : Longint;
  1909. S,NL : String;
  1910. begin
  1911. CheckSpecialChars;
  1912. // Determine needed place
  1913. if FLineBreak<>sLineBreak then
  1914. NL:=FLineBreak
  1915. else
  1916. Case FLBS of
  1917. tlbsLF : NL:=#10;
  1918. tlbsCRLF : NL:=#13#10;
  1919. tlbsCR : NL:=#13;
  1920. end;
  1921. Result:='';
  1922. For i:=0 To count-1 do
  1923. begin
  1924. S:=Strings[I];
  1925. Result:=Result+S;
  1926. if (I<Count-1) or Not SkipLastLineBreak then
  1927. Result:=Result+NL;
  1928. end;
  1929. end;
  1930. Procedure TStrings.Put(Index: Integer; const S: string);
  1931. Var Obj : TObject;
  1932. begin
  1933. Obj:=Objects[Index];
  1934. Delete(Index);
  1935. InsertObject(Index,S,Obj);
  1936. end;
  1937. Procedure TStrings.PutObject(Index: Integer; AObject: TObject);
  1938. begin
  1939. // Empty.
  1940. if Index=0 then exit;
  1941. if AObject=nil then exit;
  1942. end;
  1943. Procedure TStrings.SetCapacity(NewCapacity: Integer);
  1944. begin
  1945. // Empty.
  1946. if NewCapacity=0 then ;
  1947. end;
  1948. Function TStrings.GetNextLineBreak (Const Value : String; Out S : String; Var P : Integer) : Boolean;
  1949. Var
  1950. PP : Integer;
  1951. begin
  1952. S:='';
  1953. Result:=False;
  1954. If ((Length(Value)-P)<0) then
  1955. exit;
  1956. PP:=TJSString(Value).IndexOf(LineBreak,P-1)+1;
  1957. if (PP<1) then
  1958. PP:=Length(Value)+1;
  1959. S:=Copy(Value,P,PP-P);
  1960. P:=PP+length(LineBreak);
  1961. Result:=True;
  1962. end;
  1963. Procedure TStrings.DoSetTextStr(const Value: string; DoClear : Boolean);
  1964. Var
  1965. S : String;
  1966. P : Integer;
  1967. begin
  1968. Try
  1969. BeginUpdate;
  1970. if DoClear then
  1971. Clear;
  1972. P:=1;
  1973. While GetNextLineBreak (Value,S,P) do
  1974. Add(S);
  1975. finally
  1976. EndUpdate;
  1977. end;
  1978. end;
  1979. Procedure TStrings.SetTextStr(const Value: string);
  1980. begin
  1981. CheckSpecialChars;
  1982. DoSetTextStr(Value,True);
  1983. end;
  1984. Procedure TStrings.AddText(const S: string);
  1985. begin
  1986. CheckSpecialChars;
  1987. DoSetTextStr(S,False);
  1988. end;
  1989. Procedure TStrings.SetUpdateState(Updating: Boolean);
  1990. begin
  1991. // FPONotifyObservers(Self,ooChange,Nil);
  1992. if Updating then ;
  1993. end;
  1994. destructor TSTrings.Destroy;
  1995. begin
  1996. inherited destroy;
  1997. end;
  1998. constructor TStrings.Create;
  1999. begin
  2000. inherited Create;
  2001. FAlwaysQuote:=False;
  2002. end;
  2003. Function TStrings.Add(const S: string): Integer;
  2004. begin
  2005. Result:=Count;
  2006. Insert (Count,S);
  2007. end;
  2008. (*
  2009. function TStrings.AddFmt(const Fmt : string; const Args : Array of const): Integer;
  2010. begin
  2011. Result:=Add(Format(Fmt,Args));
  2012. end;
  2013. *)
  2014. Function TStrings.AddObject(const S: string; AObject: TObject): Integer;
  2015. begin
  2016. Result:=Add(S);
  2017. Objects[result]:=AObject;
  2018. end;
  2019. (*
  2020. function TStrings.AddObject(const Fmt: string; Args : Array of const; AObject: TObject): Integer;
  2021. begin
  2022. Result:=AddObject(Format(Fmt,Args),AObject);
  2023. end;
  2024. *)
  2025. Procedure TStrings.Append(const S: string);
  2026. begin
  2027. Add (S);
  2028. end;
  2029. Procedure TStrings.AddStrings(TheStrings: TStrings; ClearFirst : Boolean);
  2030. begin
  2031. beginupdate;
  2032. try
  2033. if ClearFirst then
  2034. Clear;
  2035. AddStrings(TheStrings);
  2036. finally
  2037. EndUpdate;
  2038. end;
  2039. end;
  2040. Procedure TStrings.AddStrings(TheStrings: TStrings);
  2041. Var Runner : longint;
  2042. begin
  2043. For Runner:=0 to TheStrings.Count-1 do
  2044. self.AddObject (Thestrings[Runner],TheStrings.Objects[Runner]);
  2045. end;
  2046. Procedure TStrings.AddStrings(const TheStrings: array of string);
  2047. Var Runner : longint;
  2048. begin
  2049. if Count + High(TheStrings)+1 > Capacity then
  2050. Capacity := Count + High(TheStrings)+1;
  2051. For Runner:=Low(TheStrings) to High(TheStrings) do
  2052. self.Add(Thestrings[Runner]);
  2053. end;
  2054. Procedure TStrings.AddStrings(const TheStrings: array of string; ClearFirst : Boolean);
  2055. begin
  2056. beginupdate;
  2057. try
  2058. if ClearFirst then
  2059. Clear;
  2060. AddStrings(TheStrings);
  2061. finally
  2062. EndUpdate;
  2063. end;
  2064. end;
  2065. function TStrings.AddPair(const AName, AValue: string): TStrings;
  2066. begin
  2067. Result:=AddPair(AName,AValue,Nil);
  2068. end;
  2069. function TStrings.AddPair(const AName, AValue: string; AObject: TObject): TStrings;
  2070. begin
  2071. Result := Self;
  2072. AddObject(AName+NameValueSeparator+AValue, AObject);
  2073. end;
  2074. Procedure TStrings.Assign(Source: TPersistent);
  2075. Var
  2076. S : TStrings;
  2077. begin
  2078. If Source is TStrings then
  2079. begin
  2080. S:=TStrings(Source);
  2081. BeginUpdate;
  2082. Try
  2083. clear;
  2084. FSpecialCharsInited:=S.FSpecialCharsInited;
  2085. FQuoteChar:=S.FQuoteChar;
  2086. FDelimiter:=S.FDelimiter;
  2087. FNameValueSeparator:=S.FNameValueSeparator;
  2088. FLBS:=S.FLBS;
  2089. FLineBreak:=S.FLineBreak;
  2090. AddStrings(S);
  2091. finally
  2092. EndUpdate;
  2093. end;
  2094. end
  2095. else
  2096. Inherited Assign(Source);
  2097. end;
  2098. Procedure TStrings.BeginUpdate;
  2099. begin
  2100. if FUpdateCount = 0 then SetUpdateState(true);
  2101. inc(FUpdateCount);
  2102. end;
  2103. Procedure TStrings.EndUpdate;
  2104. begin
  2105. If FUpdateCount>0 then
  2106. Dec(FUpdateCount);
  2107. if FUpdateCount=0 then
  2108. SetUpdateState(False);
  2109. end;
  2110. Function TStrings.Equals(Obj: TObject): Boolean;
  2111. begin
  2112. if Obj is TStrings then
  2113. Result := Equals(TStrings(Obj))
  2114. else
  2115. Result := inherited Equals(Obj);
  2116. end;
  2117. Function TStrings.Equals(TheStrings: TStrings): Boolean;
  2118. Var Runner,Nr : Longint;
  2119. begin
  2120. Result:=False;
  2121. Nr:=Self.Count;
  2122. if Nr<>TheStrings.Count then exit;
  2123. For Runner:=0 to Nr-1 do
  2124. If Strings[Runner]<>TheStrings[Runner] then exit;
  2125. Result:=True;
  2126. end;
  2127. Procedure TStrings.Exchange(Index1, Index2: Integer);
  2128. Var
  2129. Obj : TObject;
  2130. Str : String;
  2131. begin
  2132. beginUpdate;
  2133. Try
  2134. Obj:=Objects[Index1];
  2135. Str:=Strings[Index1];
  2136. Objects[Index1]:=Objects[Index2];
  2137. Strings[Index1]:=Strings[Index2];
  2138. Objects[Index2]:=Obj;
  2139. Strings[Index2]:=Str;
  2140. finally
  2141. EndUpdate;
  2142. end;
  2143. end;
  2144. function TStrings.GetEnumerator: TStringsEnumerator;
  2145. begin
  2146. Result:=TStringsEnumerator.Create(Self);
  2147. end;
  2148. Function TStrings.DoCompareText(const s1,s2 : string) : PtrInt;
  2149. begin
  2150. result:=CompareText(s1,s2);
  2151. end;
  2152. Function TStrings.IndexOf(const S: string): Integer;
  2153. begin
  2154. Result:=0;
  2155. While (Result<Count) and (DoCompareText(Strings[Result],S)<>0) do Result:=Result+1;
  2156. if Result=Count then Result:=-1;
  2157. end;
  2158. Function TStrings.IndexOfName(const Name: string): Integer;
  2159. Var
  2160. len : longint;
  2161. S : String;
  2162. begin
  2163. CheckSpecialChars;
  2164. Result:=0;
  2165. while (Result<Count) do
  2166. begin
  2167. S:=Strings[Result];
  2168. len:=pos(FNameValueSeparator,S)-1;
  2169. if (len>=0) and (DoCompareText(Name,Copy(S,1,Len))=0) then
  2170. exit;
  2171. inc(result);
  2172. end;
  2173. result:=-1;
  2174. end;
  2175. Function TStrings.IndexOfObject(AObject: TObject): Integer;
  2176. begin
  2177. Result:=0;
  2178. While (Result<count) and (Objects[Result]<>AObject) do Result:=Result+1;
  2179. If Result=Count then Result:=-1;
  2180. end;
  2181. Procedure TStrings.InsertObject(Index: Integer; const S: string;
  2182. AObject: TObject);
  2183. begin
  2184. Insert (Index,S);
  2185. Objects[Index]:=AObject;
  2186. end;
  2187. Procedure TStrings.Move(CurIndex, NewIndex: Integer);
  2188. Var
  2189. Obj : TObject;
  2190. Str : String;
  2191. begin
  2192. BeginUpdate;
  2193. Try
  2194. Obj:=Objects[CurIndex];
  2195. Str:=Strings[CurIndex];
  2196. Objects[CurIndex]:=Nil; // Prevent Delete from freeing.
  2197. Delete(Curindex);
  2198. InsertObject(NewIndex,Str,Obj);
  2199. finally
  2200. EndUpdate;
  2201. end;
  2202. end;
  2203. {****************************************************************************}
  2204. {* TStringList *}
  2205. {****************************************************************************}
  2206. procedure TStringList.ExchangeItemsInt(Index1, Index2: Integer);
  2207. Var
  2208. S : String;
  2209. O : TObject;
  2210. begin
  2211. S:=Flist[Index1].FString;
  2212. O:=Flist[Index1].FObject;
  2213. Flist[Index1].Fstring:=Flist[Index2].Fstring;
  2214. Flist[Index1].FObject:=Flist[Index2].FObject;
  2215. Flist[Index2].Fstring:=S;
  2216. Flist[Index2].FObject:=O;
  2217. end;
  2218. function TStringList.GetSorted: Boolean;
  2219. begin
  2220. Result:=FSortStyle in [sslUser,sslAuto];
  2221. end;
  2222. procedure TStringList.ExchangeItems(Index1, Index2: Integer);
  2223. begin
  2224. ExchangeItemsInt(Index1, Index2);
  2225. end;
  2226. procedure TStringList.Grow;
  2227. Var
  2228. NC : Integer;
  2229. begin
  2230. NC:=Capacity;
  2231. If NC>=256 then
  2232. NC:=NC+(NC Div 4)
  2233. else if NC=0 then
  2234. NC:=4
  2235. else
  2236. NC:=NC*4;
  2237. SetCapacity(NC);
  2238. end;
  2239. procedure TStringList.InternalClear(FromIndex: Integer; ClearOnly: Boolean);
  2240. Var
  2241. I: Integer;
  2242. begin
  2243. if FromIndex < FCount then
  2244. begin
  2245. if FOwnsObjects then
  2246. begin
  2247. For I:=FromIndex to FCount-1 do
  2248. begin
  2249. Flist[I].FString:='';
  2250. freeandnil(Flist[i].FObject);
  2251. end;
  2252. end
  2253. else
  2254. begin
  2255. For I:=FromIndex to FCount-1 do
  2256. Flist[I].FString:='';
  2257. end;
  2258. FCount:=FromIndex;
  2259. end;
  2260. if Not ClearOnly then
  2261. SetCapacity(0);
  2262. end;
  2263. procedure TStringList.QuickSort(L, R: Integer; CompareFn: TStringListSortCompare
  2264. );
  2265. var
  2266. Pivot, vL, vR: Integer;
  2267. begin
  2268. //if ExchangeItems is override call that, else call (faster) ExchangeItemsInt
  2269. if R - L <= 1 then begin // a little bit of time saver
  2270. if L < R then
  2271. if CompareFn(Self, L, R) > 0 then
  2272. ExchangeItems(L, R);
  2273. Exit;
  2274. end;
  2275. vL := L;
  2276. vR := R;
  2277. Pivot := L + Random(R - L); // they say random is best
  2278. while vL < vR do begin
  2279. while (vL < Pivot) and (CompareFn(Self, vL, Pivot) <= 0) do
  2280. Inc(vL);
  2281. while (vR > Pivot) and (CompareFn(Self, vR, Pivot) > 0) do
  2282. Dec(vR);
  2283. ExchangeItems(vL, vR);
  2284. if Pivot = vL then // swap pivot if we just hit it from one side
  2285. Pivot := vR
  2286. else if Pivot = vR then
  2287. Pivot := vL;
  2288. end;
  2289. if Pivot - 1 >= L then
  2290. QuickSort(L, Pivot - 1, CompareFn);
  2291. if Pivot + 1 <= R then
  2292. QuickSort(Pivot + 1, R, CompareFn);
  2293. end;
  2294. procedure TStringList.InsertItem(Index: Integer; const S: string);
  2295. begin
  2296. InsertItem(Index, S, nil);
  2297. end;
  2298. procedure TStringList.InsertItem(Index: Integer; const S: string; O: TObject);
  2299. Var
  2300. It : TStringItem;
  2301. begin
  2302. Changing;
  2303. If FCount=Capacity then Grow;
  2304. it.FString:=S;
  2305. it.FObject:=O;
  2306. TJSArray(FList).Splice(Index,0,It);
  2307. Inc(FCount);
  2308. Changed;
  2309. end;
  2310. procedure TStringList.SetSorted(Value: Boolean);
  2311. begin
  2312. If Value then
  2313. SortStyle:=sslAuto
  2314. else
  2315. SortStyle:=sslNone
  2316. end;
  2317. procedure TStringList.Changed;
  2318. begin
  2319. If (FUpdateCount=0) Then
  2320. begin
  2321. If Assigned(FOnChange) then
  2322. FOnchange(Self);
  2323. end;
  2324. end;
  2325. procedure TStringList.Changing;
  2326. begin
  2327. If FUpdateCount=0 then
  2328. if Assigned(FOnChanging) then
  2329. FOnchanging(Self);
  2330. end;
  2331. function TStringList.Get(Index: Integer): string;
  2332. begin
  2333. CheckIndex(Index);
  2334. Result:=Flist[Index].FString;
  2335. end;
  2336. function TStringList.GetCapacity: Integer;
  2337. begin
  2338. Result:=Length(FList);
  2339. end;
  2340. function TStringList.GetCount: Integer;
  2341. begin
  2342. Result:=FCount;
  2343. end;
  2344. function TStringList.GetObject(Index: Integer): TObject;
  2345. begin
  2346. CheckIndex(Index);
  2347. Result:=Flist[Index].FObject;
  2348. end;
  2349. procedure TStringList.Put(Index: Integer; const S: string);
  2350. begin
  2351. If Sorted then
  2352. Error(SSortedListError,0);
  2353. CheckIndex(Index);
  2354. Changing;
  2355. Flist[Index].FString:=S;
  2356. Changed;
  2357. end;
  2358. procedure TStringList.PutObject(Index: Integer; AObject: TObject);
  2359. begin
  2360. CheckIndex(Index);
  2361. Changing;
  2362. Flist[Index].FObject:=AObject;
  2363. Changed;
  2364. end;
  2365. procedure TStringList.SetCapacity(NewCapacity: Integer);
  2366. begin
  2367. If (NewCapacity<0) then
  2368. Error (SListCapacityError,NewCapacity);
  2369. If NewCapacity<>Capacity then
  2370. SetLength(FList,NewCapacity)
  2371. end;
  2372. procedure TStringList.SetUpdateState(Updating: Boolean);
  2373. begin
  2374. If Updating then
  2375. Changing
  2376. else
  2377. Changed
  2378. end;
  2379. destructor TStringList.Destroy;
  2380. begin
  2381. InternalClear;
  2382. Inherited destroy;
  2383. end;
  2384. function TStringList.Add(const S: string): Integer;
  2385. begin
  2386. If Not (SortStyle=sslAuto) then
  2387. Result:=FCount
  2388. else
  2389. If Find (S,Result) then
  2390. Case DUplicates of
  2391. DupIgnore : Exit;
  2392. DupError : Error(SDuplicateString,0)
  2393. end;
  2394. InsertItem (Result,S);
  2395. end;
  2396. procedure TStringList.Clear;
  2397. begin
  2398. if FCount = 0 then Exit;
  2399. Changing;
  2400. InternalClear;
  2401. Changed;
  2402. end;
  2403. procedure TStringList.Delete(Index: Integer);
  2404. begin
  2405. CheckIndex(Index);
  2406. Changing;
  2407. if FOwnsObjects then
  2408. FreeAndNil(Flist[Index].FObject);
  2409. TJSArray(FList).splice(Index,1);
  2410. FList[Count-1].FString:='';
  2411. Flist[Count-1].FObject:=Nil;
  2412. Dec(FCount);
  2413. Changed;
  2414. end;
  2415. procedure TStringList.Exchange(Index1, Index2: Integer);
  2416. begin
  2417. CheckIndex(Index1);
  2418. CheckIndex(Index2);
  2419. Changing;
  2420. ExchangeItemsInt(Index1,Index2);
  2421. changed;
  2422. end;
  2423. procedure TStringList.SetCaseSensitive(b : boolean);
  2424. begin
  2425. if b=FCaseSensitive then
  2426. Exit;
  2427. FCaseSensitive:=b;
  2428. if FSortStyle=sslAuto then
  2429. begin
  2430. FForceSort:=True;
  2431. try
  2432. Sort;
  2433. finally
  2434. FForceSort:=False;
  2435. end;
  2436. end;
  2437. end;
  2438. procedure TStringList.SetSortStyle(AValue: TStringsSortStyle);
  2439. begin
  2440. if FSortStyle=AValue then Exit;
  2441. if (AValue=sslAuto) then
  2442. Sort;
  2443. FSortStyle:=AValue;
  2444. end;
  2445. procedure TStringList.CheckIndex(AIndex: Integer);
  2446. begin
  2447. If (AIndex<0) or (AIndex>=FCount) then
  2448. Error(SListIndexError,AIndex);
  2449. end;
  2450. function TStringList.DoCompareText(const s1, s2: string): PtrInt;
  2451. begin
  2452. if FCaseSensitive then
  2453. result:=CompareStr(s1,s2)
  2454. else
  2455. result:=CompareText(s1,s2);
  2456. end;
  2457. function TStringList.CompareStrings(const s1,s2 : string) : Integer;
  2458. begin
  2459. Result := DoCompareText(s1, s2);
  2460. end;
  2461. function TStringList.Find(const S: string; out Index: Integer): Boolean;
  2462. var
  2463. L, R, I: Integer;
  2464. CompareRes: PtrInt;
  2465. begin
  2466. Result := false;
  2467. Index:=-1;
  2468. if Not Sorted then
  2469. Raise EListError.Create(SErrFindNeedsSortedList);
  2470. // Use binary search.
  2471. L := 0;
  2472. R := Count - 1;
  2473. while (L<=R) do
  2474. begin
  2475. I := L + (R - L) div 2;
  2476. CompareRes := DoCompareText(S, Flist[I].FString);
  2477. if (CompareRes>0) then
  2478. L := I+1
  2479. else begin
  2480. R := I-1;
  2481. if (CompareRes=0) then begin
  2482. Result := true;
  2483. if (Duplicates<>dupAccept) then
  2484. L := I; // forces end of while loop
  2485. end;
  2486. end;
  2487. end;
  2488. Index := L;
  2489. end;
  2490. function TStringList.IndexOf(const S: string): Integer;
  2491. begin
  2492. If Not Sorted then
  2493. Result:=Inherited indexOf(S)
  2494. else
  2495. // faster using binary search...
  2496. If Not Find (S,Result) then
  2497. Result:=-1;
  2498. end;
  2499. procedure TStringList.Insert(Index: Integer; const S: string);
  2500. begin
  2501. If SortStyle=sslAuto then
  2502. Error (SSortedListError,0)
  2503. else
  2504. begin
  2505. If (Index<0) or (Index>FCount) then
  2506. Error(SListIndexError,Index); // Cannot use CheckIndex, because there >= FCount...
  2507. InsertItem (Index,S);
  2508. end;
  2509. end;
  2510. procedure TStringList.CustomSort(CompareFn: TStringListSortCompare);
  2511. begin
  2512. If (FForceSort or (Not (FSortStyle=sslAuto))) and (FCount>1) then
  2513. begin
  2514. Changing;
  2515. QuickSort(0,FCount-1, CompareFn);
  2516. Changed;
  2517. end;
  2518. end;
  2519. function StringListAnsiCompare(List: TStringList; Index1, Index: Integer): Integer;
  2520. begin
  2521. Result := List.DoCompareText(List.FList[Index1].FString,
  2522. List.FList[Index].FString);
  2523. end;
  2524. procedure TStringList.Sort;
  2525. begin
  2526. CustomSort(@StringListAnsiCompare);
  2527. end;
  2528. {****************************************************************************}
  2529. {* TCollectionItem *}
  2530. {****************************************************************************}
  2531. function TCollectionItem.GetIndex: Integer;
  2532. begin
  2533. if FCollection<>nil then
  2534. Result:=FCollection.FItems.IndexOf(Self)
  2535. else
  2536. Result:=-1;
  2537. end;
  2538. procedure TCollectionItem.SetCollection(Value: TCollection);
  2539. begin
  2540. IF Value<>FCollection then
  2541. begin
  2542. If FCollection<>Nil then FCollection.RemoveItem(Self);
  2543. if Value<>Nil then Value.InsertItem(Self);
  2544. end;
  2545. end;
  2546. procedure TCollectionItem.Changed(AllItems: Boolean);
  2547. begin
  2548. If (FCollection<>Nil) and (FCollection.UpdateCount=0) then
  2549. begin
  2550. If AllItems then
  2551. FCollection.Update(Nil)
  2552. else
  2553. FCollection.Update(Self);
  2554. end;
  2555. end;
  2556. function TCollectionItem.GetNamePath: string;
  2557. begin
  2558. If FCollection<>Nil then
  2559. Result:=FCollection.GetNamePath+'['+IntToStr(Index)+']'
  2560. else
  2561. Result:=ClassName;
  2562. end;
  2563. function TCollectionItem.GetOwner: TPersistent;
  2564. begin
  2565. Result:=FCollection;
  2566. end;
  2567. function TCollectionItem.GetDisplayName: string;
  2568. begin
  2569. Result:=ClassName;
  2570. end;
  2571. procedure TCollectionItem.SetIndex(Value: Integer);
  2572. Var Temp : Longint;
  2573. begin
  2574. Temp:=GetIndex;
  2575. If (Temp>-1) and (Temp<>Value) then
  2576. begin
  2577. FCollection.FItems.Move(Temp,Value);
  2578. Changed(True);
  2579. end;
  2580. end;
  2581. procedure TCollectionItem.SetDisplayName(const Value: string);
  2582. begin
  2583. Changed(False);
  2584. if Value='' then ;
  2585. end;
  2586. constructor TCollectionItem.Create(ACollection: TCollection);
  2587. begin
  2588. Inherited Create;
  2589. SetCollection(ACollection);
  2590. end;
  2591. destructor TCollectionItem.Destroy;
  2592. begin
  2593. SetCollection(Nil);
  2594. Inherited Destroy;
  2595. end;
  2596. {****************************************************************************}
  2597. {* TCollectionEnumerator *}
  2598. {****************************************************************************}
  2599. constructor TCollectionEnumerator.Create(ACollection: TCollection);
  2600. begin
  2601. inherited Create;
  2602. FCollection := ACollection;
  2603. FPosition := -1;
  2604. end;
  2605. function TCollectionEnumerator.GetCurrent: TCollectionItem;
  2606. begin
  2607. Result := FCollection.Items[FPosition];
  2608. end;
  2609. function TCollectionEnumerator.MoveNext: Boolean;
  2610. begin
  2611. Inc(FPosition);
  2612. Result := FPosition < FCollection.Count;
  2613. end;
  2614. {****************************************************************************}
  2615. {* TCollection *}
  2616. {****************************************************************************}
  2617. function TCollection.Owner: TPersistent;
  2618. begin
  2619. result:=getowner;
  2620. end;
  2621. function TCollection.GetCount: Integer;
  2622. begin
  2623. Result:=FItems.Count;
  2624. end;
  2625. Procedure TCollection.SetPropName;
  2626. {
  2627. Var
  2628. TheOwner : TPersistent;
  2629. PropList : PPropList;
  2630. I, PropCount : Integer;
  2631. }
  2632. begin
  2633. FPropName:='';
  2634. {
  2635. TheOwner:=GetOwner;
  2636. // TODO: This needs to wait till Mattias finishes typeinfo.
  2637. // It's normally only used in the designer so should not be a problem currently.
  2638. if (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) Then Exit;
  2639. // get information from the owner RTTI
  2640. PropCount:=GetPropList(TheOwner, PropList);
  2641. Try
  2642. For I:=0 To PropCount-1 Do
  2643. If (PropList^[i]^.PropType^.Kind=tkClass) And
  2644. (GetObjectProp(TheOwner, PropList^[i], ClassType)=Self) Then
  2645. Begin
  2646. FPropName:=PropList^[i]^.Name;
  2647. Exit;
  2648. End;
  2649. Finally
  2650. FreeMem(PropList);
  2651. End;
  2652. }
  2653. end;
  2654. function TCollection.GetPropName: string;
  2655. {Var
  2656. TheOwner : TPersistent;}
  2657. begin
  2658. Result:=FPropNAme;
  2659. // TheOwner:=GetOwner;
  2660. // If (Result<>'') or (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) then exit;
  2661. SetPropName;
  2662. Result:=FPropName;
  2663. end;
  2664. procedure TCollection.InsertItem(Item: TCollectionItem);
  2665. begin
  2666. If Not(Item Is FitemClass) then
  2667. exit;
  2668. FItems.add(Item);
  2669. Item.FCollection:=Self;
  2670. Item.FID:=FNextID;
  2671. inc(FNextID);
  2672. SetItemName(Item);
  2673. Notify(Item,cnAdded);
  2674. Changed;
  2675. end;
  2676. procedure TCollection.RemoveItem(Item: TCollectionItem);
  2677. Var
  2678. I : Integer;
  2679. begin
  2680. Notify(Item,cnExtracting);
  2681. I:=FItems.IndexOfItem(Item,fromEnd);
  2682. If (I<>-1) then
  2683. FItems.Delete(I);
  2684. Item.FCollection:=Nil;
  2685. Changed;
  2686. end;
  2687. function TCollection.GetAttrCount: Integer;
  2688. begin
  2689. Result:=0;
  2690. end;
  2691. function TCollection.GetAttr(Index: Integer): string;
  2692. begin
  2693. Result:='';
  2694. if Index=0 then ;
  2695. end;
  2696. function TCollection.GetItemAttr(Index, ItemIndex: Integer): string;
  2697. begin
  2698. Result:=TCollectionItem(FItems.Items[ItemIndex]).DisplayName;
  2699. if Index=0 then ;
  2700. end;
  2701. function TCollection.GetEnumerator: TCollectionEnumerator;
  2702. begin
  2703. Result := TCollectionEnumerator.Create(Self);
  2704. end;
  2705. function TCollection.GetNamePath: string;
  2706. var o : TPersistent;
  2707. begin
  2708. o:=getowner;
  2709. if assigned(o) and (propname<>'') then
  2710. result:=o.getnamepath+'.'+propname
  2711. else
  2712. result:=classname;
  2713. end;
  2714. procedure TCollection.Changed;
  2715. begin
  2716. if FUpdateCount=0 then
  2717. Update(Nil);
  2718. end;
  2719. function TCollection.GetItem(Index: Integer): TCollectionItem;
  2720. begin
  2721. Result:=TCollectionItem(FItems.Items[Index]);
  2722. end;
  2723. procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem);
  2724. begin
  2725. TCollectionItem(FItems.items[Index]).Assign(Value);
  2726. end;
  2727. procedure TCollection.SetItemName(Item: TCollectionItem);
  2728. begin
  2729. if Item=nil then ;
  2730. end;
  2731. procedure TCollection.Update(Item: TCollectionItem);
  2732. begin
  2733. if Item=nil then ;
  2734. end;
  2735. constructor TCollection.Create(AItemClass: TCollectionItemClass);
  2736. begin
  2737. inherited create;
  2738. FItemClass:=AItemClass;
  2739. FItems:=TFpList.Create;
  2740. end;
  2741. destructor TCollection.Destroy;
  2742. begin
  2743. FUpdateCount:=1; // Prevent OnChange
  2744. try
  2745. DoClear;
  2746. Finally
  2747. FUpdateCount:=0;
  2748. end;
  2749. if assigned(FItems) then
  2750. FItems.Destroy;
  2751. Inherited Destroy;
  2752. end;
  2753. function TCollection.Add: TCollectionItem;
  2754. begin
  2755. Result:=FItemClass.Create(Self);
  2756. end;
  2757. procedure TCollection.Assign(Source: TPersistent);
  2758. Var I : Longint;
  2759. begin
  2760. If Source is TCollection then
  2761. begin
  2762. Clear;
  2763. For I:=0 To TCollection(Source).Count-1 do
  2764. Add.Assign(TCollection(Source).Items[I]);
  2765. exit;
  2766. end
  2767. else
  2768. Inherited Assign(Source);
  2769. end;
  2770. procedure TCollection.BeginUpdate;
  2771. begin
  2772. inc(FUpdateCount);
  2773. end;
  2774. procedure TCollection.Clear;
  2775. begin
  2776. if FItems.Count=0 then
  2777. exit; // Prevent Changed
  2778. BeginUpdate;
  2779. try
  2780. DoClear;
  2781. finally
  2782. EndUpdate;
  2783. end;
  2784. end;
  2785. procedure TCollection.DoClear;
  2786. var
  2787. Item: TCollectionItem;
  2788. begin
  2789. While FItems.Count>0 do
  2790. begin
  2791. Item:=TCollectionItem(FItems.Last);
  2792. if Assigned(Item) then
  2793. Item.Destroy;
  2794. end;
  2795. end;
  2796. procedure TCollection.EndUpdate;
  2797. begin
  2798. if FUpdateCount>0 then
  2799. dec(FUpdateCount);
  2800. if FUpdateCount=0 then
  2801. Changed;
  2802. end;
  2803. function TCollection.FindItemID(ID: Integer): TCollectionItem;
  2804. Var
  2805. I : Longint;
  2806. begin
  2807. For I:=0 to Fitems.Count-1 do
  2808. begin
  2809. Result:=TCollectionItem(FItems.items[I]);
  2810. If Result.Id=Id then
  2811. exit;
  2812. end;
  2813. Result:=Nil;
  2814. end;
  2815. procedure TCollection.Delete(Index: Integer);
  2816. Var
  2817. Item : TCollectionItem;
  2818. begin
  2819. Item:=TCollectionItem(FItems[Index]);
  2820. Notify(Item,cnDeleting);
  2821. If assigned(Item) then
  2822. Item.Destroy;
  2823. end;
  2824. function TCollection.Insert(Index: Integer): TCollectionItem;
  2825. begin
  2826. Result:=Add;
  2827. Result.Index:=Index;
  2828. end;
  2829. procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification);
  2830. begin
  2831. if Item=nil then ;
  2832. if Action=cnAdded then ;
  2833. end;
  2834. procedure TCollection.Sort(Const Compare : TCollectionSortCompare);
  2835. begin
  2836. BeginUpdate;
  2837. try
  2838. FItems.Sort(TListSortCompare(Compare));
  2839. Finally
  2840. EndUpdate;
  2841. end;
  2842. end;
  2843. procedure TCollection.Exchange(Const Index1, index2: integer);
  2844. begin
  2845. FItems.Exchange(Index1,Index2);
  2846. end;
  2847. {****************************************************************************}
  2848. {* TOwnedCollection *}
  2849. {****************************************************************************}
  2850. Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass);
  2851. Begin
  2852. FOwner := AOwner;
  2853. inherited Create(AItemClass);
  2854. end;
  2855. Function TOwnedCollection.GetOwner: TPersistent;
  2856. begin
  2857. Result:=FOwner;
  2858. end;
  2859. {****************************************************************************}
  2860. {* TComponent *}
  2861. {****************************************************************************}
  2862. Function TComponent.GetComponent(AIndex: Integer): TComponent;
  2863. begin
  2864. If not assigned(FComponents) then
  2865. Result:=Nil
  2866. else
  2867. Result:=TComponent(FComponents.Items[Aindex]);
  2868. end;
  2869. Function TComponent.GetComponentCount: Integer;
  2870. begin
  2871. If not assigned(FComponents) then
  2872. result:=0
  2873. else
  2874. Result:=FComponents.Count;
  2875. end;
  2876. Function TComponent.GetComponentIndex: Integer;
  2877. begin
  2878. If Assigned(FOwner) and Assigned(FOwner.FComponents) then
  2879. Result:=FOWner.FComponents.IndexOf(Self)
  2880. else
  2881. Result:=-1;
  2882. end;
  2883. Procedure TComponent.Insert(AComponent: TComponent);
  2884. begin
  2885. If not assigned(FComponents) then
  2886. FComponents:=TFpList.Create;
  2887. FComponents.Add(AComponent);
  2888. AComponent.FOwner:=Self;
  2889. end;
  2890. Procedure TComponent.Remove(AComponent: TComponent);
  2891. begin
  2892. AComponent.FOwner:=Nil;
  2893. If assigned(FCOmponents) then
  2894. begin
  2895. FComponents.Remove(AComponent);
  2896. IF FComponents.Count=0 then
  2897. begin
  2898. FComponents.Destroy;
  2899. FComponents:=Nil;
  2900. end;
  2901. end;
  2902. end;
  2903. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  2904. begin
  2905. if FFreeNotifies<>nil then
  2906. begin
  2907. FFreeNotifies.Remove(AComponent);
  2908. if FFreeNotifies.Count=0 then
  2909. begin
  2910. FFreeNotifies.Destroy;
  2911. FFreeNotifies:=nil;
  2912. Exclude(FComponentState,csFreeNotification);
  2913. end;
  2914. end;
  2915. end;
  2916. Procedure TComponent.SetComponentIndex(Value: Integer);
  2917. Var Temp,Count : longint;
  2918. begin
  2919. If Not assigned(Fowner) then exit;
  2920. Temp:=getcomponentindex;
  2921. If temp<0 then exit;
  2922. If value<0 then value:=0;
  2923. Count:=Fowner.FComponents.Count;
  2924. If Value>=Count then value:=count-1;
  2925. If Value<>Temp then
  2926. begin
  2927. FOWner.FComponents.Delete(Temp);
  2928. FOwner.FComponents.Insert(Value,Self);
  2929. end;
  2930. end;
  2931. Procedure TComponent.ChangeName(const NewName: TComponentName);
  2932. begin
  2933. FName:=NewName;
  2934. end;
  2935. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  2936. begin
  2937. // Does nothing.
  2938. if Proc=nil then ;
  2939. if Root=nil then ;
  2940. end;
  2941. Function TComponent.GetChildOwner: TComponent;
  2942. begin
  2943. Result:=Nil;
  2944. end;
  2945. Function TComponent.GetChildParent: TComponent;
  2946. begin
  2947. Result:=Self;
  2948. end;
  2949. Function TComponent.GetNamePath: string;
  2950. begin
  2951. Result:=FName;
  2952. end;
  2953. Function TComponent.GetOwner: TPersistent;
  2954. begin
  2955. Result:=FOwner;
  2956. end;
  2957. Procedure TComponent.Loaded;
  2958. begin
  2959. Exclude(FComponentState,csLoading);
  2960. end;
  2961. Procedure TComponent.Loading;
  2962. begin
  2963. Include(FComponentState,csLoading);
  2964. end;
  2965. procedure TComponent.SetWriting(Value: Boolean);
  2966. begin
  2967. If Value then
  2968. Include(FComponentState,csWriting)
  2969. else
  2970. Exclude(FComponentState,csWriting);
  2971. end;
  2972. procedure TComponent.SetReading(Value: Boolean);
  2973. begin
  2974. If Value then
  2975. Include(FComponentState,csReading)
  2976. else
  2977. Exclude(FComponentState,csReading);
  2978. end;
  2979. Procedure TComponent.Notification(AComponent: TComponent;
  2980. Operation: TOperation);
  2981. Var
  2982. C : Longint;
  2983. begin
  2984. If (Operation=opRemove) then
  2985. RemoveFreeNotification(AComponent);
  2986. If Not assigned(FComponents) then
  2987. exit;
  2988. C:=FComponents.Count-1;
  2989. While (C>=0) do
  2990. begin
  2991. TComponent(FComponents.Items[C]).Notification(AComponent,Operation);
  2992. Dec(C);
  2993. if C>=FComponents.Count then
  2994. C:=FComponents.Count-1;
  2995. end;
  2996. end;
  2997. procedure TComponent.PaletteCreated;
  2998. begin
  2999. end;
  3000. Procedure TComponent.SetAncestor(Value: Boolean);
  3001. Var Runner : Longint;
  3002. begin
  3003. If Value then
  3004. Include(FComponentState,csAncestor)
  3005. else
  3006. Exclude(FCOmponentState,csAncestor);
  3007. if Assigned(FComponents) then
  3008. For Runner:=0 To FComponents.Count-1 do
  3009. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  3010. end;
  3011. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  3012. Var Runner : Longint;
  3013. begin
  3014. If Value then
  3015. Include(FComponentState,csDesigning)
  3016. else
  3017. Exclude(FComponentState,csDesigning);
  3018. if Assigned(FComponents) and SetChildren then
  3019. For Runner:=0 To FComponents.Count - 1 do
  3020. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  3021. end;
  3022. Procedure TComponent.SetDesignInstance(Value: Boolean);
  3023. begin
  3024. If Value then
  3025. Include(FComponentState,csDesignInstance)
  3026. else
  3027. Exclude(FComponentState,csDesignInstance);
  3028. end;
  3029. Procedure TComponent.SetInline(Value: Boolean);
  3030. begin
  3031. If Value then
  3032. Include(FComponentState,csInline)
  3033. else
  3034. Exclude(FComponentState,csInline);
  3035. end;
  3036. Procedure TComponent.SetName(const NewName: TComponentName);
  3037. begin
  3038. If FName=NewName then exit;
  3039. If (NewName<>'') and not IsValidIdent(NewName) then
  3040. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  3041. If Assigned(FOwner) Then
  3042. FOwner.ValidateRename(Self,FName,NewName)
  3043. else
  3044. ValidateRename(Nil,FName,NewName);
  3045. ChangeName(NewName);
  3046. end;
  3047. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  3048. begin
  3049. // does nothing
  3050. if Child=nil then ;
  3051. if Order=0 then ;
  3052. end;
  3053. Procedure TComponent.SetParentComponent(Value: TComponent);
  3054. begin
  3055. // Does nothing
  3056. if Value=nil then ;
  3057. end;
  3058. Procedure TComponent.Updating;
  3059. begin
  3060. Include (FComponentState,csUpdating);
  3061. end;
  3062. Procedure TComponent.Updated;
  3063. begin
  3064. Exclude(FComponentState,csUpdating);
  3065. end;
  3066. Procedure TComponent.ValidateRename(AComponent: TComponent;
  3067. const CurName, NewName: string);
  3068. begin
  3069. //!! This contradicts the Delphi manual.
  3070. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  3071. (FindComponent(NewName)<>Nil) then
  3072. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  3073. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  3074. FOwner.ValidateRename(AComponent,Curname,Newname);
  3075. end;
  3076. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  3077. begin
  3078. AComponent.ValidateInsert(Self);
  3079. end;
  3080. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  3081. begin
  3082. // Does nothing.
  3083. if AComponent=nil then ;
  3084. end;
  3085. function TComponent._AddRef: Integer;
  3086. begin
  3087. Result:=-1;
  3088. end;
  3089. function TComponent._Release: Integer;
  3090. begin
  3091. Result:=-1;
  3092. end;
  3093. Constructor TComponent.Create(AOwner: TComponent);
  3094. begin
  3095. FComponentStyle:=[csInheritable];
  3096. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  3097. end;
  3098. Destructor TComponent.Destroy;
  3099. Var
  3100. I : Integer;
  3101. C : TComponent;
  3102. begin
  3103. Destroying;
  3104. If Assigned(FFreeNotifies) then
  3105. begin
  3106. I:=FFreeNotifies.Count-1;
  3107. While (I>=0) do
  3108. begin
  3109. C:=TComponent(FFreeNotifies.Items[I]);
  3110. // Delete, so one component is not notified twice, if it is owned.
  3111. FFreeNotifies.Delete(I);
  3112. C.Notification (self,opRemove);
  3113. If (FFreeNotifies=Nil) then
  3114. I:=0
  3115. else if (I>FFreeNotifies.Count) then
  3116. I:=FFreeNotifies.Count;
  3117. dec(i);
  3118. end;
  3119. FreeAndNil(FFreeNotifies);
  3120. end;
  3121. DestroyComponents;
  3122. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  3123. inherited destroy;
  3124. end;
  3125. Procedure TComponent.BeforeDestruction;
  3126. begin
  3127. if not(csDestroying in FComponentstate) then
  3128. Destroying;
  3129. end;
  3130. Procedure TComponent.DestroyComponents;
  3131. Var acomponent: TComponent;
  3132. begin
  3133. While assigned(FComponents) do
  3134. begin
  3135. aComponent:=TComponent(FComponents.Last);
  3136. Remove(aComponent);
  3137. Acomponent.Destroy;
  3138. end;
  3139. end;
  3140. Procedure TComponent.Destroying;
  3141. Var Runner : longint;
  3142. begin
  3143. If csDestroying in FComponentstate Then Exit;
  3144. include (FComponentState,csDestroying);
  3145. If Assigned(FComponents) then
  3146. for Runner:=0 to FComponents.Count-1 do
  3147. TComponent(FComponents.Items[Runner]).Destroying;
  3148. end;
  3149. function TComponent.QueryInterface(const IID: TGUID; out Obj): integer;
  3150. begin
  3151. if GetInterface(IID, Obj) then
  3152. Result := S_OK
  3153. else
  3154. Result := E_NOINTERFACE;
  3155. end;
  3156. Function TComponent.FindComponent(const AName: string): TComponent;
  3157. Var I : longint;
  3158. begin
  3159. Result:=Nil;
  3160. If (AName='') or Not assigned(FComponents) then exit;
  3161. For i:=0 to FComponents.Count-1 do
  3162. if (CompareText(TComponent(FComponents[I]).Name,AName)=0) then
  3163. begin
  3164. Result:=TComponent(FComponents.Items[I]);
  3165. exit;
  3166. end;
  3167. end;
  3168. Procedure TComponent.FreeNotification(AComponent: TComponent);
  3169. begin
  3170. If (Owner<>Nil) and (AComponent=Owner) then exit;
  3171. If not (Assigned(FFreeNotifies)) then
  3172. FFreeNotifies:=TFpList.Create;
  3173. If FFreeNotifies.IndexOf(AComponent)=-1 then
  3174. begin
  3175. FFreeNotifies.Add(AComponent);
  3176. AComponent.FreeNotification (self);
  3177. end;
  3178. end;
  3179. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  3180. begin
  3181. RemoveNotification(AComponent);
  3182. AComponent.RemoveNotification (self);
  3183. end;
  3184. Function TComponent.GetParentComponent: TComponent;
  3185. begin
  3186. Result:=Nil;
  3187. end;
  3188. Function TComponent.HasParent: Boolean;
  3189. begin
  3190. Result:=False;
  3191. end;
  3192. Procedure TComponent.InsertComponent(AComponent: TComponent);
  3193. begin
  3194. AComponent.ValidateContainer(Self);
  3195. ValidateRename(AComponent,'',AComponent.FName);
  3196. Insert(AComponent);
  3197. If csDesigning in FComponentState then
  3198. AComponent.SetDesigning(true);
  3199. Notification(AComponent,opInsert);
  3200. end;
  3201. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  3202. begin
  3203. Notification(AComponent,opRemove);
  3204. Remove(AComponent);
  3205. Acomponent.Setdesigning(False);
  3206. ValidateRename(AComponent,AComponent.FName,'');
  3207. end;
  3208. procedure TComponent.SetSubComponent(ASubComponent: Boolean);
  3209. begin
  3210. if ASubComponent then
  3211. Include(FComponentStyle, csSubComponent)
  3212. else
  3213. Exclude(FComponentStyle, csSubComponent);
  3214. end;
  3215. function TComponent.GetEnumerator: TComponentEnumerator;
  3216. begin
  3217. Result:=TComponentEnumerator.Create(Self);
  3218. end;
  3219. { ---------------------------------------------------------------------
  3220. TStream
  3221. ---------------------------------------------------------------------}
  3222. Resourcestring
  3223. SStreamInvalidSeek = 'Seek is not implemented for class %s';
  3224. SStreamNoReading = 'Stream reading is not implemented for class %s';
  3225. SStreamNoWriting = 'Stream writing is not implemented for class %s';
  3226. SReadError = 'Could not read data from stream';
  3227. SWriteError = 'Could not write data to stream';
  3228. SMemoryStreamError = 'Could not allocate memory';
  3229. SerrInvalidStreamSize = 'Invalid Stream size';
  3230. procedure TStream.ReadNotImplemented;
  3231. begin
  3232. raise EStreamError.CreateFmt(SStreamNoReading, [ClassName]);
  3233. end;
  3234. procedure TStream.WriteNotImplemented;
  3235. begin
  3236. raise EStreamError.CreateFmt(SStreamNoWriting, [ClassName]);
  3237. end;
  3238. function TStream.Read(var Buffer: TBytes; Count: Longint): Longint;
  3239. begin
  3240. Result:=Read(Buffer,0,Count);
  3241. end;
  3242. function TStream.Write(const Buffer: TBytes; Count: Longint): Longint;
  3243. begin
  3244. Result:=Self.Write(Buffer,0,Count);
  3245. end;
  3246. function TStream.GetPosition: NativeInt;
  3247. begin
  3248. Result:=Seek(0,soCurrent);
  3249. end;
  3250. procedure TStream.SetPosition(const Pos: NativeInt);
  3251. begin
  3252. Seek(pos,soBeginning);
  3253. end;
  3254. procedure TStream.SetSize64(const NewSize: NativeInt);
  3255. begin
  3256. // Required because can't use overloaded functions in properties
  3257. SetSize(NewSize);
  3258. end;
  3259. function TStream.GetSize: NativeInt;
  3260. var
  3261. p : NativeInt;
  3262. begin
  3263. p:=Seek(0,soCurrent);
  3264. GetSize:=Seek(0,soEnd);
  3265. Seek(p,soBeginning);
  3266. end;
  3267. procedure TStream.SetSize(const NewSize: NativeInt);
  3268. begin
  3269. if NewSize<0 then
  3270. Raise EStreamError.Create(SerrInvalidStreamSize);
  3271. end;
  3272. procedure TStream.Discard(const Count: NativeInt);
  3273. const
  3274. CSmallSize =255;
  3275. CLargeMaxBuffer =32*1024; // 32 KiB
  3276. var
  3277. Buffer: TBytes;
  3278. begin
  3279. if Count=0 then
  3280. Exit;
  3281. if (Count<=CSmallSize) then
  3282. begin
  3283. SetLength(Buffer,CSmallSize);
  3284. ReadBuffer(Buffer,Count)
  3285. end
  3286. else
  3287. DiscardLarge(Count,CLargeMaxBuffer);
  3288. end;
  3289. procedure TStream.DiscardLarge(Count: NativeInt; const MaxBufferSize: Longint);
  3290. var
  3291. Buffer: TBytes;
  3292. begin
  3293. if Count=0 then
  3294. Exit;
  3295. if Count>MaxBufferSize then
  3296. SetLength(Buffer,MaxBufferSize)
  3297. else
  3298. SetLength(Buffer,Count);
  3299. while (Count>=Length(Buffer)) do
  3300. begin
  3301. ReadBuffer(Buffer,Length(Buffer));
  3302. Dec(Count,Length(Buffer));
  3303. end;
  3304. if Count>0 then
  3305. ReadBuffer(Buffer,Count);
  3306. end;
  3307. procedure TStream.InvalidSeek;
  3308. begin
  3309. raise EStreamError.CreateFmt(SStreamInvalidSeek, [ClassName]);
  3310. end;
  3311. procedure TStream.FakeSeekForward(Offset: NativeInt; const Origin: TSeekOrigin; const Pos: NativeInt);
  3312. begin
  3313. if Origin=soBeginning then
  3314. Dec(Offset,Pos);
  3315. if (Offset<0) or (Origin=soEnd) then
  3316. InvalidSeek;
  3317. if Offset>0 then
  3318. Discard(Offset);
  3319. end;
  3320. function TStream.ReadData({var} Buffer: TBytes; Count: NativeInt): NativeInt;
  3321. begin
  3322. Result:=Read(Buffer,0,Count);
  3323. end;
  3324. function TStream.ReadMaxSizeData(Buffer : TBytes; aSize,aCount : NativeInt) : NativeInt;
  3325. Var
  3326. CP : NativeInt;
  3327. begin
  3328. if aCount<=aSize then
  3329. Result:=read(Buffer,aCount)
  3330. else
  3331. begin
  3332. Result:=Read(Buffer,aSize);
  3333. CP:=Position;
  3334. Result:=Result+Seek(aCount-aSize,soCurrent)-CP;
  3335. end
  3336. end;
  3337. function TStream.WriteMaxSizeData(const Buffer : TBytes; aSize,aCount : NativeInt) : NativeInt;
  3338. Var
  3339. CP : NativeInt;
  3340. begin
  3341. if aCount<=aSize then
  3342. Result:=Self.Write(Buffer,aCount)
  3343. else
  3344. begin
  3345. Result:=Self.Write(Buffer,aSize);
  3346. CP:=Position;
  3347. Result:=Result+Seek(aCount-aSize,soCurrent)-CP;
  3348. end
  3349. end;
  3350. procedure TStream.WriteExactSizeData(const Buffer : TBytes; aSize, aCount: NativeInt);
  3351. begin
  3352. // Embarcadero docs mentions no exception. Does not seem very logical
  3353. WriteMaxSizeData(Buffer,aSize,ACount);
  3354. end;
  3355. procedure TStream.ReadExactSizeData(Buffer : TBytes; aSize, aCount: NativeInt);
  3356. begin
  3357. if ReadMaxSizeData(Buffer,aSize,ACount)<>aCount then
  3358. Raise EReadError.Create(SReadError);
  3359. end;
  3360. function TStream.ReadData(var Buffer: Boolean): NativeInt;
  3361. Var
  3362. B : Byte;
  3363. begin
  3364. Result:=ReadData(B,1);
  3365. if Result=1 then
  3366. Buffer:=B<>0;
  3367. end;
  3368. function TStream.ReadData(var Buffer: Boolean; Count: NativeInt): NativeInt;
  3369. Var
  3370. B : TBytes;
  3371. begin
  3372. SetLength(B,Count);
  3373. Result:=ReadMaxSizeData(B,1,Count);
  3374. if Result>0 then
  3375. Buffer:=B[0]<>0
  3376. end;
  3377. function TStream.ReadData(var Buffer: WideChar): NativeInt;
  3378. begin
  3379. Result:=ReadData(Buffer,2);
  3380. end;
  3381. function TStream.ReadData(var Buffer: WideChar; Count: NativeInt): NativeInt;
  3382. Var
  3383. W : Word;
  3384. begin
  3385. Result:=ReadData(W,Count);
  3386. if Result=2 then
  3387. Buffer:=WideChar(W);
  3388. end;
  3389. function TStream.ReadData(var Buffer: Int8): NativeInt;
  3390. begin
  3391. Result:=ReadData(Buffer,1);
  3392. end;
  3393. Function TStream.MakeInt(B : TBytes; aSize : Integer; Signed : Boolean) : NativeInt;
  3394. Var
  3395. Mem : TJSArrayBuffer;
  3396. A : TJSUInt8Array;
  3397. D : TJSDataView;
  3398. isLittle : Boolean;
  3399. begin
  3400. IsLittle:=(Endian=TEndian.Little);
  3401. Mem:=TJSArrayBuffer.New(Length(B));
  3402. A:=TJSUInt8Array.new(Mem);
  3403. A._set(B);
  3404. D:=TJSDataView.New(Mem);
  3405. if Signed then
  3406. case aSize of
  3407. 1 : Result:=D.getInt8(0);
  3408. 2 : Result:=D.getInt16(0,IsLittle);
  3409. 4 : Result:=D.getInt32(0,IsLittle);
  3410. // Todo : fix sign
  3411. 8 : Result:=Round(D.getFloat64(0,IsLittle));
  3412. end
  3413. else
  3414. case aSize of
  3415. 1 : Result:=D.getUInt8(0);
  3416. 2 : Result:=D.getUInt16(0,IsLittle);
  3417. 4 : Result:=D.getUInt32(0,IsLittle);
  3418. 8 : Result:=Round(D.getFloat64(0,IsLittle));
  3419. end
  3420. end;
  3421. function TStream.MakeBytes(B: NativeInt; aSize: Integer; Signed: Boolean): TBytes;
  3422. Var
  3423. Mem : TJSArrayBuffer;
  3424. A : TJSUInt8Array;
  3425. D : TJSDataView;
  3426. isLittle : Boolean;
  3427. begin
  3428. IsLittle:=(Endian=TEndian.Little);
  3429. Mem:=TJSArrayBuffer.New(aSize);
  3430. D:=TJSDataView.New(Mem);
  3431. if Signed then
  3432. case aSize of
  3433. 1 : D.setInt8(0,B);
  3434. 2 : D.setInt16(0,B,IsLittle);
  3435. 4 : D.setInt32(0,B,IsLittle);
  3436. 8 : D.setFloat64(0,B,IsLittle);
  3437. end
  3438. else
  3439. case aSize of
  3440. 1 : D.SetUInt8(0,B);
  3441. 2 : D.SetUInt16(0,B,IsLittle);
  3442. 4 : D.SetUInt32(0,B,IsLittle);
  3443. 8 : D.setFloat64(0,B,IsLittle);
  3444. end;
  3445. SetLength(Result,aSize);
  3446. A:=TJSUInt8Array.new(Mem);
  3447. Result:=TMemoryStream.MemoryToBytes(A);
  3448. end;
  3449. function TStream.ReadData(var Buffer: Int8; Count: NativeInt): NativeInt;
  3450. Var
  3451. B : TBytes;
  3452. begin
  3453. SetLength(B,Count);
  3454. Result:=ReadMaxSizeData(B,1,Count);
  3455. if Result>=1 then
  3456. Buffer:=MakeInt(B,1,True);
  3457. end;
  3458. function TStream.ReadData(var Buffer: UInt8): NativeInt;
  3459. begin
  3460. Result:=ReadData(Buffer,1);
  3461. end;
  3462. function TStream.ReadData(var Buffer: UInt8; Count: NativeInt): NativeInt;
  3463. Var
  3464. B : TBytes;
  3465. begin
  3466. SetLength(B,Count);
  3467. Result:=ReadMaxSizeData(B,1,Count);
  3468. if Result>=1 then
  3469. Buffer:=MakeInt(B,1,False);
  3470. end;
  3471. function TStream.ReadData(var Buffer: Int16): NativeInt;
  3472. begin
  3473. Result:=ReadData(Buffer,2);
  3474. end;
  3475. function TStream.ReadData(var Buffer: Int16; Count: NativeInt): NativeInt;
  3476. Var
  3477. B : TBytes;
  3478. begin
  3479. SetLength(B,Count);
  3480. Result:=ReadMaxSizeData(B,2,Count);
  3481. if Result>=2 then
  3482. Buffer:=MakeInt(B,2,True);
  3483. end;
  3484. function TStream.ReadData(var Buffer: UInt16): NativeInt;
  3485. begin
  3486. Result:=ReadData(Buffer,2);
  3487. end;
  3488. function TStream.ReadData(var Buffer: UInt16; Count: NativeInt): NativeInt;
  3489. Var
  3490. B : TBytes;
  3491. begin
  3492. SetLength(B,Count);
  3493. Result:=ReadMaxSizeData(B,2,Count);
  3494. if Result>=2 then
  3495. Buffer:=MakeInt(B,2,False);
  3496. end;
  3497. function TStream.ReadData(var Buffer: Int32): NativeInt;
  3498. begin
  3499. Result:=ReadData(Buffer,4);
  3500. end;
  3501. function TStream.ReadData(var Buffer: Int32; Count: NativeInt): NativeInt;
  3502. Var
  3503. B : TBytes;
  3504. begin
  3505. SetLength(B,Count);
  3506. Result:=ReadMaxSizeData(B,4,Count);
  3507. if Result>=4 then
  3508. Buffer:=MakeInt(B,4,True);
  3509. end;
  3510. function TStream.ReadData(var Buffer: UInt32): NativeInt;
  3511. begin
  3512. Result:=ReadData(Buffer,4);
  3513. end;
  3514. function TStream.ReadData(var Buffer: UInt32; Count: NativeInt): NativeInt;
  3515. Var
  3516. B : TBytes;
  3517. begin
  3518. SetLength(B,Count);
  3519. Result:=ReadMaxSizeData(B,4,Count);
  3520. if Result>=4 then
  3521. Buffer:=MakeInt(B,4,False);
  3522. end;
  3523. function TStream.ReadData(var Buffer: NativeInt): NativeInt;
  3524. begin
  3525. Result:=ReadData(Buffer,8);
  3526. end;
  3527. function TStream.ReadData(var Buffer: NativeInt; Count: NativeInt): NativeInt;
  3528. Var
  3529. B : TBytes;
  3530. begin
  3531. SetLength(B,Count);
  3532. Result:=ReadMaxSizeData(B,8,8);
  3533. if Result>=8 then
  3534. Buffer:=MakeInt(B,8,True);
  3535. end;
  3536. function TStream.ReadData(var Buffer: NativeLargeUInt): NativeInt;
  3537. begin
  3538. Result:=ReadData(Buffer,8);
  3539. end;
  3540. function TStream.ReadData(var Buffer: NativeLargeUInt; Count: NativeInt): NativeInt;
  3541. Var
  3542. B : TBytes;
  3543. B1 : Integer;
  3544. begin
  3545. SetLength(B,Count);
  3546. Result:=ReadMaxSizeData(B,4,4);
  3547. if Result>=4 then
  3548. begin
  3549. B1:=MakeInt(B,4,False);
  3550. Result:=Result+ReadMaxSizeData(B,4,4);
  3551. Buffer:=MakeInt(B,4,False);
  3552. Buffer:=(Buffer shl 32) or B1;
  3553. end;
  3554. end;
  3555. function TStream.ReadData(var Buffer: Double): NativeInt;
  3556. begin
  3557. Result:=ReadData(Buffer,8);
  3558. end;
  3559. function TStream.ReadData(var Buffer: Double; Count: NativeInt): NativeInt;
  3560. Var
  3561. B : TBytes;
  3562. Mem : TJSArrayBuffer;
  3563. A : TJSUInt8Array;
  3564. D : TJSDataView;
  3565. begin
  3566. SetLength(B,Count);
  3567. Result:=ReadMaxSizeData(B,8,Count);
  3568. if Result>=8 then
  3569. begin
  3570. Mem:=TJSArrayBuffer.New(8);
  3571. A:=TJSUInt8Array.new(Mem);
  3572. A._set(B);
  3573. D:=TJSDataView.New(Mem);
  3574. Buffer:=D.getFloat64(0);
  3575. end;
  3576. end;
  3577. procedure TStream.ReadBuffer(var Buffer: TBytes; Count: NativeInt);
  3578. begin
  3579. ReadBuffer(Buffer,0,Count);
  3580. end;
  3581. procedure TStream.ReadBuffer(var Buffer: TBytes; Offset, Count: NativeInt);
  3582. begin
  3583. if Read(Buffer,OffSet,Count)<>Count then
  3584. Raise EStreamError.Create(SReadError);
  3585. end;
  3586. procedure TStream.ReadBufferData(var Buffer: Boolean);
  3587. begin
  3588. ReadBufferData(Buffer,1);
  3589. end;
  3590. procedure TStream.ReadBufferData(var Buffer: Boolean; Count: NativeInt);
  3591. begin
  3592. if (ReadData(Buffer,Count)<>Count) then
  3593. Raise EStreamError.Create(SReadError);
  3594. end;
  3595. procedure TStream.ReadBufferData(var Buffer: WideChar);
  3596. begin
  3597. ReadBufferData(Buffer,2);
  3598. end;
  3599. procedure TStream.ReadBufferData(var Buffer: WideChar; Count: NativeInt);
  3600. begin
  3601. if (ReadData(Buffer,Count)<>Count) then
  3602. Raise EStreamError.Create(SReadError);
  3603. end;
  3604. procedure TStream.ReadBufferData(var Buffer: Int8);
  3605. begin
  3606. ReadBufferData(Buffer,1);
  3607. end;
  3608. procedure TStream.ReadBufferData(var Buffer: Int8; Count: NativeInt);
  3609. begin
  3610. if (ReadData(Buffer,Count)<>Count) then
  3611. Raise EStreamError.Create(SReadError);
  3612. end;
  3613. procedure TStream.ReadBufferData(var Buffer: UInt8);
  3614. begin
  3615. ReadBufferData(Buffer,1);
  3616. end;
  3617. procedure TStream.ReadBufferData(var Buffer: UInt8; Count: NativeInt);
  3618. begin
  3619. if (ReadData(Buffer,Count)<>Count) then
  3620. Raise EStreamError.Create(SReadError);
  3621. end;
  3622. procedure TStream.ReadBufferData(var Buffer: Int16);
  3623. begin
  3624. ReadBufferData(Buffer,2);
  3625. end;
  3626. procedure TStream.ReadBufferData(var Buffer: Int16; Count: NativeInt);
  3627. begin
  3628. if (ReadData(Buffer,Count)<>Count) then
  3629. Raise EStreamError.Create(SReadError);
  3630. end;
  3631. procedure TStream.ReadBufferData(var Buffer: UInt16);
  3632. begin
  3633. ReadBufferData(Buffer,2);
  3634. end;
  3635. procedure TStream.ReadBufferData(var Buffer: UInt16; Count: NativeInt);
  3636. begin
  3637. if (ReadData(Buffer,Count)<>Count) then
  3638. Raise EStreamError.Create(SReadError);
  3639. end;
  3640. procedure TStream.ReadBufferData(var Buffer: Int32);
  3641. begin
  3642. ReadBufferData(Buffer,4);
  3643. end;
  3644. procedure TStream.ReadBufferData(var Buffer: Int32; Count: NativeInt);
  3645. begin
  3646. if (ReadData(Buffer,Count)<>Count) then
  3647. Raise EStreamError.Create(SReadError);
  3648. end;
  3649. procedure TStream.ReadBufferData(var Buffer: UInt32);
  3650. begin
  3651. ReadBufferData(Buffer,4);
  3652. end;
  3653. procedure TStream.ReadBufferData(var Buffer: UInt32; Count: NativeInt);
  3654. begin
  3655. if (ReadData(Buffer,Count)<>Count) then
  3656. Raise EStreamError.Create(SReadError);
  3657. end;
  3658. procedure TStream.ReadBufferData(var Buffer: NativeLargeInt);
  3659. begin
  3660. ReadBufferData(Buffer,8)
  3661. end;
  3662. procedure TStream.ReadBufferData(var Buffer: NativeLargeInt; Count: NativeInt);
  3663. begin
  3664. if (ReadData(Buffer,Count)<>Count) then
  3665. Raise EStreamError.Create(SReadError);
  3666. end;
  3667. procedure TStream.ReadBufferData(var Buffer: NativeLargeUInt);
  3668. begin
  3669. ReadBufferData(Buffer,8);
  3670. end;
  3671. procedure TStream.ReadBufferData(var Buffer: NativeLargeUInt; Count: NativeInt);
  3672. begin
  3673. if (ReadData(Buffer,Count)<>Count) then
  3674. Raise EStreamError.Create(SReadError);
  3675. end;
  3676. procedure TStream.ReadBufferData(var Buffer: Double);
  3677. begin
  3678. ReadBufferData(Buffer,8);
  3679. end;
  3680. procedure TStream.ReadBufferData(var Buffer: Double; Count: NativeInt);
  3681. begin
  3682. if (ReadData(Buffer,Count)<>Count) then
  3683. Raise EStreamError.Create(SReadError);
  3684. end;
  3685. procedure TStream.WriteBuffer(const Buffer: TBytes; Count: NativeInt);
  3686. begin
  3687. WriteBuffer(Buffer,0,Count);
  3688. end;
  3689. procedure TStream.WriteBuffer(const Buffer: TBytes; Offset, Count: NativeInt);
  3690. begin
  3691. if Self.Write(Buffer,Offset,Count)<>Count then
  3692. Raise EStreamError.Create(SWriteError);
  3693. end;
  3694. function TStream.WriteData(const Buffer: TBytes; Count: NativeInt): NativeInt;
  3695. begin
  3696. Result:=Self.Write(Buffer, 0, Count);
  3697. end;
  3698. function TStream.WriteData(const Buffer: Boolean): NativeInt;
  3699. begin
  3700. Result:=WriteData(Buffer,1);
  3701. end;
  3702. function TStream.WriteData(const Buffer: Boolean; Count: NativeInt): NativeInt;
  3703. Var
  3704. B : Int8;
  3705. begin
  3706. B:=Ord(Buffer);
  3707. Result:=WriteData(B,Count);
  3708. end;
  3709. function TStream.WriteData(const Buffer: WideChar): NativeInt;
  3710. begin
  3711. Result:=WriteData(Buffer,2);
  3712. end;
  3713. function TStream.WriteData(const Buffer: WideChar; Count: NativeInt): NativeInt;
  3714. Var
  3715. U : UInt16;
  3716. begin
  3717. U:=Ord(Buffer);
  3718. Result:=WriteData(U,Count);
  3719. end;
  3720. function TStream.WriteData(const Buffer: Int8): NativeInt;
  3721. begin
  3722. Result:=WriteData(Buffer,1);
  3723. end;
  3724. function TStream.WriteData(const Buffer: Int8; Count: NativeInt): NativeInt;
  3725. begin
  3726. Result:=WriteMaxSizeData(MakeBytes(Buffer,1,True),1,Count);
  3727. end;
  3728. function TStream.WriteData(const Buffer: UInt8): NativeInt;
  3729. begin
  3730. Result:=WriteData(Buffer,1);
  3731. end;
  3732. function TStream.WriteData(const Buffer: UInt8; Count: NativeInt): NativeInt;
  3733. begin
  3734. Result:=WriteMaxSizeData(MakeBytes(Buffer,1,False),1,Count);
  3735. end;
  3736. function TStream.WriteData(const Buffer: Int16): NativeInt;
  3737. begin
  3738. Result:=WriteData(Buffer,2);
  3739. end;
  3740. function TStream.WriteData(const Buffer: Int16; Count: NativeInt): NativeInt;
  3741. begin
  3742. Result:=WriteMaxSizeData(MakeBytes(Buffer,2,True),2,Count);
  3743. end;
  3744. function TStream.WriteData(const Buffer: UInt16): NativeInt;
  3745. begin
  3746. Result:=WriteData(Buffer,2);
  3747. end;
  3748. function TStream.WriteData(const Buffer: UInt16; Count: NativeInt): NativeInt;
  3749. begin
  3750. Result:=WriteMaxSizeData(MakeBytes(Buffer,2,True),2,Count);
  3751. end;
  3752. function TStream.WriteData(const Buffer: Int32): NativeInt;
  3753. begin
  3754. Result:=WriteData(Buffer,4);
  3755. end;
  3756. function TStream.WriteData(const Buffer: Int32; Count: NativeInt): NativeInt;
  3757. begin
  3758. Result:=WriteMaxSizeData(MakeBytes(Buffer,4,True),4,Count);
  3759. end;
  3760. function TStream.WriteData(const Buffer: UInt32): NativeInt;
  3761. begin
  3762. Result:=WriteData(Buffer,4);
  3763. end;
  3764. function TStream.WriteData(const Buffer: UInt32; Count: NativeInt): NativeInt;
  3765. begin
  3766. Result:=WriteMaxSizeData(MakeBytes(Buffer,4,False),4,Count);
  3767. end;
  3768. function TStream.WriteData(const Buffer: NativeLargeInt): NativeInt;
  3769. begin
  3770. Result:=WriteData(Buffer,8);
  3771. end;
  3772. function TStream.WriteData(const Buffer: NativeLargeInt; Count: NativeInt): NativeInt;
  3773. begin
  3774. Result:=WriteMaxSizeData(MakeBytes(Buffer,8,True),8,Count);
  3775. end;
  3776. function TStream.WriteData(const Buffer: NativeLargeUInt): NativeInt;
  3777. begin
  3778. Result:=WriteData(Buffer,8);
  3779. end;
  3780. function TStream.WriteData(const Buffer: NativeLargeUInt; Count: NativeInt): NativeInt;
  3781. begin
  3782. Result:=WriteMaxSizeData(MakeBytes(Buffer,8,False),8,Count);
  3783. end;
  3784. function TStream.WriteData(const Buffer: Double): NativeInt;
  3785. begin
  3786. Result:=WriteData(Buffer,8);
  3787. end;
  3788. function TStream.WriteData(const Buffer: Double; Count: NativeInt): NativeInt;
  3789. Var
  3790. Mem : TJSArrayBuffer;
  3791. A : TJSUint8array;
  3792. D : TJSDataview;
  3793. B : TBytes;
  3794. I : Integer;
  3795. begin
  3796. Mem:=TJSArrayBuffer.New(8);
  3797. D:=TJSDataView.new(Mem);
  3798. D.setFloat64(0,Buffer);
  3799. SetLength(B,8);
  3800. A:=TJSUint8array.New(Mem);
  3801. For I:=0 to 7 do
  3802. B[i]:=A[i];
  3803. Result:=WriteMaxSizeData(B,8,Count);
  3804. end;
  3805. procedure TStream.WriteBufferData(Buffer: Int32);
  3806. begin
  3807. WriteBufferData(Buffer,4);
  3808. end;
  3809. procedure TStream.WriteBufferData(Buffer: Int32; Count: NativeInt);
  3810. begin
  3811. if (WriteData(Buffer,Count)<>Count) then
  3812. Raise EStreamError.Create(SWriteError);
  3813. end;
  3814. procedure TStream.WriteBufferData(Buffer: Boolean);
  3815. begin
  3816. WriteBufferData(Buffer,1);
  3817. end;
  3818. procedure TStream.WriteBufferData(Buffer: Boolean; Count: NativeInt);
  3819. begin
  3820. if (WriteData(Buffer,Count)<>Count) then
  3821. Raise EStreamError.Create(SWriteError);
  3822. end;
  3823. procedure TStream.WriteBufferData(Buffer: WideChar);
  3824. begin
  3825. WriteBufferData(Buffer,2);
  3826. end;
  3827. procedure TStream.WriteBufferData(Buffer: WideChar; Count: NativeInt);
  3828. begin
  3829. if (WriteData(Buffer,Count)<>Count) then
  3830. Raise EStreamError.Create(SWriteError);
  3831. end;
  3832. procedure TStream.WriteBufferData(Buffer: Int8);
  3833. begin
  3834. WriteBufferData(Buffer,1);
  3835. end;
  3836. procedure TStream.WriteBufferData(Buffer: Int8; Count: NativeInt);
  3837. begin
  3838. if (WriteData(Buffer,Count)<>Count) then
  3839. Raise EStreamError.Create(SWriteError);
  3840. end;
  3841. procedure TStream.WriteBufferData(Buffer: UInt8);
  3842. begin
  3843. WriteBufferData(Buffer,1);
  3844. end;
  3845. procedure TStream.WriteBufferData(Buffer: UInt8; Count: NativeInt);
  3846. begin
  3847. if (WriteData(Buffer,Count)<>Count) then
  3848. Raise EStreamError.Create(SWriteError);
  3849. end;
  3850. procedure TStream.WriteBufferData(Buffer: Int16);
  3851. begin
  3852. WriteBufferData(Buffer,2);
  3853. end;
  3854. procedure TStream.WriteBufferData(Buffer: Int16; Count: NativeInt);
  3855. begin
  3856. if (WriteData(Buffer,Count)<>Count) then
  3857. Raise EStreamError.Create(SWriteError);
  3858. end;
  3859. procedure TStream.WriteBufferData(Buffer: UInt16);
  3860. begin
  3861. WriteBufferData(Buffer,2);
  3862. end;
  3863. procedure TStream.WriteBufferData(Buffer: UInt16; Count: NativeInt);
  3864. begin
  3865. if (WriteData(Buffer,Count)<>Count) then
  3866. Raise EStreamError.Create(SWriteError);
  3867. end;
  3868. procedure TStream.WriteBufferData(Buffer: UInt32);
  3869. begin
  3870. WriteBufferData(Buffer,4);
  3871. end;
  3872. procedure TStream.WriteBufferData(Buffer: UInt32; Count: NativeInt);
  3873. begin
  3874. if (WriteData(Buffer,Count)<>Count) then
  3875. Raise EStreamError.Create(SWriteError);
  3876. end;
  3877. procedure TStream.WriteBufferData(Buffer: NativeInt);
  3878. begin
  3879. WriteBufferData(Buffer,8);
  3880. end;
  3881. procedure TStream.WriteBufferData(Buffer: NativeInt; Count: NativeInt);
  3882. begin
  3883. if (WriteData(Buffer,Count)<>Count) then
  3884. Raise EStreamError.Create(SWriteError);
  3885. end;
  3886. procedure TStream.WriteBufferData(Buffer: NativeLargeUInt);
  3887. begin
  3888. WriteBufferData(Buffer,8);
  3889. end;
  3890. procedure TStream.WriteBufferData(Buffer: NativeLargeUInt; Count: NativeInt);
  3891. begin
  3892. if (WriteData(Buffer,Count)<>Count) then
  3893. Raise EStreamError.Create(SWriteError);
  3894. end;
  3895. procedure TStream.WriteBufferData(Buffer: Double);
  3896. begin
  3897. WriteBufferData(Buffer,8);
  3898. end;
  3899. procedure TStream.WriteBufferData(Buffer: Double; Count: NativeInt);
  3900. begin
  3901. if (WriteData(Buffer,Count)<>Count) then
  3902. Raise EStreamError.Create(SWriteError);
  3903. end;
  3904. function TStream.CopyFrom(Source: TStream; Count: NativeInt): NativeInt;
  3905. var
  3906. Buffer: TBytes;
  3907. BufferSize, i: LongInt;
  3908. const
  3909. MaxSize = $20000;
  3910. begin
  3911. Result:=0;
  3912. if Count=0 then
  3913. Source.Position:=0; // This WILL fail for non-seekable streams...
  3914. BufferSize:=MaxSize;
  3915. if (Count>0) and (Count<BufferSize) then
  3916. BufferSize:=Count; // do not allocate more than needed
  3917. SetLength(Buffer,BufferSize);
  3918. if Count=0 then
  3919. repeat
  3920. i:=Source.Read(Buffer,BufferSize);
  3921. if i>0 then
  3922. WriteBuffer(Buffer,i);
  3923. Inc(Result,i);
  3924. until i<BufferSize
  3925. else
  3926. while Count>0 do
  3927. begin
  3928. if Count>BufferSize then
  3929. i:=BufferSize
  3930. else
  3931. i:=Count;
  3932. Source.ReadBuffer(Buffer,i);
  3933. WriteBuffer(Buffer,i);
  3934. Dec(count,i);
  3935. Inc(Result,i);
  3936. end;
  3937. end;
  3938. (*
  3939. function TStream.ReadComponent(Instance: TComponent): TComponent;
  3940. var
  3941. Reader: TReader;
  3942. begin
  3943. Reader := TReader.Create(Self, 4096);
  3944. try
  3945. Result := Reader.ReadRootComponent(Instance);
  3946. finally
  3947. Reader.Free;
  3948. end;
  3949. end;
  3950. function TStream.ReadComponentRes(Instance: TComponent): TComponent;
  3951. begin
  3952. ReadResHeader;
  3953. Result := ReadComponent(Instance);
  3954. end;
  3955. procedure TStream.WriteComponent(Instance: TComponent);
  3956. begin
  3957. WriteDescendent(Instance, nil);
  3958. end;
  3959. procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent);
  3960. begin
  3961. WriteDescendentRes(ResName, Instance, nil);
  3962. end;
  3963. procedure TStream.WriteDescendent(Instance, Ancestor: TComponent);
  3964. var
  3965. Driver : TAbstractObjectWriter;
  3966. Writer : TWriter;
  3967. begin
  3968. Driver := TBinaryObjectWriter.Create(Self, 4096);
  3969. Try
  3970. Writer := TWriter.Create(Driver);
  3971. Try
  3972. Writer.WriteDescendent(Instance, Ancestor);
  3973. Finally
  3974. Writer.Destroy;
  3975. end;
  3976. Finally
  3977. Driver.Free;
  3978. end;
  3979. end;
  3980. procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
  3981. var
  3982. FixupInfo: Longint;
  3983. begin
  3984. { Write a resource header }
  3985. WriteResourceHeader(ResName, FixupInfo);
  3986. { Write the instance itself }
  3987. WriteDescendent(Instance, Ancestor);
  3988. { Insert the correct resource size into the resource header }
  3989. FixupResourceHeader(FixupInfo);
  3990. end;
  3991. procedure TStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Longint);
  3992. var
  3993. ResType, Flags : word;
  3994. begin
  3995. ResType:=NtoLE(word($000A));
  3996. Flags:=NtoLE(word($1030));
  3997. { Note: This is a Windows 16 bit resource }
  3998. { Numeric resource type }
  3999. WriteByte($ff);
  4000. { Application defined data }
  4001. WriteWord(ResType);
  4002. { write the name as asciiz }
  4003. WriteBuffer(ResName[1],length(ResName));
  4004. WriteByte(0);
  4005. { Movable, Pure and Discardable }
  4006. WriteWord(Flags);
  4007. { Placeholder for the resource size }
  4008. WriteDWord(0);
  4009. { Return current stream position so that the resource size can be
  4010. inserted later }
  4011. FixupInfo := Position;
  4012. end;
  4013. procedure TStream.FixupResourceHeader(FixupInfo: Longint);
  4014. var
  4015. ResSize,TmpResSize : Longint;
  4016. begin
  4017. ResSize := Position - FixupInfo;
  4018. TmpResSize := NtoLE(longword(ResSize));
  4019. { Insert the correct resource size into the placeholder written by
  4020. WriteResourceHeader }
  4021. Position := FixupInfo - 4;
  4022. WriteDWord(TmpResSize);
  4023. { Seek back to the end of the resource }
  4024. Position := FixupInfo + ResSize;
  4025. end;
  4026. procedure TStream.ReadResHeader;
  4027. var
  4028. ResType, Flags : word;
  4029. begin
  4030. try
  4031. { Note: This is a Windows 16 bit resource }
  4032. { application specific resource ? }
  4033. if ReadByte<>$ff then
  4034. raise EInvalidImage.Create(SInvalidImage);
  4035. ResType:=LEtoN(ReadWord);
  4036. if ResType<>$000a then
  4037. raise EInvalidImage.Create(SInvalidImage);
  4038. { read name }
  4039. while ReadByte<>0 do
  4040. ;
  4041. { check the access specifier }
  4042. Flags:=LEtoN(ReadWord);
  4043. if Flags<>$1030 then
  4044. raise EInvalidImage.Create(SInvalidImage);
  4045. { ignore the size }
  4046. ReadDWord;
  4047. except
  4048. on EInvalidImage do
  4049. raise;
  4050. else
  4051. raise EInvalidImage.create(SInvalidImage);
  4052. end;
  4053. end;
  4054. *)
  4055. function TStream.ReadByte : Byte;
  4056. begin
  4057. ReadBufferData(Result,1);
  4058. end;
  4059. function TStream.ReadWord : Word;
  4060. begin
  4061. ReadBufferData(Result,2);
  4062. end;
  4063. function TStream.ReadDWord : Cardinal;
  4064. begin
  4065. ReadBufferData(Result,4);
  4066. end;
  4067. function TStream.ReadQWord: NativeLargeUInt;
  4068. begin
  4069. ReadBufferData(Result,8);
  4070. end;
  4071. procedure TStream.WriteByte(b : Byte);
  4072. begin
  4073. WriteBufferData(b,1);
  4074. end;
  4075. procedure TStream.WriteWord(w : Word);
  4076. begin
  4077. WriteBufferData(W,2);
  4078. end;
  4079. procedure TStream.WriteDWord(d : Cardinal);
  4080. begin
  4081. WriteBufferData(d,4);
  4082. end;
  4083. procedure TStream.WriteQWord(q: NativeLargeUInt);
  4084. begin
  4085. WriteBufferData(q,8);
  4086. end;
  4087. {****************************************************************************}
  4088. {* TCustomMemoryStream *}
  4089. {****************************************************************************}
  4090. procedure TCustomMemoryStream.SetPointer(Ptr: TJSArrayBuffer; ASize: PtrInt);
  4091. begin
  4092. FMemory:=Ptr;
  4093. FSize:=ASize;
  4094. FDataView:=Nil;
  4095. FDataArray:=Nil;
  4096. end;
  4097. Class Function TCustomMemoryStream.MemoryToBytes(Mem : TJSArrayBuffer) : TBytes; overload;
  4098. begin
  4099. Result:=MemoryToBytes(TJSUint8Array.New(Mem));
  4100. end;
  4101. class function TCustomMemoryStream.MemoryToBytes(Mem: TJSUint8Array): TBytes;
  4102. Var
  4103. I : Integer;
  4104. begin
  4105. // This must be improved, but needs some asm or TJSFunction.call() to implement answers in
  4106. // https://stackoverflow.com/questions/29676635/convert-uint8array-to-array-in-javascript
  4107. for i:=0 to mem.length-1 do
  4108. Result[i]:=Mem[i];
  4109. end;
  4110. class function TCustomMemoryStream.BytesToMemory(aBytes: TBytes): TJSArrayBuffer;
  4111. Var
  4112. a : TJSUint8Array;
  4113. begin
  4114. Result:=TJSArrayBuffer.new(Length(aBytes));
  4115. A:=TJSUint8Array.New(Result);
  4116. A._set(aBytes);
  4117. end;
  4118. function TCustomMemoryStream.GetDataArray: TJSUint8Array;
  4119. begin
  4120. if FDataArray=Nil then
  4121. FDataArray:=TJSUint8Array.new(Memory);
  4122. Result:=FDataArray;
  4123. end;
  4124. function TCustomMemoryStream.GetDataView: TJSDataview;
  4125. begin
  4126. if FDataView=Nil then
  4127. FDataView:=TJSDataView.New(Memory);
  4128. Result:=FDataView;
  4129. end;
  4130. function TCustomMemoryStream.GetSize: NativeInt;
  4131. begin
  4132. Result:=FSize;
  4133. end;
  4134. function TCustomMemoryStream.GetPosition: NativeInt;
  4135. begin
  4136. Result:=FPosition;
  4137. end;
  4138. function TCustomMemoryStream.Read(Buffer : TBytes; offset, Count: LongInt): LongInt;
  4139. Var
  4140. I,Src,Dest : Integer;
  4141. begin
  4142. Result:=0;
  4143. If (FSize>0) and (FPosition<Fsize) and (FPosition>=0) then
  4144. begin
  4145. Result:=Count;
  4146. If (Result>(FSize-FPosition)) then
  4147. Result:=(FSize-FPosition);
  4148. Src:=FPosition;
  4149. Dest:=Offset;
  4150. I:=0;
  4151. While I<Result do
  4152. begin
  4153. Buffer[Dest]:=DataView.getUint8(Src);
  4154. inc(Src);
  4155. inc(Dest);
  4156. inc(I);
  4157. end;
  4158. FPosition:=Fposition+Result;
  4159. end;
  4160. end;
  4161. function TCustomMemoryStream.Seek(const Offset: NativeInt; Origin: TSeekOrigin): NativeInt;
  4162. begin
  4163. Case Origin of
  4164. soBeginning : FPosition:=Offset;
  4165. soEnd : FPosition:=FSize+Offset;
  4166. soCurrent : FPosition:=FPosition+Offset;
  4167. end;
  4168. if SizeBoundsSeek and (FPosition>FSize) then
  4169. FPosition:=FSize;
  4170. Result:=FPosition;
  4171. {$IFDEF DEBUG}
  4172. if Result < 0 then
  4173. raise Exception.Create('TCustomMemoryStream');
  4174. {$ENDIF}
  4175. end;
  4176. procedure TCustomMemoryStream.SaveToStream(Stream: TStream);
  4177. begin
  4178. if FSize>0 then
  4179. Stream.WriteBuffer(TMemoryStream.MemoryToBytes(Memory),FSize);
  4180. end;
  4181. {****************************************************************************}
  4182. {* TMemoryStream *}
  4183. {****************************************************************************}
  4184. Const TMSGrow = 4096; { Use 4k blocks. }
  4185. procedure TMemoryStream.SetCapacity(NewCapacity: PtrInt);
  4186. begin
  4187. SetPointer (Realloc(NewCapacity),Fsize);
  4188. FCapacity:=NewCapacity;
  4189. end;
  4190. function TMemoryStream.Realloc(var NewCapacity: PtrInt): TJSArrayBuffer;
  4191. Var
  4192. GC : PtrInt;
  4193. DestView : TJSUInt8array;
  4194. begin
  4195. If NewCapacity<0 Then
  4196. NewCapacity:=0
  4197. else
  4198. begin
  4199. GC:=FCapacity + (FCapacity div 4);
  4200. // if growing, grow at least a quarter
  4201. if (NewCapacity>FCapacity) and (NewCapacity < GC) then
  4202. NewCapacity := GC;
  4203. // round off to block size.
  4204. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  4205. end;
  4206. // Only now check !
  4207. If NewCapacity=FCapacity then
  4208. Result:=FMemory
  4209. else if NewCapacity=0 then
  4210. Result:=Nil
  4211. else
  4212. begin
  4213. // New buffer
  4214. Result:=TJSArrayBuffer.New(NewCapacity);
  4215. If (Result=Nil) then
  4216. Raise EStreamError.Create(SMemoryStreamError);
  4217. // Transfer
  4218. DestView:=TJSUInt8array.New(Result);
  4219. Destview._Set(Self.DataArray);
  4220. end;
  4221. end;
  4222. destructor TMemoryStream.Destroy;
  4223. begin
  4224. Clear;
  4225. Inherited Destroy;
  4226. end;
  4227. procedure TMemoryStream.Clear;
  4228. begin
  4229. FSize:=0;
  4230. FPosition:=0;
  4231. SetCapacity (0);
  4232. end;
  4233. procedure TMemoryStream.LoadFromStream(Stream: TStream);
  4234. begin
  4235. Stream.Position:=0;
  4236. SetSize(Stream.Size);
  4237. If FSize>0 then Stream.ReadBuffer(MemoryToBytes(FMemory),FSize);
  4238. end;
  4239. procedure TMemoryStream.SetSize(const NewSize: NativeInt);
  4240. begin
  4241. SetCapacity (NewSize);
  4242. FSize:=NewSize;
  4243. IF FPosition>FSize then
  4244. FPosition:=FSize;
  4245. end;
  4246. function TMemoryStream.Write(Const Buffer : TBytes; OffSet, Count: LongInt): LongInt;
  4247. Var NewPos : PtrInt;
  4248. begin
  4249. If (Count=0) or (FPosition<0) then
  4250. exit(0);
  4251. NewPos:=FPosition+Count;
  4252. If NewPos>Fsize then
  4253. begin
  4254. IF NewPos>FCapacity then
  4255. SetCapacity (NewPos);
  4256. FSize:=Newpos;
  4257. end;
  4258. DataArray._set(Copy(Buffer,Offset,Count),FPosition);
  4259. FPosition:=NewPos;
  4260. Result:=Count;
  4261. end;
  4262. {****************************************************************************}
  4263. {* TBytesStream *}
  4264. {****************************************************************************}
  4265. constructor TBytesStream.Create(const ABytes: TBytes);
  4266. begin
  4267. inherited Create;
  4268. SetPointer(TMemoryStream.BytesToMemory(aBytes),Length(ABytes));
  4269. FCapacity:=Length(ABytes);
  4270. end;
  4271. function TBytesStream.GetBytes: TBytes;
  4272. begin
  4273. Result:=TMemoryStream.MemoryToBytes(Memory);
  4274. end;
  4275. { ---------------------------------------------------------------------
  4276. Global routines
  4277. ---------------------------------------------------------------------}
  4278. var
  4279. ClassList : TJSObject;
  4280. Procedure RegisterClass(AClass : TPersistentClass);
  4281. begin
  4282. ClassList[AClass.ClassName]:=AClass;
  4283. end;
  4284. Function GetClass(AClassName : string) : TPersistentClass;
  4285. begin
  4286. Result:=nil;
  4287. if AClassName='' then exit;
  4288. if not ClassList.hasOwnProperty(AClassName) then exit;
  4289. Result:=TPersistentClass(ClassList[AClassName]);
  4290. end;
  4291. initialization
  4292. ClassList:=TJSObject.create(nil);
  4293. end.