classes.pas 124 KB

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