superobject.pas 199 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621
  1. (*
  2. * Super Object Toolkit
  3. *
  4. * Usage allowed under the restrictions of the Lesser GNU General Public License
  5. * or alternatively the restrictions of the Mozilla Public License 1.1
  6. *
  7. * Software distributed under the License is distributed on an "AS IS" basis,
  8. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  9. * the specific language governing rights and limitations under the License.
  10. *
  11. * Embarcadero Technologies Inc is not permitted to use or redistribute
  12. * this source code without explicit permission.
  13. *
  14. * Unit owner : Henri Gourvest <hgourvest@gmail.com>
  15. * Web site : http://www.progdigy.com
  16. *
  17. * This unit is inspired from the json c lib:
  18. * Michael Clark <michael@metaparadigm.com>
  19. * http://oss.metaparadigm.com/json-c/
  20. *
  21. * CHANGES:
  22. * v1.2
  23. * + support of currency data type
  24. * + right trim unquoted string
  25. * + read Unicode Files and streams (Litle Endian with BOM)
  26. * + Fix bug on javadate functions + windows nt compatibility
  27. * + Now you can force to parse only the canonical syntax of JSON using the stric parameter
  28. * + Delphi 2010 RTTI marshalling
  29. * v1.1
  30. * + Double licence MPL or LGPL.
  31. * + Delphi 2009 compatibility & Unicode support.
  32. * + AsString return a string instead of PChar.
  33. * + Escaped and Unascaped JSON serialiser.
  34. * + Missed FormFeed added \f
  35. * - Removed @ trick, uses forcepath() method instead.
  36. * + Fixed parse error with uppercase E symbol in numbers.
  37. * + Fixed possible buffer overflow when enlarging array.
  38. * + Added "delete", "pack", "insert" methods for arrays and/or objects
  39. * + Multi parametters when calling methods
  40. * + Delphi Enumerator (for obj1 in obj2 do ...)
  41. * + Format method ex: obj.format('<%name%>%tab[1]%</%name%>')
  42. * + ParseFile and ParseStream methods
  43. * + Parser now understand hexdecimal c syntax ex: \xFF
  44. * + Null Object Design Patern (ex: for obj in values.N['path'] do ...)
  45. * v1.0
  46. * + renamed class
  47. * + interfaced object
  48. * + added a new data type: the method
  49. * + parser can now evaluate properties and call methods
  50. * - removed obselet rpc class
  51. * - removed "find" method, now you can use "parse" method instead
  52. * v0.6
  53. * + refactoring
  54. * v0.5
  55. * + new find method to get or set value using a path syntax
  56. * ex: obj.s['obj.prop[1]'] := 'string value';
  57. * obj.a['@obj.array'].b[n] := true; // @ -> create property if necessary
  58. * v0.4
  59. * + bug corrected: AVL tree badly balanced.
  60. * v0.3
  61. * + New validator partially based on the Kwalify syntax.
  62. * + extended syntax to parse unquoted fields.
  63. * + Freepascal compatibility win32/64 Linux32/64.
  64. * + JavaToDelphiDateTime and DelphiToJavaDateTime improved for UTC.
  65. * + new TJsonObject.Compare function.
  66. * v0.2
  67. * + Hashed string list replaced with a faster AVL tree
  68. * + JsonInt data type can be changed to int64
  69. * + JavaToDelphiDateTime and DelphiToJavaDateTime helper fonctions
  70. * + from json-c v0.7
  71. * + Add escaping of backslash to json output
  72. * + Add escaping of foward slash on tokenizing and output
  73. * + Changes to internal tokenizer from using recursion to
  74. * using a depth state structure to allow incremental parsing
  75. * v0.1
  76. * + first release
  77. *)
  78. {$IFDEF FPC}
  79. {$MODE OBJFPC}{$H+}
  80. {$ENDIF}
  81. {$DEFINE SUPER_METHOD}
  82. {$DEFINE WINDOWSNT_COMPATIBILITY}
  83. {.$DEFINE DEBUG} // track memory leack
  84. {$if defined(FPC) or defined(VER170) or defined(VER180) or defined(VER190) or defined(VER200) or defined(VER210)}
  85. {$DEFINE HAVE_INLINE}
  86. {$ifend}
  87. {$if defined(VER210) or defined(VER220) or defined(VER230)}
  88. {$define HAVE_RTTI}
  89. {$ifend}
  90. {$if defined(VER230)}
  91. {$define NEED_FORMATSETTINGS}
  92. {$ifend}
  93. {$if defined(FPC) and defined(VER2_6)}
  94. {$define NEED_FORMATSETTINGS}
  95. {$ifend}
  96. {$OVERFLOWCHECKS OFF}
  97. {$RANGECHECKS OFF}
  98. unit superobject;
  99. {$if CompilerVersion>= 23}
  100. {$define NEED_FORMATSETTINGS}
  101. {$ifend}
  102. interface
  103. uses
  104. Classes
  105. {$IFDEF HAVE_RTTI}
  106. ,Generics.Collections, RTTI, TypInfo
  107. {$ENDIF}
  108. ;
  109. type
  110. {$IFNDEF FPC}
  111. {$IFDEF CPUX64}
  112. PtrInt = Int64;
  113. PtrUInt = UInt64;
  114. {$ELSE}
  115. PtrInt = longint;
  116. PtrUInt = Longword;
  117. {$ENDIF}
  118. {$ENDIF}
  119. SuperInt = Int64;
  120. {$if (sizeof(Char) = 1)}
  121. SOChar = WideChar;
  122. SOIChar = Word;
  123. PSOChar = PWideChar;
  124. {$IFDEF FPC}
  125. SOString = UnicodeString;
  126. {$ELSE}
  127. SOString = WideString;
  128. {$ENDIF}
  129. {$else}
  130. SOChar = Char;
  131. SOIChar = Word;
  132. PSOChar = PChar;
  133. SOString = string;
  134. {$ifend}
  135. const
  136. SUPER_ARRAY_LIST_DEFAULT_SIZE = 32;
  137. SUPER_TOKENER_MAX_DEPTH = 32;
  138. SUPER_AVL_MAX_DEPTH = sizeof(longint) * 8;
  139. SUPER_AVL_MASK_HIGH_BIT = not ((not longword(0)) shr 1);
  140. type
  141. // forward declarations
  142. TSuperObject = class;
  143. ISuperObject = interface;
  144. TSuperArray = class;
  145. (* AVL Tree
  146. * This is a "special" autobalanced AVL tree
  147. * It use a hash value for fast compare
  148. *)
  149. {$IFDEF SUPER_METHOD}
  150. TSuperMethod = procedure(const This, Params: ISuperObject; var Result: ISuperObject);
  151. {$ENDIF}
  152. TSuperAvlBitArray = set of 0..SUPER_AVL_MAX_DEPTH - 1;
  153. TSuperAvlSearchType = (stEQual, stLess, stGreater);
  154. TSuperAvlSearchTypes = set of TSuperAvlSearchType;
  155. TSuperAvlIterator = class;
  156. TSuperAvlEntry = class
  157. private
  158. FGt, FLt: TSuperAvlEntry;
  159. FBf: integer;
  160. FHash: Cardinal;
  161. FName: SOString;
  162. FPtr: Pointer;
  163. function GetValue: ISuperObject;
  164. procedure SetValue(const val: ISuperObject);
  165. public
  166. class function Hash(const k: SOString): Cardinal; virtual;
  167. constructor Create(const AName: SOString; Obj: Pointer); virtual;
  168. property Name: SOString read FName;
  169. property Ptr: Pointer read FPtr;
  170. property Value: ISuperObject read GetValue write SetValue;
  171. end;
  172. TSuperAvlTree = class
  173. private
  174. FRoot: TSuperAvlEntry;
  175. FCount: Integer;
  176. function balance(bal: TSuperAvlEntry): TSuperAvlEntry;
  177. protected
  178. procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); virtual;
  179. function CompareNodeNode(node1, node2: TSuperAvlEntry): integer; virtual;
  180. function CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer; virtual;
  181. function Insert(h: TSuperAvlEntry): TSuperAvlEntry; virtual;
  182. function Search(const k: SOString; st: TSuperAvlSearchTypes = [stEqual]): TSuperAvlEntry; virtual;
  183. public
  184. constructor Create; virtual;
  185. destructor Destroy; override;
  186. function IsEmpty: boolean;
  187. procedure Clear(all: boolean = false); virtual;
  188. procedure Pack(all: boolean);
  189. function Delete(const k: SOString): ISuperObject;
  190. function GetEnumerator: TSuperAvlIterator;
  191. property count: Integer read FCount;
  192. end;
  193. TSuperTableString = class(TSuperAvlTree)
  194. protected
  195. procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); override;
  196. procedure PutO(const k: SOString; const value: ISuperObject);
  197. function GetO(const k: SOString): ISuperObject;
  198. procedure PutS(const k: SOString; const value: SOString);
  199. function GetS(const k: SOString): SOString;
  200. procedure PutI(const k: SOString; value: SuperInt);
  201. function GetI(const k: SOString): SuperInt;
  202. procedure PutD(const k: SOString; value: Double);
  203. function GetD(const k: SOString): Double;
  204. procedure PutB(const k: SOString; value: Boolean);
  205. function GetB(const k: SOString): Boolean;
  206. {$IFDEF SUPER_METHOD}
  207. procedure PutM(const k: SOString; value: TSuperMethod);
  208. function GetM(const k: SOString): TSuperMethod;
  209. {$ENDIF}
  210. procedure PutN(const k: SOString; const value: ISuperObject);
  211. function GetN(const k: SOString): ISuperObject;
  212. procedure PutC(const k: SOString; value: Currency);
  213. function GetC(const k: SOString): Currency;
  214. public
  215. property O[const k: SOString]: ISuperObject read GetO write PutO; default;
  216. property S[const k: SOString]: SOString read GetS write PutS;
  217. property I[const k: SOString]: SuperInt read GetI write PutI;
  218. property D[const k: SOString]: Double read GetD write PutD;
  219. property B[const k: SOString]: Boolean read GetB write PutB;
  220. {$IFDEF SUPER_METHOD}
  221. property M[const k: SOString]: TSuperMethod read GetM write PutM;
  222. {$ENDIF}
  223. property N[const k: SOString]: ISuperObject read GetN write PutN;
  224. property C[const k: SOString]: Currency read GetC write PutC;
  225. function GetValues: ISuperObject;
  226. function GetNames: ISuperObject;
  227. function Find(const k: SOString; var value: ISuperObject): Boolean;
  228. function Exists(const k: SOString): Boolean;
  229. end;
  230. TSuperAvlIterator = class
  231. private
  232. FTree: TSuperAvlTree;
  233. FBranch: TSuperAvlBitArray;
  234. FDepth: LongInt;
  235. FPath: array[0..SUPER_AVL_MAX_DEPTH - 2] of TSuperAvlEntry;
  236. public
  237. constructor Create(tree: TSuperAvlTree); virtual;
  238. procedure Search(const k: SOString; st: TSuperAvlSearchTypes = [stEQual]);
  239. procedure First;
  240. procedure Last;
  241. function GetIter: TSuperAvlEntry;
  242. procedure Next;
  243. procedure Prior;
  244. // delphi enumerator
  245. function MoveNext: Boolean;
  246. property Current: TSuperAvlEntry read GetIter;
  247. end;
  248. TSuperObjectArray = array[0..(high(Integer) div sizeof(TSuperObject))-1] of ISuperObject;
  249. PSuperObjectArray = ^TSuperObjectArray;
  250. TSuperArray = class
  251. private
  252. FArray: PSuperObjectArray;
  253. FLength: Integer;
  254. FSize: Integer;
  255. procedure Expand(max: Integer);
  256. protected
  257. function GetO(const index: integer): ISuperObject;
  258. procedure PutO(const index: integer; const Value: ISuperObject);
  259. function GetB(const index: integer): Boolean;
  260. procedure PutB(const index: integer; Value: Boolean);
  261. function GetI(const index: integer): SuperInt;
  262. procedure PutI(const index: integer; Value: SuperInt);
  263. function GetD(const index: integer): Double;
  264. procedure PutD(const index: integer; Value: Double);
  265. function GetC(const index: integer): Currency;
  266. procedure PutC(const index: integer; Value: Currency);
  267. function GetS(const index: integer): SOString;
  268. procedure PutS(const index: integer; const Value: SOString);
  269. {$IFDEF SUPER_METHOD}
  270. function GetM(const index: integer): TSuperMethod;
  271. procedure PutM(const index: integer; Value: TSuperMethod);
  272. {$ENDIF}
  273. function GetN(const index: integer): ISuperObject;
  274. procedure PutN(const index: integer; const Value: ISuperObject);
  275. public
  276. constructor Create; virtual;
  277. destructor Destroy; override;
  278. function Add(const Data: ISuperObject): Integer; overload;
  279. function Add(Data: SuperInt): Integer; overload;
  280. function Add(const Data: SOString): Integer; overload;
  281. function Add(Data: Boolean): Integer; overload;
  282. function Add(Data: Double): Integer; overload;
  283. function AddC(const Data: Currency): Integer;
  284. function Delete(index: Integer): ISuperObject;
  285. procedure Insert(index: Integer; const value: ISuperObject);
  286. procedure Clear(all: boolean = false);
  287. procedure Pack(all: boolean);
  288. property Length: Integer read FLength;
  289. property N[const index: integer]: ISuperObject read GetN write PutN;
  290. property O[const index: integer]: ISuperObject read GetO write PutO; default;
  291. property B[const index: integer]: boolean read GetB write PutB;
  292. property I[const index: integer]: SuperInt read GetI write PutI;
  293. property D[const index: integer]: Double read GetD write PutD;
  294. property C[const index: integer]: Currency read GetC write PutC;
  295. property S[const index: integer]: SOString read GetS write PutS;
  296. {$IFDEF SUPER_METHOD}
  297. property M[const index: integer]: TSuperMethod read GetM write PutM;
  298. {$ENDIF}
  299. end;
  300. TSuperWriter = class
  301. public
  302. // abstact methods to overide
  303. function Append(buf: PSOChar; Size: Integer): Integer; overload; virtual; abstract;
  304. function Append(buf: PSOChar): Integer; overload; virtual; abstract;
  305. procedure Reset; virtual; abstract;
  306. end;
  307. TSuperWriterString = class(TSuperWriter)
  308. private
  309. FBuf: PSOChar;
  310. FBPos: integer;
  311. FSize: integer;
  312. public
  313. function Append(buf: PSOChar; Size: Integer): Integer; overload; override;
  314. function Append(buf: PSOChar): Integer; overload; override;
  315. procedure Reset; override;
  316. procedure TrimRight;
  317. constructor Create; virtual;
  318. destructor Destroy; override;
  319. function GetString: SOString;
  320. property Data: PSOChar read FBuf;
  321. property Size: Integer read FSize;
  322. property Position: integer read FBPos;
  323. end;
  324. TSuperWriterStream = class(TSuperWriter)
  325. private
  326. FStream: TStream;
  327. public
  328. function Append(buf: PSOChar): Integer; override;
  329. procedure Reset; override;
  330. constructor Create(AStream: TStream); reintroduce; virtual;
  331. end;
  332. TSuperAnsiWriterStream = class(TSuperWriterStream)
  333. public
  334. function Append(buf: PSOChar; Size: Integer): Integer; override;
  335. end;
  336. TSuperUnicodeWriterStream = class(TSuperWriterStream)
  337. public
  338. function Append(buf: PSOChar; Size: Integer): Integer; override;
  339. end;
  340. TSuperWriterFake = class(TSuperWriter)
  341. private
  342. FSize: Integer;
  343. public
  344. function Append(buf: PSOChar; Size: Integer): Integer; override;
  345. function Append(buf: PSOChar): Integer; override;
  346. procedure Reset; override;
  347. constructor Create; reintroduce; virtual;
  348. property size: integer read FSize;
  349. end;
  350. TSuperWriterSock = class(TSuperWriter)
  351. private
  352. FSocket: longint;
  353. FSize: Integer;
  354. public
  355. function Append(buf: PSOChar; Size: Integer): Integer; override;
  356. function Append(buf: PSOChar): Integer; override;
  357. procedure Reset; override;
  358. constructor Create(ASocket: longint); reintroduce; virtual;
  359. property Socket: longint read FSocket;
  360. property Size: Integer read FSize;
  361. end;
  362. TSuperTokenizerError = (
  363. teSuccess,
  364. teContinue,
  365. teDepth,
  366. teParseEof,
  367. teParseUnexpected,
  368. teParseNull,
  369. teParseBoolean,
  370. teParseNumber,
  371. teParseArray,
  372. teParseObjectKeyName,
  373. teParseObjectKeySep,
  374. teParseObjectValueSep,
  375. teParseString,
  376. teParseComment,
  377. teEvalObject,
  378. teEvalArray,
  379. teEvalMethod,
  380. teEvalInt
  381. );
  382. TSuperTokenerState = (
  383. tsEatws,
  384. tsStart,
  385. tsFinish,
  386. tsNull,
  387. tsCommentStart,
  388. tsComment,
  389. tsCommentEol,
  390. tsCommentEnd,
  391. tsString,
  392. tsStringEscape,
  393. tsIdentifier,
  394. tsEscapeUnicode,
  395. tsEscapeHexadecimal,
  396. tsBoolean,
  397. tsNumber,
  398. tsArray,
  399. tsArrayAdd,
  400. tsArraySep,
  401. tsObjectFieldStart,
  402. tsObjectField,
  403. tsObjectUnquotedField,
  404. tsObjectFieldEnd,
  405. tsObjectValue,
  406. tsObjectValueAdd,
  407. tsObjectSep,
  408. tsEvalProperty,
  409. tsEvalArray,
  410. tsEvalMethod,
  411. tsParamValue,
  412. tsParamPut,
  413. tsMethodValue,
  414. tsMethodPut
  415. );
  416. PSuperTokenerSrec = ^TSuperTokenerSrec;
  417. TSuperTokenerSrec = record
  418. state, saved_state: TSuperTokenerState;
  419. obj: ISuperObject;
  420. current: ISuperObject;
  421. field_name: SOString;
  422. parent: ISuperObject;
  423. gparent: ISuperObject;
  424. end;
  425. TSuperTokenizer = class
  426. public
  427. str: PSOChar;
  428. pb: TSuperWriterString;
  429. depth, is_double, floatcount, st_pos, char_offset: Integer;
  430. err: TSuperTokenizerError;
  431. ucs_char: Word;
  432. quote_char: SOChar;
  433. stack: array[0..SUPER_TOKENER_MAX_DEPTH-1] of TSuperTokenerSrec;
  434. line, col: Integer;
  435. public
  436. constructor Create; virtual;
  437. destructor Destroy; override;
  438. procedure ResetLevel(adepth: integer);
  439. procedure Reset;
  440. end;
  441. // supported object types
  442. TSuperType = (
  443. stNull,
  444. stBoolean,
  445. stDouble,
  446. stCurrency,
  447. stInt,
  448. stObject,
  449. stArray,
  450. stString
  451. {$IFDEF SUPER_METHOD}
  452. ,stMethod
  453. {$ENDIF}
  454. );
  455. TSuperValidateError = (
  456. veRuleMalformated,
  457. veFieldIsRequired,
  458. veInvalidDataType,
  459. veFieldNotFound,
  460. veUnexpectedField,
  461. veDuplicateEntry,
  462. veValueNotInEnum,
  463. veInvalidLength,
  464. veInvalidRange
  465. );
  466. TSuperFindOption = (
  467. foCreatePath,
  468. foPutValue,
  469. foDelete
  470. {$IFDEF SUPER_METHOD}
  471. ,foCallMethod
  472. {$ENDIF}
  473. );
  474. TSuperFindOptions = set of TSuperFindOption;
  475. TSuperCompareResult = (cpLess, cpEqu, cpGreat, cpError);
  476. TSuperOnValidateError = procedure(sender: Pointer; error: TSuperValidateError; const objpath: SOString);
  477. TSuperEnumerator = class
  478. private
  479. FObj: ISuperObject;
  480. FObjEnum: TSuperAvlIterator;
  481. FCount: Integer;
  482. public
  483. constructor Create(const obj: ISuperObject); virtual;
  484. destructor Destroy; override;
  485. function MoveNext: Boolean;
  486. function GetCurrent: ISuperObject;
  487. property Current: ISuperObject read GetCurrent;
  488. end;
  489. ISuperObject = interface
  490. ['{4B86A9E3-E094-4E5A-954A-69048B7B6327}']
  491. function GetEnumerator: TSuperEnumerator;
  492. function GetDataType: TSuperType;
  493. function GetProcessing: boolean;
  494. procedure SetProcessing(value: boolean);
  495. function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  496. function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;
  497. function GetO(const path: SOString): ISuperObject;
  498. procedure PutO(const path: SOString; const Value: ISuperObject);
  499. function GetB(const path: SOString): Boolean;
  500. procedure PutB(const path: SOString; Value: Boolean);
  501. function GetI(const path: SOString): SuperInt;
  502. procedure PutI(const path: SOString; Value: SuperInt);
  503. function GetD(const path: SOString): Double;
  504. procedure PutC(const path: SOString; Value: Currency);
  505. function GetC(const path: SOString): Currency;
  506. procedure PutD(const path: SOString; Value: Double);
  507. function GetS(const path: SOString): SOString;
  508. procedure PutS(const path: SOString; const Value: SOString);
  509. {$IFDEF SUPER_METHOD}
  510. function GetM(const path: SOString): TSuperMethod;
  511. procedure PutM(const path: SOString; Value: TSuperMethod);
  512. {$ENDIF}
  513. function GetA(const path: SOString): TSuperArray;
  514. // Null Object Design patern
  515. function GetN(const path: SOString): ISuperObject;
  516. procedure PutN(const path: SOString; const Value: ISuperObject);
  517. // Writers
  518. function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;
  519. function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;
  520. function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;
  521. function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;
  522. function CalcSize(indent: boolean = false; escape: boolean = true): integer;
  523. // convert
  524. function AsBoolean: Boolean;
  525. function AsInteger: SuperInt;
  526. function AsDouble: Double;
  527. function AsCurrency: Currency;
  528. function AsString: SOString;
  529. function AsArray: TSuperArray;
  530. function AsObject: TSuperTableString;
  531. {$IFDEF SUPER_METHOD}
  532. function AsMethod: TSuperMethod;
  533. {$ENDIF}
  534. function AsJSon(indent: boolean = false; escape: boolean = true): SOString;
  535. procedure Clear(all: boolean = false);
  536. procedure Pack(all: boolean = false);
  537. property N[const path: SOString]: ISuperObject read GetN write PutN;
  538. property O[const path: SOString]: ISuperObject read GetO write PutO; default;
  539. property B[const path: SOString]: boolean read GetB write PutB;
  540. property I[const path: SOString]: SuperInt read GetI write PutI;
  541. property D[const path: SOString]: Double read GetD write PutD;
  542. property C[const path: SOString]: Currency read GetC write PutC;
  543. property S[const path: SOString]: SOString read GetS write PutS;
  544. {$IFDEF SUPER_METHOD}
  545. property M[const path: SOString]: TSuperMethod read GetM write PutM;
  546. {$ENDIF}
  547. property A[const path: SOString]: TSuperArray read GetA;
  548. {$IFDEF SUPER_METHOD}
  549. function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload;
  550. function call(const path, param: SOString): ISuperObject; overload;
  551. {$ENDIF}
  552. // clone a node
  553. function Clone: ISuperObject;
  554. function Delete(const path: SOString): ISuperObject;
  555. // merges tow objects of same type, if reference is true then nodes are not cloned
  556. procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;
  557. procedure Merge(const str: SOString); overload;
  558. // validate methods
  559. function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  560. function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  561. // compare
  562. function Compare(const obj: ISuperObject): TSuperCompareResult; overload;
  563. function Compare(const str: SOString): TSuperCompareResult; overload;
  564. // the data type
  565. function IsType(AType: TSuperType): boolean;
  566. property DataType: TSuperType read GetDataType;
  567. property Processing: boolean read GetProcessing write SetProcessing;
  568. function GetDataPtr: Pointer;
  569. procedure SetDataPtr(const Value: Pointer);
  570. property DataPtr: Pointer read GetDataPtr write SetDataPtr;
  571. end;
  572. TSuperObject = class(TObject, ISuperObject)
  573. private
  574. FRefCount: Integer;
  575. FProcessing: boolean;
  576. FDataType: TSuperType;
  577. FDataPtr: Pointer;
  578. {.$if true}
  579. FO: record
  580. case TSuperType of
  581. stBoolean: (c_boolean: boolean);
  582. stDouble: (c_double: double);
  583. stCurrency: (c_currency: Currency);
  584. stInt: (c_int: SuperInt);
  585. stObject: (c_object: TSuperTableString);
  586. stArray: (c_array: TSuperArray);
  587. {$IFDEF SUPER_METHOD}
  588. stMethod: (c_method: TSuperMethod);
  589. {$ENDIF}
  590. end;
  591. {.$ifend}
  592. FOString: SOString;
  593. function GetDataType: TSuperType;
  594. function GetDataPtr: Pointer;
  595. procedure SetDataPtr(const Value: Pointer);
  596. protected
  597. {$IFDEF FPC}
  598. function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: tguid; out obj): longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  599. {$ELSE}
  600. function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
  601. {$ENDIF}
  602. function _AddRef: Integer; virtual; stdcall;
  603. function _Release: Integer; virtual; stdcall;
  604. function GetO(const path: SOString): ISuperObject;
  605. procedure PutO(const path: SOString; const Value: ISuperObject);
  606. function GetB(const path: SOString): Boolean;
  607. procedure PutB(const path: SOString; Value: Boolean);
  608. function GetI(const path: SOString): SuperInt;
  609. procedure PutI(const path: SOString; Value: SuperInt);
  610. function GetD(const path: SOString): Double;
  611. procedure PutD(const path: SOString; Value: Double);
  612. procedure PutC(const path: SOString; Value: Currency);
  613. function GetC(const path: SOString): Currency;
  614. function GetS(const path: SOString): SOString;
  615. procedure PutS(const path: SOString; const Value: SOString);
  616. {$IFDEF SUPER_METHOD}
  617. function GetM(const path: SOString): TSuperMethod;
  618. procedure PutM(const path: SOString; Value: TSuperMethod);
  619. {$ENDIF}
  620. function GetA(const path: SOString): TSuperArray;
  621. function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; virtual;
  622. public
  623. function GetEnumerator: TSuperEnumerator;
  624. procedure AfterConstruction; override;
  625. procedure BeforeDestruction; override;
  626. class function NewInstance: TObject; override;
  627. property RefCount: Integer read FRefCount;
  628. function GetProcessing: boolean;
  629. procedure SetProcessing(value: boolean);
  630. // Writers
  631. function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;
  632. function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;
  633. function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;
  634. function CalcSize(indent: boolean = false; escape: boolean = true): integer;
  635. function AsJSon(indent: boolean = false; escape: boolean = true): SOString;
  636. // parser ... owned!
  637. class function ParseString(s: PSOChar; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  638. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  639. class function ParseStream(stream: TStream; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  640. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  641. class function ParseFile(const FileName: string; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  642. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  643. class function ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer; strict: Boolean; const this: ISuperObject = nil;
  644. options: TSuperFindOptions = []; const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  645. // constructors / destructor
  646. constructor Create(jt: TSuperType = stObject); overload; virtual;
  647. constructor Create(b: boolean); overload; virtual;
  648. constructor Create(i: SuperInt); overload; virtual;
  649. constructor Create(d: double); overload; virtual;
  650. constructor CreateCurrency(c: Currency); overload; virtual;
  651. constructor Create(const s: SOString); overload; virtual;
  652. {$IFDEF SUPER_METHOD}
  653. constructor Create(m: TSuperMethod); overload; virtual;
  654. {$ENDIF}
  655. destructor Destroy; override;
  656. // convert
  657. function AsBoolean: Boolean; virtual;
  658. function AsInteger: SuperInt; virtual;
  659. function AsDouble: Double; virtual;
  660. function AsCurrency: Currency; virtual;
  661. function AsString: SOString; virtual;
  662. function AsArray: TSuperArray; virtual;
  663. function AsObject: TSuperTableString; virtual;
  664. {$IFDEF SUPER_METHOD}
  665. function AsMethod: TSuperMethod; virtual;
  666. {$ENDIF}
  667. procedure Clear(all: boolean = false); virtual;
  668. procedure Pack(all: boolean = false); virtual;
  669. function GetN(const path: SOString): ISuperObject;
  670. procedure PutN(const path: SOString; const Value: ISuperObject);
  671. function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  672. function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;
  673. property N[const path: SOString]: ISuperObject read GetN write PutN;
  674. property O[const path: SOString]: ISuperObject read GetO write PutO; default;
  675. property B[const path: SOString]: boolean read GetB write PutB;
  676. property I[const path: SOString]: SuperInt read GetI write PutI;
  677. property D[const path: SOString]: Double read GetD write PutD;
  678. property C[const path: SOString]: Currency read GetC write PutC;
  679. property S[const path: SOString]: SOString read GetS write PutS;
  680. {$IFDEF SUPER_METHOD}
  681. property M[const path: SOString]: TSuperMethod read GetM write PutM;
  682. {$ENDIF}
  683. property A[const path: SOString]: TSuperArray read GetA;
  684. {$IFDEF SUPER_METHOD}
  685. function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload; virtual;
  686. function call(const path, param: SOString): ISuperObject; overload; virtual;
  687. {$ENDIF}
  688. // clone a node
  689. function Clone: ISuperObject; virtual;
  690. function Delete(const path: SOString): ISuperObject;
  691. // merges tow objects of same type, if reference is true then nodes are not cloned
  692. procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;
  693. procedure Merge(const str: SOString); overload;
  694. // validate methods
  695. function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  696. function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  697. // compare
  698. function Compare(const obj: ISuperObject): TSuperCompareResult; overload;
  699. function Compare(const str: SOString): TSuperCompareResult; overload;
  700. // the data type
  701. function IsType(AType: TSuperType): boolean;
  702. property DataType: TSuperType read GetDataType;
  703. // a data pointer to link to something ele, a treeview for example
  704. property DataPtr: Pointer read GetDataPtr write SetDataPtr;
  705. property Processing: boolean read GetProcessing;
  706. end;
  707. {$IFDEF HAVE_RTTI}
  708. TSuperRttiContext = class;
  709. TSerialFromJson = function(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  710. TSerialToJson = function(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  711. TSuperAttribute = class(TCustomAttribute)
  712. private
  713. FName: string;
  714. public
  715. constructor Create(const AName: string);
  716. property Name: string read FName;
  717. end;
  718. SOName = class(TSuperAttribute);
  719. SODefault = class(TSuperAttribute);
  720. TSuperRttiContext = class
  721. private
  722. class function GetFieldName(r: TRttiField): string;
  723. class function GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;
  724. public
  725. Context: TRttiContext;
  726. SerialFromJson: TDictionary<PTypeInfo, TSerialFromJson>;
  727. SerialToJson: TDictionary<PTypeInfo, TSerialToJson>;
  728. constructor Create; virtual;
  729. destructor Destroy; override;
  730. function FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject; var Value: TValue): Boolean; virtual;
  731. function ToJson(var value: TValue; const index: ISuperObject): ISuperObject; virtual;
  732. function AsType<T>(const obj: ISuperObject): T;
  733. function AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;
  734. end;
  735. TSuperObjectHelper = class helper for TObject
  736. public
  737. function ToJson(ctx: TSuperRttiContext = nil): ISuperObject;
  738. constructor FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil); overload;
  739. constructor FromJson(const str: string; ctx: TSuperRttiContext = nil); overload;
  740. end;
  741. {$ENDIF}
  742. TSuperObjectIter = record
  743. key: SOString;
  744. val: ISuperObject;
  745. Ite: TSuperAvlIterator;
  746. end;
  747. function ObjectIsError(obj: TSuperObject): boolean;
  748. function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;
  749. function ObjectGetType(const obj: ISuperObject): TSuperType;
  750. function ObjectIsNull(const obj: ISuperObject): Boolean;
  751. function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;
  752. function ObjectFindNext(var F: TSuperObjectIter): boolean;
  753. procedure ObjectFindClose(var F: TSuperObjectIter);
  754. function SO(const s: SOString = '{}'): ISuperObject; overload;
  755. function SO(const value: Variant): ISuperObject; overload;
  756. function SO(const Args: array of const): ISuperObject; overload;
  757. function SA(const Args: array of const): ISuperObject; overload;
  758. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  759. function DelphiToJavaDateTime(const dt: TDateTime): int64;
  760. function TryObjectToDate(const obj: ISuperObject; var dt: TDateTime): Boolean;
  761. function ISO8601DateToJavaDateTime(const str: SOString; var ms: Int64): Boolean;
  762. function ISO8601DateToDelphiDateTime(const str: SOString; var dt: TDateTime): Boolean;
  763. function DelphiDateTimeToISO8601Date(dt: TDateTime): SOString;
  764. function UUIDToString(const g: TGUID): SOString;
  765. function StringToUUID(const str: SOString; var g: TGUID): Boolean;
  766. {$IFDEF HAVE_RTTI}
  767. type
  768. TSuperInvokeResult = (
  769. irSuccess,
  770. irMethothodError, // method don't exist
  771. irParamError, // invalid parametters
  772. irError // other error
  773. );
  774. function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue; const method: string; const params: ISuperObject; var Return: ISuperObject): TSuperInvokeResult; overload;
  775. function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext = nil): ISuperObject; overload;
  776. function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext = nil): ISuperObject; overload;
  777. {$ENDIF}
  778. implementation
  779. uses sysutils,
  780. {$IFDEF UNIX}
  781. baseunix, unix, DateUtils
  782. {$ELSE}
  783. Windows
  784. {$ENDIF}
  785. {$IFDEF FPC}
  786. ,sockets
  787. {$ELSE}
  788. ,WinSock
  789. {$ENDIF};
  790. {$IFDEF DEBUG}
  791. var
  792. debugcount: integer = 0;
  793. {$ENDIF}
  794. const
  795. super_number_chars_set = ['0'..'9','.','+','-','e','E'];
  796. super_hex_chars: PSOChar = '0123456789abcdef';
  797. super_hex_chars_set = ['0'..'9','a'..'f','A'..'F'];
  798. ESC_BS: PSOChar = '\b';
  799. ESC_LF: PSOChar = '\n';
  800. ESC_CR: PSOChar = '\r';
  801. ESC_TAB: PSOChar = '\t';
  802. ESC_FF: PSOChar = '\f';
  803. ESC_QUOT: PSOChar = '\"';
  804. ESC_SL: PSOChar = '\\';
  805. ESC_SR: PSOChar = '\/';
  806. ESC_ZERO: PSOChar = '\u0000';
  807. TOK_CRLF: PSOChar = #13#10;
  808. TOK_SP: PSOChar = #32;
  809. TOK_BS: PSOChar = #8;
  810. TOK_TAB: PSOChar = #9;
  811. TOK_LF: PSOChar = #10;
  812. TOK_FF: PSOChar = #12;
  813. TOK_CR: PSOChar = #13;
  814. // TOK_SL: PSOChar = '\';
  815. // TOK_SR: PSOChar = '/';
  816. TOK_NULL: PSOChar = 'null';
  817. TOK_CBL: PSOChar = '{'; // curly bracket left
  818. TOK_CBR: PSOChar = '}'; // curly bracket right
  819. TOK_ARL: PSOChar = '[';
  820. TOK_ARR: PSOChar = ']';
  821. TOK_ARRAY: PSOChar = '[]';
  822. TOK_OBJ: PSOChar = '{}'; // empty object
  823. TOK_COM: PSOChar = ','; // Comma
  824. TOK_DQT: PSOChar = '"'; // Double Quote
  825. TOK_TRUE: PSOChar = 'true';
  826. TOK_FALSE: PSOChar = 'false';
  827. {$if (sizeof(Char) = 1)}
  828. function StrLComp(const Str1, Str2: PSOChar; MaxLen: Cardinal): Integer;
  829. var
  830. P1, P2: PWideChar;
  831. I: Cardinal;
  832. C1, C2: WideChar;
  833. begin
  834. P1 := Str1;
  835. P2 := Str2;
  836. I := 0;
  837. while I < MaxLen do
  838. begin
  839. C1 := P1^;
  840. C2 := P2^;
  841. if (C1 <> C2) or (C1 = #0) then
  842. begin
  843. Result := Ord(C1) - Ord(C2);
  844. Exit;
  845. end;
  846. Inc(P1);
  847. Inc(P2);
  848. Inc(I);
  849. end;
  850. Result := 0;
  851. end;
  852. function StrComp(const Str1, Str2: PSOChar): Integer;
  853. var
  854. P1, P2: PWideChar;
  855. C1, C2: WideChar;
  856. begin
  857. P1 := Str1;
  858. P2 := Str2;
  859. while True do
  860. begin
  861. C1 := P1^;
  862. C2 := P2^;
  863. if (C1 <> C2) or (C1 = #0) then
  864. begin
  865. Result := Ord(C1) - Ord(C2);
  866. Exit;
  867. end;
  868. Inc(P1);
  869. Inc(P2);
  870. end;
  871. end;
  872. function StrLen(const Str: PSOChar): Cardinal;
  873. var
  874. p: PSOChar;
  875. begin
  876. Result := 0;
  877. if Str <> nil then
  878. begin
  879. p := Str;
  880. while p^ <> #0 do inc(p);
  881. Result := (p - Str);
  882. end;
  883. end;
  884. {$ifend}
  885. function FloatToJson(const value: Double): SOString;
  886. var
  887. p: PSOChar;
  888. begin
  889. Result := FloatToStr(value);
  890. if {$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator <> '.' then
  891. begin
  892. p := PSOChar(Result);
  893. while p^ <> #0 do
  894. if p^ <> SOChar({$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator) then
  895. inc(p) else
  896. begin
  897. p^ := '.';
  898. Exit;
  899. end;
  900. end;
  901. end;
  902. function CurrToJson(const value: Currency): SOString;
  903. var
  904. p: PSOChar;
  905. begin
  906. Result := CurrToStr(value);
  907. if {$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator <> '.' then
  908. begin
  909. p := PSOChar(Result);
  910. while p^ <> #0 do
  911. if p^ <> SOChar({$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator) then
  912. inc(p) else
  913. begin
  914. p^ := '.';
  915. Exit;
  916. end;
  917. end;
  918. end;
  919. {$IFDEF UNIX}
  920. function GetTimeBias: integer;
  921. var
  922. TimeVal: TTimeVal;
  923. TimeZone: TTimeZone;
  924. begin
  925. fpGetTimeOfDay(@TimeVal, @TimeZone);
  926. Result := TimeZone.tz_minuteswest;
  927. end;
  928. {$ELSE}
  929. function GetTimeBias: integer;
  930. var
  931. tzi : TTimeZoneInformation;
  932. begin
  933. case GetTimeZoneInformation(tzi) of
  934. TIME_ZONE_ID_UNKNOWN : Result := tzi.Bias;
  935. TIME_ZONE_ID_STANDARD: Result := tzi.Bias + tzi.StandardBias;
  936. TIME_ZONE_ID_DAYLIGHT: Result := tzi.Bias + tzi.DaylightBias;
  937. else
  938. Result := 0;
  939. end;
  940. end;
  941. {$ENDIF}
  942. {$IFDEF UNIX}
  943. type
  944. ptm = ^tm;
  945. tm = record
  946. tm_sec: Integer; (* Seconds: 0-59 (K&R says 0-61?) *)
  947. tm_min: Integer; (* Minutes: 0-59 *)
  948. tm_hour: Integer; (* Hours since midnight: 0-23 *)
  949. tm_mday: Integer; (* Day of the month: 1-31 *)
  950. tm_mon: Integer; (* Months *since* january: 0-11 *)
  951. tm_year: Integer; (* Years since 1900 *)
  952. tm_wday: Integer; (* Days since Sunday (0-6) *)
  953. tm_yday: Integer; (* Days since Jan. 1: 0-365 *)
  954. tm_isdst: Integer; (* +1 Daylight Savings Time, 0 No DST, -1 don't know *)
  955. end;
  956. function mktime(p: ptm): LongInt; cdecl; external;
  957. function gmtime(const t: PLongint): ptm; cdecl; external;
  958. function localtime (const t: PLongint): ptm; cdecl; external;
  959. function DelphiToJavaDateTime(const dt: TDateTime): Int64;
  960. var
  961. p: ptm;
  962. l, ms: Integer;
  963. v: Int64;
  964. begin
  965. v := Round((dt - 25569) * 86400000);
  966. ms := v mod 1000;
  967. l := v div 1000;
  968. p := localtime(@l);
  969. Result := Int64(mktime(p)) * 1000 + ms;
  970. end;
  971. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  972. var
  973. p: ptm;
  974. l, ms: Integer;
  975. begin
  976. l := dt div 1000;
  977. ms := dt mod 1000;
  978. p := gmtime(@l);
  979. Result := EncodeDateTime(p^.tm_year+1900, p^.tm_mon+1, p^.tm_mday, p^.tm_hour, p^.tm_min, p^.tm_sec, ms);
  980. end;
  981. {$ELSE}
  982. {$IFDEF WINDOWSNT_COMPATIBILITY}
  983. function DayLightCompareDate(const date: PSystemTime;
  984. const compareDate: PSystemTime): Integer;
  985. var
  986. limit_day, dayinsecs, weekofmonth: Integer;
  987. First: Word;
  988. begin
  989. if (date^.wMonth < compareDate^.wMonth) then
  990. begin
  991. Result := -1; (* We are in a month before the date limit. *)
  992. Exit;
  993. end;
  994. if (date^.wMonth > compareDate^.wMonth) then
  995. begin
  996. Result := 1; (* We are in a month after the date limit. *)
  997. Exit;
  998. end;
  999. (* if year is 0 then date is in day-of-week format, otherwise
  1000. * it's absolute date.
  1001. *)
  1002. if (compareDate^.wYear = 0) then
  1003. begin
  1004. (* compareDate.wDay is interpreted as number of the week in the month
  1005. * 5 means: the last week in the month *)
  1006. weekofmonth := compareDate^.wDay;
  1007. (* calculate the day of the first DayOfWeek in the month *)
  1008. First := (6 + compareDate^.wDayOfWeek - date^.wDayOfWeek + date^.wDay) mod 7 + 1;
  1009. limit_day := First + 7 * (weekofmonth - 1);
  1010. (* check needed for the 5th weekday of the month *)
  1011. if (limit_day > MonthDays[(date^.wMonth=2) and IsLeapYear(date^.wYear)][date^.wMonth]) then
  1012. dec(limit_day, 7);
  1013. end
  1014. else
  1015. limit_day := compareDate^.wDay;
  1016. (* convert to seconds *)
  1017. limit_day := ((limit_day * 24 + compareDate^.wHour) * 60 + compareDate^.wMinute ) * 60;
  1018. dayinsecs := ((date^.wDay * 24 + date^.wHour) * 60 + date^.wMinute ) * 60 + date^.wSecond;
  1019. (* and compare *)
  1020. if dayinsecs < limit_day then
  1021. Result := -1 else
  1022. if dayinsecs > limit_day then
  1023. Result := 1 else
  1024. Result := 0; (* date is equal to the date limit. *)
  1025. end;
  1026. function CompTimeZoneID(const pTZinfo: PTimeZoneInformation;
  1027. lpFileTime: PFileTime; islocal: Boolean): LongWord;
  1028. var
  1029. ret: Integer;
  1030. beforeStandardDate, afterDaylightDate: Boolean;
  1031. llTime: Int64;
  1032. SysTime: TSystemTime;
  1033. ftTemp: TFileTime;
  1034. begin
  1035. llTime := 0;
  1036. if (pTZinfo^.DaylightDate.wMonth <> 0) then
  1037. begin
  1038. (* if year is 0 then date is in day-of-week format, otherwise
  1039. * it's absolute date.
  1040. *)
  1041. if ((pTZinfo^.StandardDate.wMonth = 0) or
  1042. ((pTZinfo^.StandardDate.wYear = 0) and
  1043. ((pTZinfo^.StandardDate.wDay < 1) or
  1044. (pTZinfo^.StandardDate.wDay > 5) or
  1045. (pTZinfo^.DaylightDate.wDay < 1) or
  1046. (pTZinfo^.DaylightDate.wDay > 5)))) then
  1047. begin
  1048. SetLastError(ERROR_INVALID_PARAMETER);
  1049. Result := TIME_ZONE_ID_INVALID;
  1050. Exit;
  1051. end;
  1052. if (not islocal) then
  1053. begin
  1054. llTime := PInt64(lpFileTime)^;
  1055. dec(llTime, Int64(pTZinfo^.Bias + pTZinfo^.DaylightBias) * 600000000);
  1056. PInt64(@ftTemp)^ := llTime;
  1057. lpFileTime := @ftTemp;
  1058. end;
  1059. FileTimeToSystemTime(lpFileTime^, SysTime);
  1060. (* check for daylight savings *)
  1061. ret := DayLightCompareDate(@SysTime, @pTZinfo^.StandardDate);
  1062. if (ret = -2) then
  1063. begin
  1064. Result := TIME_ZONE_ID_INVALID;
  1065. Exit;
  1066. end;
  1067. beforeStandardDate := ret < 0;
  1068. if (not islocal) then
  1069. begin
  1070. dec(llTime, Int64(pTZinfo^.StandardBias - pTZinfo^.DaylightBias) * 600000000);
  1071. PInt64(@ftTemp)^ := llTime;
  1072. FileTimeToSystemTime(lpFileTime^, SysTime);
  1073. end;
  1074. ret := DayLightCompareDate(@SysTime, @pTZinfo^.DaylightDate);
  1075. if (ret = -2) then
  1076. begin
  1077. Result := TIME_ZONE_ID_INVALID;
  1078. Exit;
  1079. end;
  1080. afterDaylightDate := ret >= 0;
  1081. Result := TIME_ZONE_ID_STANDARD;
  1082. if( pTZinfo^.DaylightDate.wMonth < pTZinfo^.StandardDate.wMonth ) then
  1083. begin
  1084. (* Northern hemisphere *)
  1085. if( beforeStandardDate and afterDaylightDate) then
  1086. Result := TIME_ZONE_ID_DAYLIGHT;
  1087. end else (* Down south *)
  1088. if( beforeStandardDate or afterDaylightDate) then
  1089. Result := TIME_ZONE_ID_DAYLIGHT;
  1090. end else
  1091. (* No transition date *)
  1092. Result := TIME_ZONE_ID_UNKNOWN;
  1093. end;
  1094. function GetTimezoneBias(const pTZinfo: PTimeZoneInformation;
  1095. lpFileTime: PFileTime; islocal: Boolean; pBias: PLongint): Boolean;
  1096. var
  1097. bias: LongInt;
  1098. tzid: LongWord;
  1099. begin
  1100. bias := pTZinfo^.Bias;
  1101. tzid := CompTimeZoneID(pTZinfo, lpFileTime, islocal);
  1102. if( tzid = TIME_ZONE_ID_INVALID) then
  1103. begin
  1104. Result := False;
  1105. Exit;
  1106. end;
  1107. if (tzid = TIME_ZONE_ID_DAYLIGHT) then
  1108. inc(bias, pTZinfo^.DaylightBias)
  1109. else if (tzid = TIME_ZONE_ID_STANDARD) then
  1110. inc(bias, pTZinfo^.StandardBias);
  1111. pBias^ := bias;
  1112. Result := True;
  1113. end;
  1114. function SystemTimeToTzSpecificLocalTime(
  1115. lpTimeZoneInformation: PTimeZoneInformation;
  1116. lpUniversalTime, lpLocalTime: PSystemTime): BOOL;
  1117. var
  1118. ft: TFileTime;
  1119. lBias: LongInt;
  1120. llTime: Int64;
  1121. tzinfo: TTimeZoneInformation;
  1122. begin
  1123. if (lpTimeZoneInformation <> nil) then
  1124. tzinfo := lpTimeZoneInformation^ else
  1125. if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
  1126. begin
  1127. Result := False;
  1128. Exit;
  1129. end;
  1130. if (not SystemTimeToFileTime(lpUniversalTime^, ft)) then
  1131. begin
  1132. Result := False;
  1133. Exit;
  1134. end;
  1135. llTime := PInt64(@ft)^;
  1136. if (not GetTimezoneBias(@tzinfo, @ft, False, @lBias)) then
  1137. begin
  1138. Result := False;
  1139. Exit;
  1140. end;
  1141. (* convert minutes to 100-nanoseconds-ticks *)
  1142. dec(llTime, Int64(lBias) * 600000000);
  1143. PInt64(@ft)^ := llTime;
  1144. Result := FileTimeToSystemTime(ft, lpLocalTime^);
  1145. end;
  1146. function TzSpecificLocalTimeToSystemTime(
  1147. const lpTimeZoneInformation: PTimeZoneInformation;
  1148. const lpLocalTime: PSystemTime; lpUniversalTime: PSystemTime): BOOL;
  1149. var
  1150. ft: TFileTime;
  1151. lBias: LongInt;
  1152. t: Int64;
  1153. tzinfo: TTimeZoneInformation;
  1154. begin
  1155. if (lpTimeZoneInformation <> nil) then
  1156. tzinfo := lpTimeZoneInformation^
  1157. else
  1158. if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
  1159. begin
  1160. Result := False;
  1161. Exit;
  1162. end;
  1163. if (not SystemTimeToFileTime(lpLocalTime^, ft)) then
  1164. begin
  1165. Result := False;
  1166. Exit;
  1167. end;
  1168. t := PInt64(@ft)^;
  1169. if (not GetTimezoneBias(@tzinfo, @ft, True, @lBias)) then
  1170. begin
  1171. Result := False;
  1172. Exit;
  1173. end;
  1174. (* convert minutes to 100-nanoseconds-ticks *)
  1175. inc(t, Int64(lBias) * 600000000);
  1176. PInt64(@ft)^ := t;
  1177. Result := FileTimeToSystemTime(ft, lpUniversalTime^);
  1178. end;
  1179. {$ELSE}
  1180. function TzSpecificLocalTimeToSystemTime(
  1181. lpTimeZoneInformation: PTimeZoneInformation;
  1182. lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';
  1183. function SystemTimeToTzSpecificLocalTime(
  1184. lpTimeZoneInformation: PTimeZoneInformation;
  1185. lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';
  1186. {$ENDIF}
  1187. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  1188. var
  1189. t: TSystemTime;
  1190. begin
  1191. DateTimeToSystemTime(25569 + (dt / 86400000), t);
  1192. SystemTimeToTzSpecificLocalTime(nil, @t, @t);
  1193. Result := SystemTimeToDateTime(t);
  1194. end;
  1195. function DelphiToJavaDateTime(const dt: TDateTime): int64;
  1196. var
  1197. t: TSystemTime;
  1198. begin
  1199. DateTimeToSystemTime(dt, t);
  1200. TzSpecificLocalTimeToSystemTime(nil, @t, @t);
  1201. Result := Round((SystemTimeToDateTime(t) - 25569) * 86400000)
  1202. end;
  1203. {$ENDIF}
  1204. function ISO8601DateToJavaDateTime(const str: SOString; var ms: Int64): Boolean;
  1205. type
  1206. TState = (
  1207. stStart, stYear, stMonth, stWeek, stWeekDay, stDay, stDayOfYear,
  1208. stHour, stMin, stSec, stMs, stUTC, stGMTH, stGMTM,
  1209. stGMTend, stEnd);
  1210. TPerhaps = (yes, no, perhaps);
  1211. TDateTimeInfo = record
  1212. year: Word;
  1213. month: Word;
  1214. week: Word;
  1215. weekday: Word;
  1216. day: Word;
  1217. dayofyear: Integer;
  1218. hour: Word;
  1219. minute: Word;
  1220. second: Word;
  1221. ms: Word;
  1222. bias: Integer;
  1223. end;
  1224. var
  1225. p: PSOChar;
  1226. state: TState;
  1227. pos, v: Word;
  1228. sep: TPerhaps;
  1229. inctz, havetz, havedate: Boolean;
  1230. st: TDateTimeInfo;
  1231. DayTable: PDayTable;
  1232. function get(var v: Word; c: SOChar): Boolean; {$IFDEF HAVE_INLINE} inline;{$ENDIF}
  1233. begin
  1234. if (c < #256) and (AnsiChar(c) in ['0'..'9']) then
  1235. begin
  1236. Result := True;
  1237. v := v * 10 + Ord(c) - Ord('0');
  1238. end else
  1239. Result := False;
  1240. end;
  1241. label
  1242. error;
  1243. begin
  1244. p := PSOChar(str);
  1245. sep := perhaps;
  1246. state := stStart;
  1247. pos := 0;
  1248. FillChar(st, SizeOf(st), 0);
  1249. havedate := True;
  1250. inctz := False;
  1251. havetz := False;
  1252. while true do
  1253. case state of
  1254. stStart:
  1255. case p^ of
  1256. '0'..'9': state := stYear;
  1257. 'T', 't':
  1258. begin
  1259. state := stHour;
  1260. pos := 0;
  1261. inc(p);
  1262. havedate := False;
  1263. end;
  1264. else
  1265. goto error;
  1266. end;
  1267. stYear:
  1268. case pos of
  1269. 0..1,3:
  1270. if get(st.year, p^) then
  1271. begin
  1272. Inc(pos);
  1273. Inc(p);
  1274. end else
  1275. goto error;
  1276. 2: case p^ of
  1277. '0'..'9':
  1278. begin
  1279. st.year := st.year * 10 + ord(p^) - ord('0');
  1280. Inc(pos);
  1281. Inc(p);
  1282. end;
  1283. ':':
  1284. begin
  1285. havedate := false;
  1286. st.hour := st.year;
  1287. st.year := 0;
  1288. inc(p);
  1289. pos := 0;
  1290. state := stMin;
  1291. sep := yes;
  1292. end;
  1293. else
  1294. goto error;
  1295. end;
  1296. 4: case p^ of
  1297. '-': begin
  1298. pos := 0;
  1299. Inc(p);
  1300. sep := yes;
  1301. state := stMonth;
  1302. end;
  1303. '0'..'9':
  1304. begin
  1305. sep := no;
  1306. pos := 0;
  1307. state := stMonth;
  1308. end;
  1309. 'W', 'w' :
  1310. begin
  1311. pos := 0;
  1312. Inc(p);
  1313. state := stWeek;
  1314. end;
  1315. 'T', 't', ' ':
  1316. begin
  1317. state := stHour;
  1318. pos := 0;
  1319. inc(p);
  1320. st.month := 1;
  1321. st.day := 1;
  1322. end;
  1323. #0:
  1324. begin
  1325. st.month := 1;
  1326. st.day := 1;
  1327. state := stEnd;
  1328. end;
  1329. else
  1330. goto error;
  1331. end;
  1332. end;
  1333. stMonth:
  1334. case pos of
  1335. 0: case p^ of
  1336. '0'..'9':
  1337. begin
  1338. st.month := ord(p^) - ord('0');
  1339. Inc(pos);
  1340. Inc(p);
  1341. end;
  1342. 'W', 'w':
  1343. begin
  1344. pos := 0;
  1345. Inc(p);
  1346. state := stWeek;
  1347. end;
  1348. else
  1349. goto error;
  1350. end;
  1351. 1: if get(st.month, p^) then
  1352. begin
  1353. Inc(pos);
  1354. Inc(p);
  1355. end else
  1356. goto error;
  1357. 2: case p^ of
  1358. '-':
  1359. if (sep in [yes, perhaps]) then
  1360. begin
  1361. pos := 0;
  1362. Inc(p);
  1363. state := stDay;
  1364. sep := yes;
  1365. end else
  1366. goto error;
  1367. '0'..'9':
  1368. if sep in [no, perhaps] then
  1369. begin
  1370. pos := 0;
  1371. state := stDay;
  1372. sep := no;
  1373. end else
  1374. begin
  1375. st.dayofyear := st.month * 10 + Ord(p^) - Ord('0');
  1376. st.month := 0;
  1377. inc(p);
  1378. pos := 3;
  1379. state := stDayOfYear;
  1380. end;
  1381. 'T', 't', ' ':
  1382. begin
  1383. state := stHour;
  1384. pos := 0;
  1385. inc(p);
  1386. st.day := 1;
  1387. end;
  1388. #0:
  1389. begin
  1390. st.day := 1;
  1391. state := stEnd;
  1392. end;
  1393. else
  1394. goto error;
  1395. end;
  1396. end;
  1397. stDay:
  1398. case pos of
  1399. 0: if get(st.day, p^) then
  1400. begin
  1401. Inc(pos);
  1402. Inc(p);
  1403. end else
  1404. goto error;
  1405. 1: if get(st.day, p^) then
  1406. begin
  1407. Inc(pos);
  1408. Inc(p);
  1409. end else
  1410. if sep in [no, perhaps] then
  1411. begin
  1412. st.dayofyear := st.month * 10 + st.day;
  1413. st.day := 0;
  1414. st.month := 0;
  1415. state := stDayOfYear;
  1416. end else
  1417. goto error;
  1418. 2: case p^ of
  1419. 'T', 't', ' ':
  1420. begin
  1421. pos := 0;
  1422. Inc(p);
  1423. state := stHour;
  1424. end;
  1425. #0: state := stEnd;
  1426. else
  1427. goto error;
  1428. end;
  1429. end;
  1430. stDayOfYear:
  1431. begin
  1432. if (st.dayofyear <= 0) then goto error;
  1433. case p^ of
  1434. 'T', 't', ' ':
  1435. begin
  1436. pos := 0;
  1437. Inc(p);
  1438. state := stHour;
  1439. end;
  1440. #0: state := stEnd;
  1441. else
  1442. goto error;
  1443. end;
  1444. end;
  1445. stWeek:
  1446. begin
  1447. case pos of
  1448. 0..1: if get(st.week, p^) then
  1449. begin
  1450. inc(pos);
  1451. inc(p);
  1452. end else
  1453. goto error;
  1454. 2: case p^ of
  1455. '-': if (sep in [yes, perhaps]) then
  1456. begin
  1457. Inc(p);
  1458. state := stWeekDay;
  1459. sep := yes;
  1460. end else
  1461. goto error;
  1462. '1'..'7':
  1463. if sep in [no, perhaps] then
  1464. begin
  1465. state := stWeekDay;
  1466. sep := no;
  1467. end else
  1468. goto error;
  1469. else
  1470. goto error;
  1471. end;
  1472. end;
  1473. end;
  1474. stWeekDay:
  1475. begin
  1476. if (st.week > 0) and get(st.weekday, p^) then
  1477. begin
  1478. inc(p);
  1479. v := st.year - 1;
  1480. v := ((v * 365) + (v div 4) - (v div 100) + (v div 400)) mod 7 + 1;
  1481. st.dayofyear := (st.weekday - v) + ((st.week) * 7) + 1;
  1482. if v <= 4 then dec(st.dayofyear, 7);
  1483. case p^ of
  1484. 'T', 't', ' ':
  1485. begin
  1486. pos := 0;
  1487. Inc(p);
  1488. state := stHour;
  1489. end;
  1490. #0: state := stEnd;
  1491. else
  1492. goto error;
  1493. end;
  1494. end else
  1495. goto error;
  1496. end;
  1497. stHour:
  1498. case pos of
  1499. 0: case p^ of
  1500. '0'..'9':
  1501. if get(st.hour, p^) then
  1502. begin
  1503. inc(pos);
  1504. inc(p);
  1505. end else
  1506. goto error;
  1507. '-':
  1508. begin
  1509. inc(p);
  1510. state := stMin;
  1511. end;
  1512. else
  1513. goto error;
  1514. end;
  1515. 1: if get(st.hour, p^) then
  1516. begin
  1517. inc(pos);
  1518. inc(p);
  1519. end else
  1520. goto error;
  1521. 2: case p^ of
  1522. ':': if sep in [yes, perhaps] then
  1523. begin
  1524. sep := yes;
  1525. pos := 0;
  1526. Inc(p);
  1527. state := stMin;
  1528. end else
  1529. goto error;
  1530. ',', '.':
  1531. begin
  1532. Inc(p);
  1533. state := stMs;
  1534. end;
  1535. '+':
  1536. if havedate then
  1537. begin
  1538. state := stGMTH;
  1539. pos := 0;
  1540. v := 0;
  1541. inc(p);
  1542. end else
  1543. goto error;
  1544. '-':
  1545. if havedate then
  1546. begin
  1547. state := stGMTH;
  1548. pos := 0;
  1549. v := 0;
  1550. inc(p);
  1551. inctz := True;
  1552. end else
  1553. goto error;
  1554. 'Z', 'z':
  1555. if havedate then
  1556. state := stUTC else
  1557. goto error;
  1558. '0'..'9':
  1559. if sep in [no, perhaps] then
  1560. begin
  1561. pos := 0;
  1562. state := stMin;
  1563. sep := no;
  1564. end else
  1565. goto error;
  1566. #0: state := stEnd;
  1567. else
  1568. goto error;
  1569. end;
  1570. end;
  1571. stMin:
  1572. case pos of
  1573. 0: case p^ of
  1574. '0'..'9':
  1575. if get(st.minute, p^) then
  1576. begin
  1577. inc(pos);
  1578. inc(p);
  1579. end else
  1580. goto error;
  1581. '-':
  1582. begin
  1583. inc(p);
  1584. state := stSec;
  1585. end;
  1586. else
  1587. goto error;
  1588. end;
  1589. 1: if get(st.minute, p^) then
  1590. begin
  1591. inc(pos);
  1592. inc(p);
  1593. end else
  1594. goto error;
  1595. 2: case p^ of
  1596. ':': if sep in [yes, perhaps] then
  1597. begin
  1598. pos := 0;
  1599. Inc(p);
  1600. state := stSec;
  1601. sep := yes;
  1602. end else
  1603. goto error;
  1604. ',', '.':
  1605. begin
  1606. Inc(p);
  1607. state := stMs;
  1608. end;
  1609. '+':
  1610. if havedate then
  1611. begin
  1612. state := stGMTH;
  1613. pos := 0;
  1614. v := 0;
  1615. inc(p);
  1616. end else
  1617. goto error;
  1618. '-':
  1619. if havedate then
  1620. begin
  1621. state := stGMTH;
  1622. pos := 0;
  1623. v := 0;
  1624. inc(p);
  1625. inctz := True;
  1626. end else
  1627. goto error;
  1628. 'Z', 'z':
  1629. if havedate then
  1630. state := stUTC else
  1631. goto error;
  1632. '0'..'9':
  1633. if sep in [no, perhaps] then
  1634. begin
  1635. pos := 0;
  1636. state := stSec;
  1637. end else
  1638. goto error;
  1639. #0: state := stEnd;
  1640. else
  1641. goto error;
  1642. end;
  1643. end;
  1644. stSec:
  1645. case pos of
  1646. 0..1: if get(st.second, p^) then
  1647. begin
  1648. inc(pos);
  1649. inc(p);
  1650. end else
  1651. goto error;
  1652. 2: case p^ of
  1653. ',', '.':
  1654. begin
  1655. Inc(p);
  1656. state := stMs;
  1657. end;
  1658. '+':
  1659. if havedate then
  1660. begin
  1661. state := stGMTH;
  1662. pos := 0;
  1663. v := 0;
  1664. inc(p);
  1665. end else
  1666. goto error;
  1667. '-':
  1668. if havedate then
  1669. begin
  1670. state := stGMTH;
  1671. pos := 0;
  1672. v := 0;
  1673. inc(p);
  1674. inctz := True;
  1675. end else
  1676. goto error;
  1677. 'Z', 'z':
  1678. if havedate then
  1679. state := stUTC else
  1680. goto error;
  1681. #0: state := stEnd;
  1682. else
  1683. goto error;
  1684. end;
  1685. end;
  1686. stMs:
  1687. case p^ of
  1688. '0'..'9':
  1689. begin
  1690. st.ms := st.ms * 10 + ord(p^) - ord('0');
  1691. inc(p);
  1692. end;
  1693. '+':
  1694. if havedate then
  1695. begin
  1696. state := stGMTH;
  1697. pos := 0;
  1698. v := 0;
  1699. inc(p);
  1700. end else
  1701. goto error;
  1702. '-':
  1703. if havedate then
  1704. begin
  1705. state := stGMTH;
  1706. pos := 0;
  1707. v := 0;
  1708. inc(p);
  1709. inctz := True;
  1710. end else
  1711. goto error;
  1712. 'Z', 'z':
  1713. if havedate then
  1714. state := stUTC else
  1715. goto error;
  1716. #0: state := stEnd;
  1717. else
  1718. goto error;
  1719. end;
  1720. stUTC: // = GMT 0
  1721. begin
  1722. havetz := True;
  1723. inc(p);
  1724. if p^ = #0 then
  1725. Break else
  1726. goto error;
  1727. end;
  1728. stGMTH:
  1729. begin
  1730. havetz := True;
  1731. case pos of
  1732. 0..1: if get(v, p^) then
  1733. begin
  1734. inc(p);
  1735. inc(pos);
  1736. end else
  1737. goto error;
  1738. 2:
  1739. begin
  1740. st.bias := v * 60;
  1741. case p^ of
  1742. ':': if sep in [yes, perhaps] then
  1743. begin
  1744. state := stGMTM;
  1745. inc(p);
  1746. pos := 0;
  1747. v := 0;
  1748. sep := yes;
  1749. end else
  1750. goto error;
  1751. '0'..'9':
  1752. if sep in [no, perhaps] then
  1753. begin
  1754. state := stGMTM;
  1755. pos := 1;
  1756. sep := no;
  1757. inc(p);
  1758. v := ord(p^) - ord('0');
  1759. end else
  1760. goto error;
  1761. #0: state := stGMTend;
  1762. else
  1763. goto error;
  1764. end;
  1765. end;
  1766. end;
  1767. end;
  1768. stGMTM:
  1769. case pos of
  1770. 0..1: if get(v, p^) then
  1771. begin
  1772. inc(p);
  1773. inc(pos);
  1774. end else
  1775. goto error;
  1776. 2: case p^ of
  1777. #0:
  1778. begin
  1779. state := stGMTend;
  1780. inc(st.Bias, v);
  1781. end;
  1782. else
  1783. goto error;
  1784. end;
  1785. end;
  1786. stGMTend:
  1787. begin
  1788. if not inctz then
  1789. st.Bias := -st.bias;
  1790. Break;
  1791. end;
  1792. stEnd:
  1793. begin
  1794. Break;
  1795. end;
  1796. end;
  1797. if (st.hour >= 24) or (st.minute >= 60) or (st.second >= 60) or (st.ms >= 1000) or (st.week > 53)
  1798. then goto error;
  1799. if not havetz then
  1800. st.bias := GetTimeBias;
  1801. ms := st.ms + st.second * 1000 + (st.minute + st.bias) * 60000 + st.hour * 3600000;
  1802. if havedate then
  1803. begin
  1804. DayTable := @MonthDays[IsLeapYear(st.year)];
  1805. if st.month <> 0 then
  1806. begin
  1807. if not (st.month in [1..12]) or (DayTable^[st.month] < st.day) then
  1808. goto error;
  1809. for v := 1 to st.month - 1 do
  1810. Inc(ms, DayTable^[v] * 86400000);
  1811. end;
  1812. dec(st.year);
  1813. ms := ms + (int64((st.year * 365) + (st.year div 4) - (st.year div 100) +
  1814. (st.year div 400) + st.day + st.dayofyear - 719163) * 86400000);
  1815. end;
  1816. Result := True;
  1817. Exit;
  1818. error:
  1819. Result := False;
  1820. end;
  1821. function ISO8601DateToDelphiDateTime(const str: SOString; var dt: TDateTime): Boolean;
  1822. var
  1823. ms: Int64;
  1824. begin
  1825. Result := ISO8601DateToJavaDateTime(str, ms);
  1826. if Result then
  1827. dt := JavaToDelphiDateTime(ms)
  1828. end;
  1829. function DelphiDateTimeToISO8601Date(dt: TDateTime): SOString;
  1830. var
  1831. year, month, day, hour, min, sec, msec: Word;
  1832. tzh: SmallInt;
  1833. tzm: Word;
  1834. sign: SOChar;
  1835. bias: Integer;
  1836. begin
  1837. DecodeDate(dt, year, month, day);
  1838. DecodeTime(dt, hour, min, sec, msec);
  1839. bias := GetTimeBias;
  1840. tzh := Abs(bias) div 60;
  1841. tzm := Abs(bias) - tzh * 60;
  1842. if Bias > 0 then
  1843. sign := '-' else
  1844. sign := '+';
  1845. Result := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d,%d%s%.2d:%.2d',
  1846. [year, month, day, hour, min, sec, msec, sign, tzh, tzm]);
  1847. end;
  1848. function TryObjectToDate(const obj: ISuperObject; var dt: TDateTime): Boolean;
  1849. var
  1850. i: Int64;
  1851. begin
  1852. case ObjectGetType(obj) of
  1853. stInt:
  1854. begin
  1855. dt := JavaToDelphiDateTime(obj.AsInteger);
  1856. Result := True;
  1857. end;
  1858. stString:
  1859. begin
  1860. if ISO8601DateToJavaDateTime(obj.AsString, i) then
  1861. begin
  1862. dt := JavaToDelphiDateTime(i);
  1863. Result := True;
  1864. end else
  1865. Result := TryStrToDateTime(obj.AsString, dt);
  1866. end;
  1867. else
  1868. Result := False;
  1869. end;
  1870. end;
  1871. function SO(const s: SOString): ISuperObject; overload;
  1872. begin
  1873. Result := TSuperObject.ParseString(PSOChar(s), False);
  1874. end;
  1875. function SA(const Args: array of const): ISuperObject; overload;
  1876. type
  1877. TByteArray = array[0..sizeof(integer) - 1] of byte;
  1878. PByteArray = ^TByteArray;
  1879. var
  1880. j: Integer;
  1881. intf: IInterface;
  1882. begin
  1883. Result := TSuperObject.Create(stArray);
  1884. for j := 0 to length(Args) - 1 do
  1885. with Result.AsArray do
  1886. case TVarRec(Args[j]).VType of
  1887. vtInteger : Add(TSuperObject.Create(TVarRec(Args[j]).VInteger));
  1888. vtInt64 : Add(TSuperObject.Create(TVarRec(Args[j]).VInt64^));
  1889. vtBoolean : Add(TSuperObject.Create(TVarRec(Args[j]).VBoolean));
  1890. vtChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VChar)));
  1891. vtWideChar: Add(TSuperObject.Create(SOChar(TVarRec(Args[j]).VWideChar)));
  1892. vtExtended: Add(TSuperObject.Create(TVarRec(Args[j]).VExtended^));
  1893. vtCurrency: Add(TSuperObject.CreateCurrency(TVarRec(Args[j]).VCurrency^));
  1894. vtString : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VString^)));
  1895. vtPChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VPChar^)));
  1896. vtAnsiString: Add(TSuperObject.Create(SOString(AnsiString(TVarRec(Args[j]).VAnsiString))));
  1897. vtWideString: Add(TSuperObject.Create(SOString(PWideChar(TVarRec(Args[j]).VWideString))));
  1898. vtInterface:
  1899. if TVarRec(Args[j]).VInterface = nil then
  1900. Add(nil) else
  1901. if IInterface(TVarRec(Args[j]).VInterface).QueryInterface(ISuperObject, intf) = 0 then
  1902. Add(ISuperObject(intf)) else
  1903. Add(nil);
  1904. vtPointer :
  1905. if TVarRec(Args[j]).VPointer = nil then
  1906. Add(nil) else
  1907. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1908. vtVariant:
  1909. Add(SO(TVarRec(Args[j]).VVariant^));
  1910. vtObject:
  1911. if TVarRec(Args[j]).VPointer = nil then
  1912. Add(nil) else
  1913. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1914. vtClass:
  1915. if TVarRec(Args[j]).VPointer = nil then
  1916. Add(nil) else
  1917. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1918. {$if declared(vtUnicodeString)}
  1919. vtUnicodeString:
  1920. Add(TSuperObject.Create(SOString(string(TVarRec(Args[j]).VUnicodeString))));
  1921. {$ifend}
  1922. else
  1923. assert(false);
  1924. end;
  1925. end;
  1926. function SO(const Args: array of const): ISuperObject; overload;
  1927. var
  1928. j: Integer;
  1929. arr: ISuperObject;
  1930. begin
  1931. Result := TSuperObject.Create(stObject);
  1932. arr := SA(Args);
  1933. with arr.AsArray do
  1934. for j := 0 to (Length div 2) - 1 do
  1935. Result.AsObject.PutO(O[j*2].AsString, O[(j*2) + 1]);
  1936. end;
  1937. function SO(const value: Variant): ISuperObject; overload;
  1938. begin
  1939. with TVarData(value) do
  1940. case VType of
  1941. varNull: Result := nil;
  1942. varEmpty: Result := nil;
  1943. varSmallInt: Result := TSuperObject.Create(VSmallInt);
  1944. varInteger: Result := TSuperObject.Create(VInteger);
  1945. varSingle: Result := TSuperObject.Create(VSingle);
  1946. varDouble: Result := TSuperObject.Create(VDouble);
  1947. varCurrency: Result := TSuperObject.CreateCurrency(VCurrency);
  1948. varDate: Result := TSuperObject.Create(DelphiToJavaDateTime(vDate));
  1949. varOleStr: Result := TSuperObject.Create(SOString(VOleStr));
  1950. varBoolean: Result := TSuperObject.Create(VBoolean);
  1951. varShortInt: Result := TSuperObject.Create(VShortInt);
  1952. varByte: Result := TSuperObject.Create(VByte);
  1953. varWord: Result := TSuperObject.Create(VWord);
  1954. varLongWord: Result := TSuperObject.Create(VLongWord);
  1955. varInt64: Result := TSuperObject.Create(VInt64);
  1956. varString: Result := TSuperObject.Create(SOString(AnsiString(VString)));
  1957. {$if declared(varUString)}
  1958. {$IFDEF FPC}
  1959. varUString: Result := TSuperObject.Create(SOString(UnicodeString(VString)));
  1960. {$ELSE}
  1961. varUString: Result := TSuperObject.Create(SOString(string(VUString)));
  1962. {$ENDIF}
  1963. {$ifend}
  1964. else
  1965. raise Exception.CreateFmt('Unsuported variant data type: %d', [VType]);
  1966. end;
  1967. end;
  1968. function ObjectIsError(obj: TSuperObject): boolean;
  1969. begin
  1970. Result := PtrUInt(obj) > PtrUInt(-4000);
  1971. end;
  1972. function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;
  1973. begin
  1974. if obj <> nil then
  1975. Result := typ = obj.DataType else
  1976. Result := typ = stNull;
  1977. end;
  1978. function ObjectGetType(const obj: ISuperObject): TSuperType;
  1979. begin
  1980. if obj <> nil then
  1981. Result := obj.DataType else
  1982. Result := stNull;
  1983. end;
  1984. function ObjectIsNull(const obj: ISuperObject): Boolean;
  1985. begin
  1986. Result := ObjectIsType(obj, stNull);
  1987. end;
  1988. function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;
  1989. var
  1990. i: TSuperAvlEntry;
  1991. begin
  1992. if ObjectIsType(obj, stObject) then
  1993. begin
  1994. F.Ite := TSuperAvlIterator.Create(obj.AsObject);
  1995. F.Ite.First;
  1996. i := F.Ite.GetIter;
  1997. if i <> nil then
  1998. begin
  1999. f.key := i.Name;
  2000. f.val := i.Value;
  2001. Result := true;
  2002. end else
  2003. Result := False;
  2004. end else
  2005. Result := False;
  2006. end;
  2007. function ObjectFindNext(var F: TSuperObjectIter): boolean;
  2008. var
  2009. i: TSuperAvlEntry;
  2010. begin
  2011. F.Ite.Next;
  2012. i := F.Ite.GetIter;
  2013. if i <> nil then
  2014. begin
  2015. f.key := i.FName;
  2016. f.val := i.Value;
  2017. Result := true;
  2018. end else
  2019. Result := False;
  2020. end;
  2021. procedure ObjectFindClose(var F: TSuperObjectIter);
  2022. begin
  2023. F.Ite.Free;
  2024. F.val := nil;
  2025. end;
  2026. function UuidFromString(p: PSOChar; Uuid: PGUID): Boolean;
  2027. const
  2028. hex2bin: array[48..102] of Byte = (
  2029. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
  2030. 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2031. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2032. 0,10,11,12,13,14,15);
  2033. type
  2034. TState = (stEatSpaces, stStart, stHEX, stBracket, stEnd);
  2035. TUUID = record
  2036. case byte of
  2037. 0: (guid: TGUID);
  2038. 1: (bytes: array[0..15] of Byte);
  2039. 2: (words: array[0..7] of Word);
  2040. 3: (ints: array[0..3] of Cardinal);
  2041. 4: (i64s: array[0..1] of UInt64);
  2042. end;
  2043. function ishex(const c: SOChar): Boolean; {$IFDEF HAVE_INLINE} inline;{$ENDIF}
  2044. begin
  2045. result := (c < #256) and (AnsiChar(c) in ['0'..'9', 'a'..'z', 'A'..'Z'])
  2046. end;
  2047. var
  2048. pos: Byte;
  2049. state, saved: TState;
  2050. bracket, separator: Boolean;
  2051. label
  2052. redo;
  2053. begin
  2054. FillChar(Uuid^, SizeOf(TGUID), 0);
  2055. saved := stStart;
  2056. state := stEatSpaces;
  2057. bracket := false;
  2058. separator := false;
  2059. pos := 0;
  2060. while true do
  2061. redo:
  2062. case state of
  2063. stEatSpaces:
  2064. begin
  2065. while true do
  2066. case p^ of
  2067. ' ', #13, #10, #9: inc(p);
  2068. else
  2069. state := saved;
  2070. goto redo;
  2071. end;
  2072. end;
  2073. stStart:
  2074. case p^ of
  2075. '{':
  2076. begin
  2077. bracket := true;
  2078. inc(p);
  2079. state := stEatSpaces;
  2080. saved := stHEX;
  2081. pos := 0;
  2082. end;
  2083. else
  2084. state := stHEX;
  2085. end;
  2086. stHEX:
  2087. case pos of
  2088. 0..7:
  2089. if ishex(p^) then
  2090. begin
  2091. Uuid^.D1 := (Uuid^.D1 * 16) + hex2bin[Ord(p^)];
  2092. inc(p);
  2093. inc(pos);
  2094. end else
  2095. begin
  2096. Result := False;
  2097. Exit;
  2098. end;
  2099. 8:
  2100. if (p^ = '-') then
  2101. begin
  2102. separator := true;
  2103. inc(p);
  2104. inc(pos)
  2105. end else
  2106. inc(pos);
  2107. 13,18,23:
  2108. if separator then
  2109. begin
  2110. if p^ <> '-' then
  2111. begin
  2112. Result := False;
  2113. Exit;
  2114. end;
  2115. inc(p);
  2116. inc(pos);
  2117. end else
  2118. inc(pos);
  2119. 9..12:
  2120. if ishex(p^) then
  2121. begin
  2122. TUUID(Uuid^).words[2] := (TUUID(Uuid^).words[2] * 16) + hex2bin[Ord(p^)];
  2123. inc(p);
  2124. inc(pos);
  2125. end else
  2126. begin
  2127. Result := False;
  2128. Exit;
  2129. end;
  2130. 14..17:
  2131. if ishex(p^) then
  2132. begin
  2133. TUUID(Uuid^).words[3] := (TUUID(Uuid^).words[3] * 16) + hex2bin[Ord(p^)];
  2134. inc(p);
  2135. inc(pos);
  2136. end else
  2137. begin
  2138. Result := False;
  2139. Exit;
  2140. end;
  2141. 19..20:
  2142. if ishex(p^) then
  2143. begin
  2144. TUUID(Uuid^).bytes[8] := (TUUID(Uuid^).bytes[8] * 16) + hex2bin[Ord(p^)];
  2145. inc(p);
  2146. inc(pos);
  2147. end else
  2148. begin
  2149. Result := False;
  2150. Exit;
  2151. end;
  2152. 21..22:
  2153. if ishex(p^) then
  2154. begin
  2155. TUUID(Uuid^).bytes[9] := (TUUID(Uuid^).bytes[9] * 16) + hex2bin[Ord(p^)];
  2156. inc(p);
  2157. inc(pos);
  2158. end else
  2159. begin
  2160. Result := False;
  2161. Exit;
  2162. end;
  2163. 24..25:
  2164. if ishex(p^) then
  2165. begin
  2166. TUUID(Uuid^).bytes[10] := (TUUID(Uuid^).bytes[10] * 16) + hex2bin[Ord(p^)];
  2167. inc(p);
  2168. inc(pos);
  2169. end else
  2170. begin
  2171. Result := False;
  2172. Exit;
  2173. end;
  2174. 26..27:
  2175. if ishex(p^) then
  2176. begin
  2177. TUUID(Uuid^).bytes[11] := (TUUID(Uuid^).bytes[11] * 16) + hex2bin[Ord(p^)];
  2178. inc(p);
  2179. inc(pos);
  2180. end else
  2181. begin
  2182. Result := False;
  2183. Exit;
  2184. end;
  2185. 28..29:
  2186. if ishex(p^) then
  2187. begin
  2188. TUUID(Uuid^).bytes[12] := (TUUID(Uuid^).bytes[12] * 16) + hex2bin[Ord(p^)];
  2189. inc(p);
  2190. inc(pos);
  2191. end else
  2192. begin
  2193. Result := False;
  2194. Exit;
  2195. end;
  2196. 30..31:
  2197. if ishex(p^) then
  2198. begin
  2199. TUUID(Uuid^).bytes[13] := (TUUID(Uuid^).bytes[13] * 16) + hex2bin[Ord(p^)];
  2200. inc(p);
  2201. inc(pos);
  2202. end else
  2203. begin
  2204. Result := False;
  2205. Exit;
  2206. end;
  2207. 32..33:
  2208. if ishex(p^) then
  2209. begin
  2210. TUUID(Uuid^).bytes[14] := (TUUID(Uuid^).bytes[14] * 16) + hex2bin[Ord(p^)];
  2211. inc(p);
  2212. inc(pos);
  2213. end else
  2214. begin
  2215. Result := False;
  2216. Exit;
  2217. end;
  2218. 34..35:
  2219. if ishex(p^) then
  2220. begin
  2221. TUUID(Uuid^).bytes[15] := (TUUID(Uuid^).bytes[15] * 16) + hex2bin[Ord(p^)];
  2222. inc(p);
  2223. inc(pos);
  2224. end else
  2225. begin
  2226. Result := False;
  2227. Exit;
  2228. end;
  2229. 36: if bracket then
  2230. begin
  2231. state := stEatSpaces;
  2232. saved := stBracket;
  2233. end else
  2234. begin
  2235. state := stEatSpaces;
  2236. saved := stEnd;
  2237. end;
  2238. end;
  2239. stBracket:
  2240. begin
  2241. if p^ <> '}' then
  2242. begin
  2243. Result := False;
  2244. Exit;
  2245. end;
  2246. inc(p);
  2247. state := stEatSpaces;
  2248. saved := stEnd;
  2249. end;
  2250. stEnd:
  2251. begin
  2252. if p^ <> #0 then
  2253. begin
  2254. Result := False;
  2255. Exit;
  2256. end;
  2257. Break;
  2258. end;
  2259. end;
  2260. Result := True;
  2261. end;
  2262. function UUIDToString(const g: TGUID): SOString;
  2263. begin
  2264. Result := format('%.8x%.4x%.4x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x',
  2265. [g.D1, g.D2, g.D3,
  2266. g.D4[0], g.D4[1], g.D4[2],
  2267. g.D4[3], g.D4[4], g.D4[5],
  2268. g.D4[6], g.D4[7]]);
  2269. end;
  2270. function StringToUUID(const str: SOString; var g: TGUID): Boolean;
  2271. begin
  2272. Result := UuidFromString(PSOChar(str), @g);
  2273. end;
  2274. {$IFDEF HAVE_RTTI}
  2275. function serialtoboolean(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  2276. begin
  2277. Result := TSuperObject.Create(TValueData(value).FAsSLong <> 0);
  2278. end;
  2279. function serialtodatetime(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  2280. begin
  2281. Result := TSuperObject.Create(DelphiToJavaDateTime(TValueData(value).FAsDouble));
  2282. end;
  2283. function serialtoguid(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  2284. var
  2285. g: TGUID;
  2286. begin
  2287. value.ExtractRawData(@g);
  2288. Result := TSuperObject.Create(
  2289. format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x',
  2290. [g.D1, g.D2, g.D3,
  2291. g.D4[0], g.D4[1], g.D4[2],
  2292. g.D4[3], g.D4[4], g.D4[5],
  2293. g.D4[6], g.D4[7]])
  2294. );
  2295. end;
  2296. function serialfromboolean(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  2297. var
  2298. o: ISuperObject;
  2299. begin
  2300. case ObjectGetType(obj) of
  2301. stBoolean:
  2302. begin
  2303. TValueData(Value).FAsSLong := obj.AsInteger;
  2304. Result := True;
  2305. end;
  2306. stInt:
  2307. begin
  2308. TValueData(Value).FAsSLong := ord(obj.AsInteger <> 0);
  2309. Result := True;
  2310. end;
  2311. stString:
  2312. begin
  2313. o := SO(obj.AsString);
  2314. if not ObjectIsType(o, stString) then
  2315. Result := serialfromboolean(ctx, SO(obj.AsString), Value) else
  2316. Result := False;
  2317. end;
  2318. else
  2319. Result := False;
  2320. end;
  2321. end;
  2322. function serialfromdatetime(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  2323. var
  2324. dt: TDateTime;
  2325. i: Int64;
  2326. begin
  2327. case ObjectGetType(obj) of
  2328. stInt:
  2329. begin
  2330. TValueData(Value).FAsDouble := JavaToDelphiDateTime(obj.AsInteger);
  2331. Result := True;
  2332. end;
  2333. stString:
  2334. begin
  2335. if ISO8601DateToJavaDateTime(obj.AsString, i) then
  2336. begin
  2337. TValueData(Value).FAsDouble := JavaToDelphiDateTime(i);
  2338. Result := True;
  2339. end else
  2340. if TryStrToDateTime(obj.AsString, dt) then
  2341. begin
  2342. TValueData(Value).FAsDouble := dt;
  2343. Result := True;
  2344. end else
  2345. Result := False;
  2346. end;
  2347. else
  2348. Result := False;
  2349. end;
  2350. end;
  2351. function serialfromguid(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  2352. begin
  2353. case ObjectGetType(obj) of
  2354. stNull:
  2355. begin
  2356. FillChar(Value.GetReferenceToRawData^, SizeOf(TGUID), 0);
  2357. Result := True;
  2358. end;
  2359. stString: Result := UuidFromString(PSOChar(obj.AsString), Value.GetReferenceToRawData);
  2360. else
  2361. Result := False;
  2362. end;
  2363. end;
  2364. function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext): ISuperObject; overload;
  2365. var
  2366. owned: Boolean;
  2367. begin
  2368. if ctx = nil then
  2369. begin
  2370. ctx := TSuperRttiContext.Create;
  2371. owned := True;
  2372. end else
  2373. owned := False;
  2374. try
  2375. if TrySOInvoke(ctx, obj, method, params, Result) <> irSuccess then
  2376. raise Exception.Create('Invalid method call');
  2377. finally
  2378. if owned then
  2379. ctx.Free;
  2380. end;
  2381. end;
  2382. function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext): ISuperObject; overload;
  2383. begin
  2384. Result := SOInvoke(obj, method, so(params), ctx)
  2385. end;
  2386. function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue;
  2387. const method: string; const params: ISuperObject;
  2388. var Return: ISuperObject): TSuperInvokeResult;
  2389. var
  2390. t: TRttiInstanceType;
  2391. m: TRttiMethod;
  2392. a: TArray<TValue>;
  2393. ps: TArray<TRttiParameter>;
  2394. v: TValue;
  2395. index: ISuperObject;
  2396. function GetParams: Boolean;
  2397. var
  2398. i: Integer;
  2399. begin
  2400. case ObjectGetType(params) of
  2401. stArray:
  2402. for i := 0 to Length(ps) - 1 do
  2403. if (pfOut in ps[i].Flags) then
  2404. TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else
  2405. if not ctx.FromJson(ps[i].ParamType.Handle, params.AsArray[i], a[i]) then
  2406. Exit(False);
  2407. stObject:
  2408. for i := 0 to Length(ps) - 1 do
  2409. if (pfOut in ps[i].Flags) then
  2410. TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else
  2411. if not ctx.FromJson(ps[i].ParamType.Handle, params.AsObject[ps[i].Name], a[i]) then
  2412. Exit(False);
  2413. stNull: ;
  2414. else
  2415. Exit(False);
  2416. end;
  2417. Result := True;
  2418. end;
  2419. procedure SetParams;
  2420. var
  2421. i: Integer;
  2422. begin
  2423. case ObjectGetType(params) of
  2424. stArray:
  2425. for i := 0 to Length(ps) - 1 do
  2426. if (ps[i].Flags * [pfVar, pfOut]) <> [] then
  2427. params.AsArray[i] := ctx.ToJson(a[i], index);
  2428. stObject:
  2429. for i := 0 to Length(ps) - 1 do
  2430. if (ps[i].Flags * [pfVar, pfOut]) <> [] then
  2431. params.AsObject[ps[i].Name] := ctx.ToJson(a[i], index);
  2432. end;
  2433. end;
  2434. begin
  2435. Result := irSuccess;
  2436. index := SO;
  2437. case obj.Kind of
  2438. tkClass:
  2439. begin
  2440. t := TRttiInstanceType(ctx.Context.GetType(obj.AsObject.ClassType));
  2441. m := t.GetMethod(method);
  2442. if m = nil then Exit(irMethothodError);
  2443. ps := m.GetParameters;
  2444. SetLength(a, Length(ps));
  2445. if not GetParams then Exit(irParamError);
  2446. if m.IsClassMethod then
  2447. begin
  2448. v := m.Invoke(obj.AsObject.ClassType, a);
  2449. Return := ctx.ToJson(v, index);
  2450. SetParams;
  2451. end else
  2452. begin
  2453. v := m.Invoke(obj, a);
  2454. Return := ctx.ToJson(v, index);
  2455. SetParams;
  2456. end;
  2457. end;
  2458. tkClassRef:
  2459. begin
  2460. t := TRttiInstanceType(ctx.Context.GetType(obj.AsClass));
  2461. m := t.GetMethod(method);
  2462. if m = nil then Exit(irMethothodError);
  2463. ps := m.GetParameters;
  2464. SetLength(a, Length(ps));
  2465. if not GetParams then Exit(irParamError);
  2466. if m.IsClassMethod then
  2467. begin
  2468. v := m.Invoke(obj, a);
  2469. Return := ctx.ToJson(v, index);
  2470. SetParams;
  2471. end else
  2472. Exit(irError);
  2473. end;
  2474. else
  2475. Exit(irError);
  2476. end;
  2477. end;
  2478. {$ENDIF}
  2479. { TSuperEnumerator }
  2480. constructor TSuperEnumerator.Create(const obj: ISuperObject);
  2481. begin
  2482. FObj := obj;
  2483. FCount := -1;
  2484. if ObjectIsType(FObj, stObject) then
  2485. FObjEnum := FObj.AsObject.GetEnumerator else
  2486. FObjEnum := nil;
  2487. end;
  2488. destructor TSuperEnumerator.Destroy;
  2489. begin
  2490. if FObjEnum <> nil then
  2491. FObjEnum.Free;
  2492. end;
  2493. function TSuperEnumerator.MoveNext: Boolean;
  2494. begin
  2495. case ObjectGetType(FObj) of
  2496. stObject: Result := FObjEnum.MoveNext;
  2497. stArray:
  2498. begin
  2499. inc(FCount);
  2500. if FCount < FObj.AsArray.Length then
  2501. Result := True else
  2502. Result := False;
  2503. end;
  2504. else
  2505. Result := false;
  2506. end;
  2507. end;
  2508. function TSuperEnumerator.GetCurrent: ISuperObject;
  2509. begin
  2510. case ObjectGetType(FObj) of
  2511. stObject: Result := FObjEnum.Current.Value;
  2512. stArray: Result := FObj.AsArray.GetO(FCount);
  2513. else
  2514. Result := FObj;
  2515. end;
  2516. end;
  2517. { TSuperObject }
  2518. constructor TSuperObject.Create(jt: TSuperType);
  2519. begin
  2520. inherited Create;
  2521. {$IFDEF DEBUG}
  2522. InterlockedIncrement(debugcount);
  2523. {$ENDIF}
  2524. FProcessing := false;
  2525. FDataPtr := nil;
  2526. FDataType := jt;
  2527. case FDataType of
  2528. stObject: FO.c_object := TSuperTableString.Create;
  2529. stArray: FO.c_array := TSuperArray.Create;
  2530. stString: FOString := '';
  2531. else
  2532. FO.c_object := nil;
  2533. end;
  2534. end;
  2535. constructor TSuperObject.Create(b: boolean);
  2536. begin
  2537. Create(stBoolean);
  2538. FO.c_boolean := b;
  2539. end;
  2540. constructor TSuperObject.Create(i: SuperInt);
  2541. begin
  2542. Create(stInt);
  2543. FO.c_int := i;
  2544. end;
  2545. constructor TSuperObject.Create(d: double);
  2546. begin
  2547. Create(stDouble);
  2548. FO.c_double := d;
  2549. end;
  2550. constructor TSuperObject.CreateCurrency(c: Currency);
  2551. begin
  2552. Create(stCurrency);
  2553. FO.c_currency := c;
  2554. end;
  2555. destructor TSuperObject.Destroy;
  2556. begin
  2557. {$IFDEF DEBUG}
  2558. InterlockedDecrement(debugcount);
  2559. {$ENDIF}
  2560. case FDataType of
  2561. stObject: FO.c_object.Free;
  2562. stArray: FO.c_array.Free;
  2563. end;
  2564. inherited;
  2565. end;
  2566. function TSuperObject.Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;
  2567. function DoEscape(str: PSOChar; len: Integer): Integer;
  2568. var
  2569. pos, start_offset: Integer;
  2570. c: SOChar;
  2571. buf: array[0..5] of SOChar;
  2572. type
  2573. TByteChar = record
  2574. case integer of
  2575. 0: (a, b: Byte);
  2576. 1: (c: WideChar);
  2577. end;
  2578. begin
  2579. if str = nil then
  2580. begin
  2581. Result := 0;
  2582. exit;
  2583. end;
  2584. pos := 0; start_offset := 0;
  2585. with writer do
  2586. while pos < len do
  2587. begin
  2588. c := str[pos];
  2589. case c of
  2590. #8,#9,#10,#12,#13,'"','\','/':
  2591. begin
  2592. if(pos - start_offset > 0) then
  2593. Append(str + start_offset, pos - start_offset);
  2594. if(c = #8) then Append(ESC_BS, 2)
  2595. else if (c = #9) then Append(ESC_TAB, 2)
  2596. else if (c = #10) then Append(ESC_LF, 2)
  2597. else if (c = #12) then Append(ESC_FF, 2)
  2598. else if (c = #13) then Append(ESC_CR, 2)
  2599. else if (c = '"') then Append(ESC_QUOT, 2)
  2600. else if (c = '\') then Append(ESC_SL, 2)
  2601. else if (c = '/') then Append(ESC_SR, 2);
  2602. inc(pos);
  2603. start_offset := pos;
  2604. end;
  2605. else
  2606. if (SOIChar(c) > 255) then
  2607. begin
  2608. if(pos - start_offset > 0) then
  2609. Append(str + start_offset, pos - start_offset);
  2610. buf[0] := '\';
  2611. buf[1] := 'u';
  2612. buf[2] := super_hex_chars[TByteChar(c).b shr 4];
  2613. buf[3] := super_hex_chars[TByteChar(c).b and $f];
  2614. buf[4] := super_hex_chars[TByteChar(c).a shr 4];
  2615. buf[5] := super_hex_chars[TByteChar(c).a and $f];
  2616. Append(@buf, 6);
  2617. inc(pos);
  2618. start_offset := pos;
  2619. end else
  2620. if (c < #32) or (c > #127) then
  2621. begin
  2622. if(pos - start_offset > 0) then
  2623. Append(str + start_offset, pos - start_offset);
  2624. buf[0] := '\';
  2625. buf[1] := 'u';
  2626. buf[2] := '0';
  2627. buf[3] := '0';
  2628. buf[4] := super_hex_chars[ord(c) shr 4];
  2629. buf[5] := super_hex_chars[ord(c) and $f];
  2630. Append(buf, 6);
  2631. inc(pos);
  2632. start_offset := pos;
  2633. end else
  2634. inc(pos);
  2635. end;
  2636. end;
  2637. if(pos - start_offset > 0) then
  2638. writer.Append(str + start_offset, pos - start_offset);
  2639. Result := 0;
  2640. end;
  2641. function DoMinimalEscape(str: PSOChar; len: Integer): Integer;
  2642. var
  2643. pos, start_offset: Integer;
  2644. c: SOChar;
  2645. type
  2646. TByteChar = record
  2647. case integer of
  2648. 0: (a, b: Byte);
  2649. 1: (c: WideChar);
  2650. end;
  2651. begin
  2652. if str = nil then
  2653. begin
  2654. Result := 0;
  2655. exit;
  2656. end;
  2657. pos := 0; start_offset := 0;
  2658. with writer do
  2659. while pos < len do
  2660. begin
  2661. c := str[pos];
  2662. case c of
  2663. #0:
  2664. begin
  2665. if(pos - start_offset > 0) then
  2666. Append(str + start_offset, pos - start_offset);
  2667. Append(ESC_ZERO, 6);
  2668. inc(pos);
  2669. start_offset := pos;
  2670. end;
  2671. '"':
  2672. begin
  2673. if(pos - start_offset > 0) then
  2674. Append(str + start_offset, pos - start_offset);
  2675. Append(ESC_QUOT, 2);
  2676. inc(pos);
  2677. start_offset := pos;
  2678. end;
  2679. '\':
  2680. begin
  2681. if(pos - start_offset > 0) then
  2682. Append(str + start_offset, pos - start_offset);
  2683. Append(ESC_SL, 2);
  2684. inc(pos);
  2685. start_offset := pos;
  2686. end;
  2687. else
  2688. inc(pos);
  2689. end;
  2690. end;
  2691. if(pos - start_offset > 0) then
  2692. writer.Append(str + start_offset, pos - start_offset);
  2693. Result := 0;
  2694. end;
  2695. procedure _indent(i: shortint; r: boolean);
  2696. begin
  2697. inc(level, i);
  2698. if r then
  2699. with writer do
  2700. begin
  2701. {$IFDEF MSWINDOWS}
  2702. Append(TOK_CRLF, 2);
  2703. {$ELSE}
  2704. Append(TOK_LF, 1);
  2705. {$ENDIF}
  2706. for i := 0 to level - 1 do
  2707. Append(TOK_SP, 1);
  2708. end;
  2709. end;
  2710. var
  2711. k,j: Integer;
  2712. iter: TSuperObjectIter;
  2713. st: AnsiString;
  2714. val: ISuperObject;
  2715. const
  2716. ENDSTR_A: PSOChar = '": ';
  2717. ENDSTR_B: PSOChar = '":';
  2718. begin
  2719. if FProcessing then
  2720. begin
  2721. Result := writer.Append(TOK_NULL, 4);
  2722. Exit;
  2723. end;
  2724. FProcessing := true;
  2725. with writer do
  2726. try
  2727. case FDataType of
  2728. stObject:
  2729. if FO.c_object.FCount > 0 then
  2730. begin
  2731. k := 0;
  2732. Append(TOK_CBL, 1);
  2733. if indent then _indent(1, false);
  2734. if ObjectFindFirst(Self, iter) then
  2735. repeat
  2736. {$IFDEF SUPER_METHOD}
  2737. if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then
  2738. begin
  2739. {$ENDIF}
  2740. if (iter.val = nil) or (not iter.val.Processing) then
  2741. begin
  2742. if(k <> 0) then
  2743. Append(TOK_COM, 1);
  2744. if indent then _indent(0, true);
  2745. Append(TOK_DQT, 1);
  2746. if escape then
  2747. doEscape(PSOChar(iter.key), Length(iter.key)) else
  2748. DoMinimalEscape(PSOChar(iter.key), Length(iter.key));
  2749. if indent then
  2750. Append(ENDSTR_A, 3) else
  2751. Append(ENDSTR_B, 2);
  2752. if(iter.val = nil) then
  2753. Append(TOK_NULL, 4) else
  2754. iter.val.write(writer, indent, escape, level);
  2755. inc(k);
  2756. end;
  2757. {$IFDEF SUPER_METHOD}
  2758. end;
  2759. {$ENDIF}
  2760. until not ObjectFindNext(iter);
  2761. ObjectFindClose(iter);
  2762. if indent then _indent(-1, true);
  2763. Result := Append(TOK_CBR, 1);
  2764. end else
  2765. Result := Append(TOK_OBJ, 2);
  2766. stBoolean:
  2767. begin
  2768. if (FO.c_boolean) then
  2769. Result := Append(TOK_TRUE, 4) else
  2770. Result := Append(TOK_FALSE, 5);
  2771. end;
  2772. stInt:
  2773. begin
  2774. str(FO.c_int, st);
  2775. Result := Append(PSOChar(SOString(st)));
  2776. end;
  2777. stDouble:
  2778. Result := Append(PSOChar(FloatToJson(FO.c_double)));
  2779. stCurrency:
  2780. begin
  2781. Result := Append(PSOChar(CurrToJson(FO.c_currency)));
  2782. end;
  2783. stString:
  2784. begin
  2785. Append(TOK_DQT, 1);
  2786. if escape then
  2787. doEscape(PSOChar(FOString), Length(FOString)) else
  2788. DoMinimalEscape(PSOChar(FOString), Length(FOString));
  2789. Append(TOK_DQT, 1);
  2790. Result := 0;
  2791. end;
  2792. stArray:
  2793. if FO.c_array.FLength > 0 then
  2794. begin
  2795. Append(TOK_ARL, 1);
  2796. if indent then _indent(1, true);
  2797. k := 0;
  2798. j := 0;
  2799. while k < FO.c_array.FLength do
  2800. begin
  2801. val := FO.c_array.GetO(k);
  2802. {$IFDEF SUPER_METHOD}
  2803. if not ObjectIsType(val, stMethod) then
  2804. begin
  2805. {$ENDIF}
  2806. if (val = nil) or (not val.Processing) then
  2807. begin
  2808. if (j <> 0) then
  2809. Append(TOK_COM, 1);
  2810. if(val = nil) then
  2811. Append(TOK_NULL, 4) else
  2812. val.write(writer, indent, escape, level);
  2813. inc(j);
  2814. end;
  2815. {$IFDEF SUPER_METHOD}
  2816. end;
  2817. {$ENDIF}
  2818. inc(k);
  2819. end;
  2820. if indent then _indent(-1, false);
  2821. Result := Append(TOK_ARR, 1);
  2822. end else
  2823. Result := Append(TOK_ARRAY, 2);
  2824. stNull:
  2825. Result := Append(TOK_NULL, 4);
  2826. else
  2827. Result := 0;
  2828. end;
  2829. finally
  2830. FProcessing := false;
  2831. end;
  2832. end;
  2833. function TSuperObject.IsType(AType: TSuperType): boolean;
  2834. begin
  2835. Result := AType = FDataType;
  2836. end;
  2837. function TSuperObject.AsBoolean: boolean;
  2838. begin
  2839. case FDataType of
  2840. stBoolean: Result := FO.c_boolean;
  2841. stInt: Result := (FO.c_int <> 0);
  2842. stDouble: Result := (FO.c_double <> 0);
  2843. stCurrency: Result := (FO.c_currency <> 0);
  2844. stString: Result := (Length(FOString) <> 0);
  2845. stNull: Result := False;
  2846. else
  2847. Result := True;
  2848. end;
  2849. end;
  2850. function TSuperObject.AsInteger: SuperInt;
  2851. var
  2852. code: integer;
  2853. cint: SuperInt;
  2854. begin
  2855. case FDataType of
  2856. stInt: Result := FO.c_int;
  2857. stDouble: Result := round(FO.c_double);
  2858. stCurrency: Result := round(FO.c_currency);
  2859. stBoolean: Result := ord(FO.c_boolean);
  2860. stString:
  2861. begin
  2862. Val(FOString, cint, code);
  2863. if code = 0 then
  2864. Result := cint else
  2865. Result := 0;
  2866. end;
  2867. else
  2868. Result := 0;
  2869. end;
  2870. end;
  2871. function TSuperObject.AsDouble: Double;
  2872. var
  2873. code: integer;
  2874. cdouble: double;
  2875. begin
  2876. case FDataType of
  2877. stDouble: Result := FO.c_double;
  2878. stCurrency: Result := FO.c_currency;
  2879. stInt: Result := FO.c_int;
  2880. stBoolean: Result := ord(FO.c_boolean);
  2881. stString:
  2882. begin
  2883. Val(FOString, cdouble, code);
  2884. if code = 0 then
  2885. Result := cdouble else
  2886. Result := 0.0;
  2887. end;
  2888. else
  2889. Result := 0.0;
  2890. end;
  2891. end;
  2892. function TSuperObject.AsCurrency: Currency;
  2893. var
  2894. code: integer;
  2895. cdouble: double;
  2896. begin
  2897. case FDataType of
  2898. stDouble: Result := FO.c_double;
  2899. stCurrency: Result := FO.c_currency;
  2900. stInt: Result := FO.c_int;
  2901. stBoolean: Result := ord(FO.c_boolean);
  2902. stString:
  2903. begin
  2904. Val(FOString, cdouble, code);
  2905. if code = 0 then
  2906. Result := cdouble else
  2907. Result := 0.0;
  2908. end;
  2909. else
  2910. Result := 0.0;
  2911. end;
  2912. end;
  2913. function TSuperObject.AsString: SOString;
  2914. begin
  2915. case FDataType of
  2916. stString: Result := FOString;
  2917. stNull: Result := '';
  2918. else
  2919. Result := AsJSon(false, false);
  2920. end;
  2921. end;
  2922. function TSuperObject.GetEnumerator: TSuperEnumerator;
  2923. begin
  2924. Result := TSuperEnumerator.Create(Self);
  2925. end;
  2926. procedure TSuperObject.AfterConstruction;
  2927. begin
  2928. InterlockedDecrement(FRefCount);
  2929. end;
  2930. procedure TSuperObject.BeforeDestruction;
  2931. begin
  2932. if RefCount <> 0 then
  2933. raise Exception.Create('Invalid pointer');
  2934. end;
  2935. function TSuperObject.AsArray: TSuperArray;
  2936. begin
  2937. if FDataType = stArray then
  2938. Result := FO.c_array else
  2939. Result := nil;
  2940. end;
  2941. function TSuperObject.AsObject: TSuperTableString;
  2942. begin
  2943. if FDataType = stObject then
  2944. Result := FO.c_object else
  2945. Result := nil;
  2946. end;
  2947. function TSuperObject.AsJSon(indent, escape: boolean): SOString;
  2948. var
  2949. pb: TSuperWriterString;
  2950. begin
  2951. pb := TSuperWriterString.Create;
  2952. try
  2953. if(Write(pb, indent, escape, 0) < 0) then
  2954. begin
  2955. Result := '';
  2956. Exit;
  2957. end;
  2958. if pb.FBPos > 0 then
  2959. Result := pb.FBuf else
  2960. Result := '';
  2961. finally
  2962. pb.Free;
  2963. end;
  2964. end;
  2965. class function TSuperObject.ParseString(s: PSOChar; strict: Boolean; partial: boolean; const this: ISuperObject;
  2966. options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;
  2967. var
  2968. tok: TSuperTokenizer;
  2969. obj: ISuperObject;
  2970. begin
  2971. tok := TSuperTokenizer.Create;
  2972. obj := ParseEx(tok, s, -1, strict, this, options, put, dt);
  2973. if(tok.err <> teSuccess) or (not partial and (s[tok.char_offset] <> #0)) then
  2974. Result := nil else
  2975. Result := obj;
  2976. tok.Free;
  2977. end;
  2978. class function TSuperObject.ParseStream(stream: TStream; strict: Boolean;
  2979. partial: boolean; const this: ISuperObject; options: TSuperFindOptions;
  2980. const put: ISuperObject; dt: TSuperType): ISuperObject;
  2981. const
  2982. BUFFER_SIZE = 10240;
  2983. var
  2984. tok: TSuperTokenizer;
  2985. buffera: array[0..BUFFER_SIZE-1] of AnsiChar;
  2986. bufferw: array[0..BUFFER_SIZE-1] of SOChar;
  2987. bom: array[0..1] of byte;
  2988. unicode: boolean;
  2989. j, size: Integer;
  2990. st: string;
  2991. begin
  2992. st := '';
  2993. tok := TSuperTokenizer.Create;
  2994. if (stream.Read(bom, sizeof(bom)) = 2) and (bom[0] = $FF) and (bom[1] = $FE) then
  2995. begin
  2996. unicode := true;
  2997. size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);
  2998. end else
  2999. begin
  3000. unicode := false;
  3001. stream.Seek(0, soFromBeginning);
  3002. size := stream.Read(buffera, BUFFER_SIZE);
  3003. end;
  3004. while size > 0 do
  3005. begin
  3006. if not unicode then
  3007. for j := 0 to size - 1 do
  3008. bufferw[j] := SOChar(buffera[j]);
  3009. ParseEx(tok, bufferw, size, strict, this, options, put, dt);
  3010. if tok.err = teContinue then
  3011. begin
  3012. if not unicode then
  3013. size := stream.Read(buffera, BUFFER_SIZE) else
  3014. size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);
  3015. end else
  3016. Break;
  3017. end;
  3018. if(tok.err <> teSuccess) or (not partial and (st[tok.char_offset] <> #0)) then
  3019. Result := nil else
  3020. Result := tok.stack[tok.depth].current;
  3021. tok.Free;
  3022. end;
  3023. class function TSuperObject.ParseFile(const FileName: string; strict: Boolean;
  3024. partial: boolean; const this: ISuperObject; options: TSuperFindOptions;
  3025. const put: ISuperObject; dt: TSuperType): ISuperObject;
  3026. var
  3027. stream: TFileStream;
  3028. begin
  3029. stream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyNone);
  3030. try
  3031. Result := ParseStream(stream, strict, partial, this, options, put, dt);
  3032. finally
  3033. stream.Free;
  3034. end;
  3035. end;
  3036. class function TSuperObject.ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer;
  3037. strict: Boolean; const this: ISuperObject; options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;
  3038. const
  3039. spaces = [#32,#8,#9,#10,#12,#13];
  3040. delimiters = ['"', '.', '[', ']', '{', '}', '(', ')', ',', ':', #0];
  3041. reserved = delimiters + spaces;
  3042. path = ['a'..'z', 'A'..'Z', '.', '_'];
  3043. function hexdigit(x: SOChar): byte; {$IFDEF HAVE_INLINE} inline;{$ENDIF}
  3044. begin
  3045. if x <= '9' then
  3046. Result := byte(x) - byte('0') else
  3047. Result := (byte(x) and 7) + 9;
  3048. end;
  3049. function min(v1, v2: integer): integer;{$IFDEF HAVE_INLINE} inline;{$ENDIF}
  3050. begin if v1 < v2 then result := v1 else result := v2 end;
  3051. var
  3052. obj: ISuperObject;
  3053. v: SOChar;
  3054. {$IFDEF SUPER_METHOD}
  3055. sm: TSuperMethod;
  3056. {$ENDIF}
  3057. numi: SuperInt;
  3058. numd: Double;
  3059. code: integer;
  3060. TokRec: PSuperTokenerSrec;
  3061. evalstack: integer;
  3062. p: PSOChar;
  3063. function IsEndDelimiter(v: AnsiChar): Boolean;
  3064. begin
  3065. if tok.depth > 0 then
  3066. case tok.stack[tok.depth - 1].state of
  3067. tsArrayAdd: Result := v in [',', ']', #0];
  3068. tsObjectValueAdd: Result := v in [',', '}', #0];
  3069. else
  3070. Result := v = #0;
  3071. end else
  3072. Result := v = #0;
  3073. end;
  3074. label out, redo_char;
  3075. begin
  3076. evalstack := 0;
  3077. obj := nil;
  3078. Result := nil;
  3079. TokRec := @tok.stack[tok.depth];
  3080. tok.char_offset := 0;
  3081. tok.err := teSuccess;
  3082. repeat
  3083. if (tok.char_offset = len) then
  3084. begin
  3085. if (tok.depth = 0) and (TokRec^.state = tsEatws) and
  3086. (TokRec^.saved_state = tsFinish) then
  3087. tok.err := teSuccess else
  3088. tok.err := teContinue;
  3089. goto out;
  3090. end;
  3091. v := str^;
  3092. case v of
  3093. #10:
  3094. begin
  3095. inc(tok.line);
  3096. tok.col := 0;
  3097. end;
  3098. #9: inc(tok.col, 4);
  3099. else
  3100. inc(tok.col);
  3101. end;
  3102. redo_char:
  3103. case TokRec^.state of
  3104. tsEatws:
  3105. begin
  3106. if (SOIChar(v) < 256) and (AnsiChar(v) in spaces) then {nop} else
  3107. if (v = '/') then
  3108. begin
  3109. tok.pb.Reset;
  3110. tok.pb.Append(@v, 1);
  3111. TokRec^.state := tsCommentStart;
  3112. end else begin
  3113. TokRec^.state := TokRec^.saved_state;
  3114. goto redo_char;
  3115. end
  3116. end;
  3117. tsStart:
  3118. case v of
  3119. '"',
  3120. '''':
  3121. begin
  3122. TokRec^.state := tsString;
  3123. tok.pb.Reset;
  3124. tok.quote_char := v;
  3125. end;
  3126. '-':
  3127. begin
  3128. TokRec^.state := tsNumber;
  3129. tok.pb.Reset;
  3130. tok.is_double := 0;
  3131. tok.floatcount := -1;
  3132. goto redo_char;
  3133. end;
  3134. '0'..'9':
  3135. begin
  3136. if (tok.depth = 0) then
  3137. case ObjectGetType(this) of
  3138. stObject:
  3139. begin
  3140. TokRec^.state := tsIdentifier;
  3141. TokRec^.current := this;
  3142. goto redo_char;
  3143. end;
  3144. end;
  3145. TokRec^.state := tsNumber;
  3146. tok.pb.Reset;
  3147. tok.is_double := 0;
  3148. tok.floatcount := -1;
  3149. goto redo_char;
  3150. end;
  3151. '{':
  3152. begin
  3153. TokRec^.state := tsEatws;
  3154. TokRec^.saved_state := tsObjectFieldStart;
  3155. TokRec^.current := TSuperObject.Create(stObject);
  3156. end;
  3157. '[':
  3158. begin
  3159. TokRec^.state := tsEatws;
  3160. TokRec^.saved_state := tsArray;
  3161. TokRec^.current := TSuperObject.Create(stArray);
  3162. end;
  3163. {$IFDEF SUPER_METHOD}
  3164. '(':
  3165. begin
  3166. if (tok.depth = 0) and ObjectIsType(this, stMethod) then
  3167. begin
  3168. TokRec^.current := this;
  3169. TokRec^.state := tsParamValue;
  3170. end;
  3171. end;
  3172. {$ENDIF}
  3173. 'N',
  3174. 'n':
  3175. begin
  3176. TokRec^.state := tsNull;
  3177. tok.pb.Reset;
  3178. tok.st_pos := 0;
  3179. goto redo_char;
  3180. end;
  3181. 'T',
  3182. 't',
  3183. 'F',
  3184. 'f':
  3185. begin
  3186. TokRec^.state := tsBoolean;
  3187. tok.pb.Reset;
  3188. tok.st_pos := 0;
  3189. goto redo_char;
  3190. end;
  3191. else
  3192. TokRec^.state := tsIdentifier;
  3193. tok.pb.Reset;
  3194. goto redo_char;
  3195. end;
  3196. tsFinish:
  3197. begin
  3198. if(tok.depth = 0) then goto out;
  3199. obj := TokRec^.current;
  3200. tok.ResetLevel(tok.depth);
  3201. dec(tok.depth);
  3202. TokRec := @tok.stack[tok.depth];
  3203. goto redo_char;
  3204. end;
  3205. tsNull:
  3206. begin
  3207. tok.pb.Append(@v, 1);
  3208. if (StrLComp(TOK_NULL, PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then
  3209. begin
  3210. if (tok.st_pos = 4) then
  3211. if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then
  3212. TokRec^.state := tsIdentifier else
  3213. begin
  3214. TokRec^.current := TSuperObject.Create(stNull);
  3215. TokRec^.saved_state := tsFinish;
  3216. TokRec^.state := tsEatws;
  3217. goto redo_char;
  3218. end;
  3219. end else
  3220. begin
  3221. TokRec^.state := tsIdentifier;
  3222. tok.pb.FBuf[tok.st_pos] := #0;
  3223. dec(tok.pb.FBPos);
  3224. goto redo_char;
  3225. end;
  3226. inc(tok.st_pos);
  3227. end;
  3228. tsCommentStart:
  3229. begin
  3230. if(v = '*') then
  3231. begin
  3232. TokRec^.state := tsComment;
  3233. end else
  3234. if (v = '/') then
  3235. begin
  3236. TokRec^.state := tsCommentEol;
  3237. end else
  3238. begin
  3239. tok.err := teParseComment;
  3240. goto out;
  3241. end;
  3242. tok.pb.Append(@v, 1);
  3243. end;
  3244. tsComment:
  3245. begin
  3246. if(v = '*') then
  3247. TokRec^.state := tsCommentEnd;
  3248. tok.pb.Append(@v, 1);
  3249. end;
  3250. tsCommentEol:
  3251. begin
  3252. if (v = #10) then
  3253. TokRec^.state := tsEatws else
  3254. tok.pb.Append(@v, 1);
  3255. end;
  3256. tsCommentEnd:
  3257. begin
  3258. tok.pb.Append(@v, 1);
  3259. if (v = '/') then
  3260. TokRec^.state := tsEatws else
  3261. TokRec^.state := tsComment;
  3262. end;
  3263. tsString:
  3264. begin
  3265. if (v = tok.quote_char) then
  3266. begin
  3267. TokRec^.current := TSuperObject.Create(SOString(tok.pb.GetString));
  3268. TokRec^.saved_state := tsFinish;
  3269. TokRec^.state := tsEatws;
  3270. end else
  3271. if (v = '\') then
  3272. begin
  3273. TokRec^.saved_state := tsString;
  3274. TokRec^.state := tsStringEscape;
  3275. end else
  3276. begin
  3277. tok.pb.Append(@v, 1);
  3278. end
  3279. end;
  3280. tsEvalProperty:
  3281. begin
  3282. if (TokRec^.current = nil) and (foCreatePath in options) then
  3283. begin
  3284. TokRec^.current := TSuperObject.Create(stObject);
  3285. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)
  3286. end else
  3287. if not ObjectIsType(TokRec^.current, stObject) then
  3288. begin
  3289. tok.err := teEvalObject;
  3290. goto out;
  3291. end;
  3292. tok.pb.Reset;
  3293. TokRec^.state := tsIdentifier;
  3294. goto redo_char;
  3295. end;
  3296. tsEvalArray:
  3297. begin
  3298. if (TokRec^.current = nil) and (foCreatePath in options) then
  3299. begin
  3300. TokRec^.current := TSuperObject.Create(stArray);
  3301. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)
  3302. end else
  3303. if not ObjectIsType(TokRec^.current, stArray) then
  3304. begin
  3305. tok.err := teEvalArray;
  3306. goto out;
  3307. end;
  3308. tok.pb.Reset;
  3309. TokRec^.state := tsParamValue;
  3310. goto redo_char;
  3311. end;
  3312. {$IFDEF SUPER_METHOD}
  3313. tsEvalMethod:
  3314. begin
  3315. if ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then
  3316. begin
  3317. tok.pb.Reset;
  3318. TokRec^.obj := TSuperObject.Create(stArray);
  3319. TokRec^.state := tsMethodValue;
  3320. goto redo_char;
  3321. end else
  3322. begin
  3323. tok.err := teEvalMethod;
  3324. goto out;
  3325. end;
  3326. end;
  3327. tsMethodValue:
  3328. begin
  3329. case v of
  3330. ')':
  3331. TokRec^.state := tsIdentifier;
  3332. else
  3333. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then
  3334. begin
  3335. tok.err := teDepth;
  3336. goto out;
  3337. end;
  3338. inc(evalstack);
  3339. TokRec^.state := tsMethodPut;
  3340. inc(tok.depth);
  3341. tok.ResetLevel(tok.depth);
  3342. TokRec := @tok.stack[tok.depth];
  3343. goto redo_char;
  3344. end;
  3345. end;
  3346. tsMethodPut:
  3347. begin
  3348. TokRec^.obj.AsArray.Add(obj);
  3349. case v of
  3350. ',':
  3351. begin
  3352. tok.pb.Reset;
  3353. TokRec^.saved_state := tsMethodValue;
  3354. TokRec^.state := tsEatws;
  3355. end;
  3356. ')':
  3357. begin
  3358. if TokRec^.obj.AsArray.Length = 1 then
  3359. TokRec^.obj := TokRec^.obj.AsArray.GetO(0);
  3360. dec(evalstack);
  3361. tok.pb.Reset;
  3362. TokRec^.saved_state := tsIdentifier;
  3363. TokRec^.state := tsEatws;
  3364. end;
  3365. else
  3366. tok.err := teEvalMethod;
  3367. goto out;
  3368. end;
  3369. end;
  3370. {$ENDIF}
  3371. tsParamValue:
  3372. begin
  3373. case v of
  3374. ']':
  3375. TokRec^.state := tsIdentifier;
  3376. else
  3377. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then
  3378. begin
  3379. tok.err := teDepth;
  3380. goto out;
  3381. end;
  3382. inc(evalstack);
  3383. TokRec^.state := tsParamPut;
  3384. inc(tok.depth);
  3385. tok.ResetLevel(tok.depth);
  3386. TokRec := @tok.stack[tok.depth];
  3387. goto redo_char;
  3388. end;
  3389. end;
  3390. tsParamPut:
  3391. begin
  3392. dec(evalstack);
  3393. TokRec^.obj := obj;
  3394. tok.pb.Reset;
  3395. TokRec^.saved_state := tsIdentifier;
  3396. TokRec^.state := tsEatws;
  3397. if v <> ']' then
  3398. begin
  3399. tok.err := teEvalArray;
  3400. goto out;
  3401. end;
  3402. end;
  3403. tsIdentifier:
  3404. begin
  3405. if (this = nil) then
  3406. begin
  3407. if (SOIChar(v) < 256) and IsEndDelimiter(AnsiChar(v)) then
  3408. begin
  3409. if not strict then
  3410. begin
  3411. tok.pb.TrimRight;
  3412. TokRec^.current := TSuperObject.Create(tok.pb.Fbuf);
  3413. TokRec^.saved_state := tsFinish;
  3414. TokRec^.state := tsEatws;
  3415. goto redo_char;
  3416. end else
  3417. begin
  3418. tok.err := teParseString;
  3419. goto out;
  3420. end;
  3421. end else
  3422. if (v = '\') then
  3423. begin
  3424. TokRec^.saved_state := tsIdentifier;
  3425. TokRec^.state := tsStringEscape;
  3426. end else
  3427. tok.pb.Append(@v, 1);
  3428. end else
  3429. begin
  3430. if (SOIChar(v) < 256) and (AnsiChar(v) in reserved) then
  3431. begin
  3432. TokRec^.gparent := TokRec^.parent;
  3433. if TokRec^.current = nil then
  3434. TokRec^.parent := this else
  3435. TokRec^.parent := TokRec^.current;
  3436. case ObjectGetType(TokRec^.parent) of
  3437. stObject:
  3438. case v of
  3439. '.':
  3440. begin
  3441. TokRec^.state := tsEvalProperty;
  3442. if tok.pb.FBPos > 0 then
  3443. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  3444. end;
  3445. '[':
  3446. begin
  3447. TokRec^.state := tsEvalArray;
  3448. if tok.pb.FBPos > 0 then
  3449. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  3450. end;
  3451. '(':
  3452. begin
  3453. TokRec^.state := tsEvalMethod;
  3454. if tok.pb.FBPos > 0 then
  3455. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  3456. end;
  3457. else
  3458. if tok.pb.FBPos > 0 then
  3459. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  3460. if (foPutValue in options) and (evalstack = 0) then
  3461. begin
  3462. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, put);
  3463. TokRec^.current := put
  3464. end else
  3465. if (foDelete in options) and (evalstack = 0) then
  3466. begin
  3467. TokRec^.current := TokRec^.parent.AsObject.Delete(tok.pb.Fbuf);
  3468. end else
  3469. if (TokRec^.current = nil) and (foCreatePath in options) then
  3470. begin
  3471. TokRec^.current := TSuperObject.Create(dt);
  3472. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current);
  3473. end;
  3474. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  3475. TokRec^.state := tsFinish;
  3476. goto redo_char;
  3477. end;
  3478. stArray:
  3479. begin
  3480. if TokRec^.obj <> nil then
  3481. begin
  3482. if not ObjectIsType(TokRec^.obj, stInt) or (TokRec^.obj.AsInteger < 0) then
  3483. begin
  3484. tok.err := teEvalInt;
  3485. TokRec^.obj := nil;
  3486. goto out;
  3487. end;
  3488. numi := TokRec^.obj.AsInteger;
  3489. TokRec^.obj := nil;
  3490. TokRec^.current := TokRec^.parent.AsArray.GetO(numi);
  3491. case v of
  3492. '.':
  3493. if (TokRec^.current = nil) and (foCreatePath in options) then
  3494. begin
  3495. TokRec^.current := TSuperObject.Create(stObject);
  3496. TokRec^.parent.AsArray.PutO(numi, TokRec^.current);
  3497. end else
  3498. if (TokRec^.current = nil) then
  3499. begin
  3500. tok.err := teEvalObject;
  3501. goto out;
  3502. end;
  3503. '[':
  3504. begin
  3505. if (TokRec^.current = nil) and (foCreatePath in options) then
  3506. begin
  3507. TokRec^.current := TSuperObject.Create(stArray);
  3508. TokRec^.parent.AsArray.Add(TokRec^.current);
  3509. end else
  3510. if (TokRec^.current = nil) then
  3511. begin
  3512. tok.err := teEvalArray;
  3513. goto out;
  3514. end;
  3515. TokRec^.state := tsEvalArray;
  3516. end;
  3517. '(': TokRec^.state := tsEvalMethod;
  3518. else
  3519. if (foPutValue in options) and (evalstack = 0) then
  3520. begin
  3521. TokRec^.parent.AsArray.PutO(numi, put);
  3522. TokRec^.current := put;
  3523. end else
  3524. if (foDelete in options) and (evalstack = 0) then
  3525. begin
  3526. TokRec^.current := TokRec^.parent.AsArray.Delete(numi);
  3527. end else
  3528. TokRec^.current := TokRec^.parent.AsArray.GetO(numi);
  3529. TokRec^.state := tsFinish;
  3530. goto redo_char
  3531. end;
  3532. end else
  3533. begin
  3534. case v of
  3535. '.':
  3536. begin
  3537. if (foPutValue in options) then
  3538. begin
  3539. TokRec^.current := TSuperObject.Create(stObject);
  3540. TokRec^.parent.AsArray.Add(TokRec^.current);
  3541. end else
  3542. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);
  3543. end;
  3544. '[':
  3545. begin
  3546. if (foPutValue in options) then
  3547. begin
  3548. TokRec^.current := TSuperObject.Create(stArray);
  3549. TokRec^.parent.AsArray.Add(TokRec^.current);
  3550. end else
  3551. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);
  3552. TokRec^.state := tsEvalArray;
  3553. end;
  3554. '(':
  3555. begin
  3556. if not (foPutValue in options) then
  3557. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1) else
  3558. TokRec^.current := nil;
  3559. TokRec^.state := tsEvalMethod;
  3560. end;
  3561. else
  3562. if (foPutValue in options) and (evalstack = 0) then
  3563. begin
  3564. TokRec^.parent.AsArray.Add(put);
  3565. TokRec^.current := put;
  3566. end else
  3567. if tok.pb.FBPos = 0 then
  3568. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);
  3569. TokRec^.state := tsFinish;
  3570. goto redo_char
  3571. end;
  3572. end;
  3573. end;
  3574. {$IFDEF SUPER_METHOD}
  3575. stMethod:
  3576. case v of
  3577. '.':
  3578. begin
  3579. TokRec^.current := nil;
  3580. sm := TokRec^.parent.AsMethod;
  3581. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  3582. TokRec^.obj := nil;
  3583. end;
  3584. '[':
  3585. begin
  3586. TokRec^.current := nil;
  3587. sm := TokRec^.parent.AsMethod;
  3588. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  3589. TokRec^.state := tsEvalArray;
  3590. TokRec^.obj := nil;
  3591. end;
  3592. '(':
  3593. begin
  3594. TokRec^.current := nil;
  3595. sm := TokRec^.parent.AsMethod;
  3596. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  3597. TokRec^.state := tsEvalMethod;
  3598. TokRec^.obj := nil;
  3599. end;
  3600. else
  3601. if not (foPutValue in options) or (evalstack > 0) then
  3602. begin
  3603. TokRec^.current := nil;
  3604. sm := TokRec^.parent.AsMethod;
  3605. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  3606. TokRec^.obj := nil;
  3607. TokRec^.state := tsFinish;
  3608. goto redo_char
  3609. end else
  3610. begin
  3611. tok.err := teEvalMethod;
  3612. TokRec^.obj := nil;
  3613. goto out;
  3614. end;
  3615. end;
  3616. {$ENDIF}
  3617. end;
  3618. end else
  3619. tok.pb.Append(@v, 1);
  3620. end;
  3621. end;
  3622. tsStringEscape:
  3623. case v of
  3624. 'b',
  3625. 'n',
  3626. 'r',
  3627. 't',
  3628. 'f':
  3629. begin
  3630. if(v = 'b') then tok.pb.Append(TOK_BS, 1)
  3631. else if(v = 'n') then tok.pb.Append(TOK_LF, 1)
  3632. else if(v = 'r') then tok.pb.Append(TOK_CR, 1)
  3633. else if(v = 't') then tok.pb.Append(TOK_TAB, 1)
  3634. else if(v = 'f') then tok.pb.Append(TOK_FF, 1);
  3635. TokRec^.state := TokRec^.saved_state;
  3636. end;
  3637. 'u':
  3638. begin
  3639. tok.ucs_char := 0;
  3640. tok.st_pos := 0;
  3641. TokRec^.state := tsEscapeUnicode;
  3642. end;
  3643. 'x':
  3644. begin
  3645. tok.ucs_char := 0;
  3646. tok.st_pos := 0;
  3647. TokRec^.state := tsEscapeHexadecimal;
  3648. end
  3649. else
  3650. tok.pb.Append(@v, 1);
  3651. TokRec^.state := TokRec^.saved_state;
  3652. end;
  3653. tsEscapeUnicode:
  3654. begin
  3655. if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then
  3656. begin
  3657. inc(tok.ucs_char, (Word(hexdigit(v)) shl ((3-tok.st_pos)*4)));
  3658. inc(tok.st_pos);
  3659. if (tok.st_pos = 4) then
  3660. begin
  3661. tok.pb.Append(@tok.ucs_char, 1);
  3662. TokRec^.state := TokRec^.saved_state;
  3663. end
  3664. end else
  3665. begin
  3666. tok.err := teParseString;
  3667. goto out;
  3668. end
  3669. end;
  3670. tsEscapeHexadecimal:
  3671. begin
  3672. if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then
  3673. begin
  3674. inc(tok.ucs_char, (Word(hexdigit(v)) shl ((1-tok.st_pos)*4)));
  3675. inc(tok.st_pos);
  3676. if (tok.st_pos = 2) then
  3677. begin
  3678. tok.pb.Append(@tok.ucs_char, 1);
  3679. TokRec^.state := TokRec^.saved_state;
  3680. end
  3681. end else
  3682. begin
  3683. tok.err := teParseString;
  3684. goto out;
  3685. end
  3686. end;
  3687. tsBoolean:
  3688. begin
  3689. tok.pb.Append(@v, 1);
  3690. if (StrLComp('true', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then
  3691. begin
  3692. if (tok.st_pos = 4) then
  3693. if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then
  3694. TokRec^.state := tsIdentifier else
  3695. begin
  3696. TokRec^.current := TSuperObject.Create(true);
  3697. TokRec^.saved_state := tsFinish;
  3698. TokRec^.state := tsEatws;
  3699. goto redo_char;
  3700. end
  3701. end else
  3702. if (StrLComp('false', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 5)) = 0) then
  3703. begin
  3704. if (tok.st_pos = 5) then
  3705. if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then
  3706. TokRec^.state := tsIdentifier else
  3707. begin
  3708. TokRec^.current := TSuperObject.Create(false);
  3709. TokRec^.saved_state := tsFinish;
  3710. TokRec^.state := tsEatws;
  3711. goto redo_char;
  3712. end
  3713. end else
  3714. begin
  3715. TokRec^.state := tsIdentifier;
  3716. tok.pb.FBuf[tok.st_pos] := #0;
  3717. dec(tok.pb.FBPos);
  3718. goto redo_char;
  3719. end;
  3720. inc(tok.st_pos);
  3721. end;
  3722. tsNumber:
  3723. begin
  3724. if (SOIChar(v) < 256) and (AnsiChar(v) in super_number_chars_set) then
  3725. begin
  3726. tok.pb.Append(@v, 1);
  3727. if (SOIChar(v) < 256) then
  3728. case v of
  3729. '.': begin
  3730. tok.is_double := 1;
  3731. tok.floatcount := 0;
  3732. end;
  3733. 'e','E':
  3734. begin
  3735. tok.is_double := 1;
  3736. tok.floatcount := -1;
  3737. end;
  3738. '0'..'9':
  3739. begin
  3740. if (tok.is_double = 1) and (tok.floatcount >= 0) then
  3741. begin
  3742. inc(tok.floatcount);
  3743. if tok.floatcount > 4 then
  3744. tok.floatcount := -1;
  3745. end;
  3746. end;
  3747. end;
  3748. end else
  3749. begin
  3750. if (tok.is_double = 0) then
  3751. begin
  3752. val(tok.pb.FBuf, numi, code);
  3753. if ObjectIsType(this, stArray) then
  3754. begin
  3755. if (foPutValue in options) and (evalstack = 0) then
  3756. begin
  3757. this.AsArray.PutO(numi, put);
  3758. TokRec^.current := put;
  3759. end else
  3760. if (foDelete in options) and (evalstack = 0) then
  3761. TokRec^.current := this.AsArray.Delete(numi) else
  3762. TokRec^.current := this.AsArray.GetO(numi);
  3763. end else
  3764. TokRec^.current := TSuperObject.Create(numi);
  3765. end else
  3766. if (tok.is_double <> 0) then
  3767. begin
  3768. if tok.floatcount >= 0 then
  3769. begin
  3770. p := tok.pb.FBuf;
  3771. while p^ <> '.' do inc(p);
  3772. for code := 0 to tok.floatcount - 1 do
  3773. begin
  3774. p^ := p[1];
  3775. inc(p);
  3776. end;
  3777. p^ := #0;
  3778. val(tok.pb.FBuf, numi, code);
  3779. case tok.floatcount of
  3780. 0: numi := numi * 10000;
  3781. 1: numi := numi * 1000;
  3782. 2: numi := numi * 100;
  3783. 3: numi := numi * 10;
  3784. end;
  3785. TokRec^.current := TSuperObject.CreateCurrency(PCurrency(@numi)^);
  3786. end else
  3787. begin
  3788. val(tok.pb.FBuf, numd, code);
  3789. TokRec^.current := TSuperObject.Create(numd);
  3790. end;
  3791. end else
  3792. begin
  3793. tok.err := teParseNumber;
  3794. goto out;
  3795. end;
  3796. TokRec^.saved_state := tsFinish;
  3797. TokRec^.state := tsEatws;
  3798. goto redo_char;
  3799. end
  3800. end;
  3801. tsArray:
  3802. begin
  3803. if (v = ']') then
  3804. begin
  3805. TokRec^.saved_state := tsFinish;
  3806. TokRec^.state := tsEatws;
  3807. end else
  3808. begin
  3809. if(tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then
  3810. begin
  3811. tok.err := teDepth;
  3812. goto out;
  3813. end;
  3814. TokRec^.state := tsArrayAdd;
  3815. inc(tok.depth);
  3816. tok.ResetLevel(tok.depth);
  3817. TokRec := @tok.stack[tok.depth];
  3818. goto redo_char;
  3819. end
  3820. end;
  3821. tsArrayAdd:
  3822. begin
  3823. TokRec^.current.AsArray.Add(obj);
  3824. TokRec^.saved_state := tsArraySep;
  3825. TokRec^.state := tsEatws;
  3826. goto redo_char;
  3827. end;
  3828. tsArraySep:
  3829. begin
  3830. if (v = ']') then
  3831. begin
  3832. TokRec^.saved_state := tsFinish;
  3833. TokRec^.state := tsEatws;
  3834. end else
  3835. if (v = ',') then
  3836. begin
  3837. TokRec^.saved_state := tsArray;
  3838. TokRec^.state := tsEatws;
  3839. end else
  3840. begin
  3841. tok.err := teParseArray;
  3842. goto out;
  3843. end
  3844. end;
  3845. tsObjectFieldStart:
  3846. begin
  3847. if (v = '}') then
  3848. begin
  3849. TokRec^.saved_state := tsFinish;
  3850. TokRec^.state := tsEatws;
  3851. end else
  3852. if (SOIChar(v) < 256) and (AnsiChar(v) in ['"', '''']) then
  3853. begin
  3854. tok.quote_char := v;
  3855. tok.pb.Reset;
  3856. TokRec^.state := tsObjectField;
  3857. end else
  3858. if not((SOIChar(v) < 256) and ((AnsiChar(v) in reserved) or strict)) then
  3859. begin
  3860. TokRec^.state := tsObjectUnquotedField;
  3861. tok.pb.Reset;
  3862. goto redo_char;
  3863. end else
  3864. begin
  3865. tok.err := teParseObjectKeyName;
  3866. goto out;
  3867. end
  3868. end;
  3869. tsObjectField:
  3870. begin
  3871. if (v = tok.quote_char) then
  3872. begin
  3873. TokRec^.field_name := tok.pb.FBuf;
  3874. TokRec^.saved_state := tsObjectFieldEnd;
  3875. TokRec^.state := tsEatws;
  3876. end else
  3877. if (v = '\') then
  3878. begin
  3879. TokRec^.saved_state := tsObjectField;
  3880. TokRec^.state := tsStringEscape;
  3881. end else
  3882. begin
  3883. tok.pb.Append(@v, 1);
  3884. end
  3885. end;
  3886. tsObjectUnquotedField:
  3887. begin
  3888. if (SOIChar(v) < 256) and (AnsiChar(v) in [':', #0]) then
  3889. begin
  3890. TokRec^.field_name := tok.pb.FBuf;
  3891. TokRec^.saved_state := tsObjectFieldEnd;
  3892. TokRec^.state := tsEatws;
  3893. goto redo_char;
  3894. end else
  3895. if (v = '\') then
  3896. begin
  3897. TokRec^.saved_state := tsObjectUnquotedField;
  3898. TokRec^.state := tsStringEscape;
  3899. end else
  3900. tok.pb.Append(@v, 1);
  3901. end;
  3902. tsObjectFieldEnd:
  3903. begin
  3904. if (v = ':') then
  3905. begin
  3906. TokRec^.saved_state := tsObjectValue;
  3907. TokRec^.state := tsEatws;
  3908. end else
  3909. begin
  3910. tok.err := teParseObjectKeySep;
  3911. goto out;
  3912. end
  3913. end;
  3914. tsObjectValue:
  3915. begin
  3916. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then
  3917. begin
  3918. tok.err := teDepth;
  3919. goto out;
  3920. end;
  3921. TokRec^.state := tsObjectValueAdd;
  3922. inc(tok.depth);
  3923. tok.ResetLevel(tok.depth);
  3924. TokRec := @tok.stack[tok.depth];
  3925. goto redo_char;
  3926. end;
  3927. tsObjectValueAdd:
  3928. begin
  3929. TokRec^.current.AsObject.PutO(TokRec^.field_name, obj);
  3930. TokRec^.field_name := '';
  3931. TokRec^.saved_state := tsObjectSep;
  3932. TokRec^.state := tsEatws;
  3933. goto redo_char;
  3934. end;
  3935. tsObjectSep:
  3936. begin
  3937. if (v = '}') then
  3938. begin
  3939. TokRec^.saved_state := tsFinish;
  3940. TokRec^.state := tsEatws;
  3941. end else
  3942. if (v = ',') then
  3943. begin
  3944. TokRec^.saved_state := tsObjectFieldStart;
  3945. TokRec^.state := tsEatws;
  3946. end else
  3947. begin
  3948. tok.err := teParseObjectValueSep;
  3949. goto out;
  3950. end
  3951. end;
  3952. end;
  3953. inc(str);
  3954. inc(tok.char_offset);
  3955. until v = #0;
  3956. if(TokRec^.state <> tsFinish) and
  3957. (TokRec^.saved_state <> tsFinish) then
  3958. tok.err := teParseEof;
  3959. out:
  3960. if(tok.err in [teSuccess]) then
  3961. begin
  3962. {$IFDEF SUPER_METHOD}
  3963. if (foCallMethod in options) and ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then
  3964. begin
  3965. sm := TokRec^.current.AsMethod;
  3966. sm(TokRec^.parent, put, Result);
  3967. end else
  3968. {$ENDIF}
  3969. Result := TokRec^.current;
  3970. end else
  3971. Result := nil;
  3972. end;
  3973. procedure TSuperObject.PutO(const path: SOString; const Value: ISuperObject);
  3974. begin
  3975. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], Value);
  3976. end;
  3977. procedure TSuperObject.PutB(const path: SOString; Value: Boolean);
  3978. begin
  3979. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3980. end;
  3981. procedure TSuperObject.PutD(const path: SOString; Value: Double);
  3982. begin
  3983. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3984. end;
  3985. procedure TSuperObject.PutC(const path: SOString; Value: Currency);
  3986. begin
  3987. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.CreateCurrency(Value));
  3988. end;
  3989. procedure TSuperObject.PutI(const path: SOString; Value: SuperInt);
  3990. begin
  3991. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3992. end;
  3993. procedure TSuperObject.PutS(const path: SOString; const Value: SOString);
  3994. begin
  3995. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3996. end;
  3997. {$IFDEF FPC}
  3998. function TSuperObject.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: tguid; out obj): longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  3999. {$ELSE}
  4000. function TSuperObject.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  4001. {$ENDIF}
  4002. begin
  4003. if GetInterface(IID, Obj) then
  4004. Result := 0
  4005. else
  4006. Result := E_NOINTERFACE;
  4007. end;
  4008. function TSuperObject.SaveTo(stream: TStream; indent, escape: boolean): integer;
  4009. var
  4010. pb: TSuperWriterStream;
  4011. begin
  4012. if escape then
  4013. pb := TSuperAnsiWriterStream.Create(stream) else
  4014. pb := TSuperUnicodeWriterStream.Create(stream);
  4015. if(Write(pb, indent, escape, 0) < 0) then
  4016. begin
  4017. pb.Reset;
  4018. pb.Free;
  4019. Result := 0;
  4020. Exit;
  4021. end;
  4022. Result := stream.Size;
  4023. pb.Free;
  4024. end;
  4025. function TSuperObject.CalcSize(indent, escape: boolean): integer;
  4026. var
  4027. pb: TSuperWriterFake;
  4028. begin
  4029. pb := TSuperWriterFake.Create;
  4030. if(Write(pb, indent, escape, 0) < 0) then
  4031. begin
  4032. pb.Free;
  4033. Result := 0;
  4034. Exit;
  4035. end;
  4036. Result := pb.FSize;
  4037. pb.Free;
  4038. end;
  4039. function TSuperObject.SaveTo(socket: Integer; indent, escape: boolean): integer;
  4040. var
  4041. pb: TSuperWriterSock;
  4042. begin
  4043. pb := TSuperWriterSock.Create(socket);
  4044. if(Write(pb, indent, escape, 0) < 0) then
  4045. begin
  4046. pb.Free;
  4047. Result := 0;
  4048. Exit;
  4049. end;
  4050. Result := pb.FSize;
  4051. pb.Free;
  4052. end;
  4053. constructor TSuperObject.Create(const s: SOString);
  4054. begin
  4055. Create(stString);
  4056. FOString := s;
  4057. end;
  4058. procedure TSuperObject.Clear(all: boolean);
  4059. begin
  4060. if FProcessing then exit;
  4061. FProcessing := true;
  4062. try
  4063. case FDataType of
  4064. stBoolean: FO.c_boolean := false;
  4065. stDouble: FO.c_double := 0.0;
  4066. stCurrency: FO.c_currency := 0.0;
  4067. stInt: FO.c_int := 0;
  4068. stObject: FO.c_object.Clear(all);
  4069. stArray: FO.c_array.Clear(all);
  4070. stString: FOString := '';
  4071. {$IFDEF SUPER_METHOD}
  4072. stMethod: FO.c_method := nil;
  4073. {$ENDIF}
  4074. end;
  4075. finally
  4076. FProcessing := false;
  4077. end;
  4078. end;
  4079. procedure TSuperObject.Pack(all: boolean = false);
  4080. begin
  4081. if FProcessing then exit;
  4082. FProcessing := true;
  4083. try
  4084. case FDataType of
  4085. stObject: FO.c_object.Pack(all);
  4086. stArray: FO.c_array.Pack(all);
  4087. end;
  4088. finally
  4089. FProcessing := false;
  4090. end;
  4091. end;
  4092. function TSuperObject.GetN(const path: SOString): ISuperObject;
  4093. begin
  4094. Result := ParseString(PSOChar(path), False, true, self);
  4095. if Result = nil then
  4096. Result := TSuperObject.Create(stNull);
  4097. end;
  4098. procedure TSuperObject.PutN(const path: SOString; const Value: ISuperObject);
  4099. begin
  4100. if Value = nil then
  4101. ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], TSuperObject.Create(stNull)) else
  4102. ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], Value);
  4103. end;
  4104. function TSuperObject.Delete(const path: SOString): ISuperObject;
  4105. begin
  4106. Result := ParseString(PSOChar(path), False, true, self, [foDelete]);
  4107. end;
  4108. function TSuperObject.Clone: ISuperObject;
  4109. var
  4110. ite: TSuperObjectIter;
  4111. arr: TSuperArray;
  4112. j: integer;
  4113. begin
  4114. case FDataType of
  4115. stBoolean: Result := TSuperObject.Create(FO.c_boolean);
  4116. stDouble: Result := TSuperObject.Create(FO.c_double);
  4117. stCurrency: Result := TSuperObject.CreateCurrency(FO.c_currency);
  4118. stInt: Result := TSuperObject.Create(FO.c_int);
  4119. stString: Result := TSuperObject.Create(FOString);
  4120. {$IFDEF SUPER_METHOD}
  4121. stMethod: Result := TSuperObject.Create(FO.c_method);
  4122. {$ENDIF}
  4123. stObject:
  4124. begin
  4125. Result := TSuperObject.Create(stObject);
  4126. if ObjectFindFirst(self, ite) then
  4127. with Result.AsObject do
  4128. repeat
  4129. PutO(ite.key, ite.val.Clone);
  4130. until not ObjectFindNext(ite);
  4131. ObjectFindClose(ite);
  4132. end;
  4133. stArray:
  4134. begin
  4135. Result := TSuperObject.Create(stArray);
  4136. arr := AsArray;
  4137. with Result.AsArray do
  4138. for j := 0 to arr.Length - 1 do
  4139. Add(arr.GetO(j).Clone);
  4140. end;
  4141. else
  4142. Result := nil;
  4143. end;
  4144. end;
  4145. procedure TSuperObject.Merge(const obj: ISuperObject; reference: boolean);
  4146. var
  4147. prop1, prop2: ISuperObject;
  4148. ite: TSuperObjectIter;
  4149. arr: TSuperArray;
  4150. j: integer;
  4151. begin
  4152. if ObjectIsType(obj, FDataType) then
  4153. case FDataType of
  4154. stBoolean: FO.c_boolean := obj.AsBoolean;
  4155. stDouble: FO.c_double := obj.AsDouble;
  4156. stCurrency: FO.c_currency := obj.AsCurrency;
  4157. stInt: FO.c_int := obj.AsInteger;
  4158. stString: FOString := obj.AsString;
  4159. {$IFDEF SUPER_METHOD}
  4160. stMethod: FO.c_method := obj.AsMethod;
  4161. {$ENDIF}
  4162. stObject:
  4163. begin
  4164. if ObjectFindFirst(obj, ite) then
  4165. with FO.c_object do
  4166. repeat
  4167. prop1 := FO.c_object.GetO(ite.key);
  4168. if (prop1 <> nil) and (ite.val <> nil) and (prop1.DataType = ite.val.DataType) then
  4169. prop1.Merge(ite.val) else
  4170. if reference then
  4171. PutO(ite.key, ite.val) else
  4172. if ite.val <> nil then
  4173. PutO(ite.key, ite.val.Clone) else
  4174. PutO(ite.key, nil)
  4175. until not ObjectFindNext(ite);
  4176. ObjectFindClose(ite);
  4177. end;
  4178. stArray:
  4179. begin
  4180. arr := obj.AsArray;
  4181. with FO.c_array do
  4182. for j := 0 to arr.Length - 1 do
  4183. begin
  4184. prop1 := GetO(j);
  4185. prop2 := arr.GetO(j);
  4186. if (prop1 <> nil) and (prop2 <> nil) and (prop1.DataType = prop2.DataType) then
  4187. prop1.Merge(prop2) else
  4188. if reference then
  4189. PutO(j, prop2) else
  4190. if prop2 <> nil then
  4191. PutO(j, prop2.Clone) else
  4192. PutO(j, nil);
  4193. end;
  4194. end;
  4195. end;
  4196. end;
  4197. procedure TSuperObject.Merge(const str: SOString);
  4198. begin
  4199. Merge(TSuperObject.ParseString(PSOChar(str), False), true);
  4200. end;
  4201. class function TSuperObject.NewInstance: TObject;
  4202. begin
  4203. Result := inherited NewInstance;
  4204. TSuperObject(Result).FRefCount := 1;
  4205. end;
  4206. function TSuperObject.ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  4207. begin
  4208. Result := ParseString(PSOChar(path), False, True, Self, [foCreatePath], nil, dataType);
  4209. end;
  4210. function TSuperObject.Format(const str: SOString; BeginSep: SOChar; EndSep: SOChar): SOString;
  4211. var
  4212. p1, p2: PSOChar;
  4213. begin
  4214. Result := '';
  4215. p2 := PSOChar(str);
  4216. p1 := p2;
  4217. while true do
  4218. if p2^ = BeginSep then
  4219. begin
  4220. if p2 > p1 then
  4221. Result := Result + Copy(p1, 0, p2-p1);
  4222. inc(p2);
  4223. p1 := p2;
  4224. while true do
  4225. if p2^ = EndSep then Break else
  4226. if p2^ = #0 then Exit else
  4227. inc(p2);
  4228. Result := Result + GetS(copy(p1, 0, p2-p1));
  4229. inc(p2);
  4230. p1 := p2;
  4231. end
  4232. else if p2^ = #0 then
  4233. begin
  4234. if p2 > p1 then
  4235. Result := Result + Copy(p1, 0, p2-p1);
  4236. Break;
  4237. end else
  4238. inc(p2);
  4239. end;
  4240. function TSuperObject.GetO(const path: SOString): ISuperObject;
  4241. begin
  4242. Result := ParseString(PSOChar(path), False, True, Self);
  4243. end;
  4244. function TSuperObject.GetA(const path: SOString): TSuperArray;
  4245. var
  4246. obj: ISuperObject;
  4247. begin
  4248. obj := ParseString(PSOChar(path), False, True, Self);
  4249. if obj <> nil then
  4250. Result := obj.AsArray else
  4251. Result := nil;
  4252. end;
  4253. function TSuperObject.GetB(const path: SOString): Boolean;
  4254. var
  4255. obj: ISuperObject;
  4256. begin
  4257. obj := GetO(path);
  4258. if obj <> nil then
  4259. Result := obj.AsBoolean else
  4260. Result := false;
  4261. end;
  4262. function TSuperObject.GetD(const path: SOString): Double;
  4263. var
  4264. obj: ISuperObject;
  4265. begin
  4266. obj := GetO(path);
  4267. if obj <> nil then
  4268. Result := obj.AsDouble else
  4269. Result := 0.0;
  4270. end;
  4271. function TSuperObject.GetC(const path: SOString): Currency;
  4272. var
  4273. obj: ISuperObject;
  4274. begin
  4275. obj := GetO(path);
  4276. if obj <> nil then
  4277. Result := obj.AsCurrency else
  4278. Result := 0.0;
  4279. end;
  4280. function TSuperObject.GetI(const path: SOString): SuperInt;
  4281. var
  4282. obj: ISuperObject;
  4283. begin
  4284. obj := GetO(path);
  4285. if obj <> nil then
  4286. Result := obj.AsInteger else
  4287. Result := 0;
  4288. end;
  4289. function TSuperObject.GetDataPtr: Pointer;
  4290. begin
  4291. Result := FDataPtr;
  4292. end;
  4293. function TSuperObject.GetDataType: TSuperType;
  4294. begin
  4295. Result := FDataType
  4296. end;
  4297. function TSuperObject.GetS(const path: SOString): SOString;
  4298. var
  4299. obj: ISuperObject;
  4300. begin
  4301. obj := GetO(path);
  4302. if obj <> nil then
  4303. Result := obj.AsString else
  4304. Result := '';
  4305. end;
  4306. function TSuperObject.SaveTo(const FileName: string; indent, escape: boolean): integer;
  4307. var
  4308. stream: TFileStream;
  4309. begin
  4310. stream := TFileStream.Create(FileName, fmCreate);
  4311. try
  4312. Result := SaveTo(stream, indent, escape);
  4313. finally
  4314. stream.Free;
  4315. end;
  4316. end;
  4317. function TSuperObject.Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;
  4318. begin
  4319. Result := Validate(TSuperObject.ParseString(PSOChar(rules), False), TSuperObject.ParseString(PSOChar(defs), False), callback, sender);
  4320. end;
  4321. function TSuperObject.Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;
  4322. type
  4323. TDataType = (dtUnknown, dtStr, dtInt, dtFloat, dtNumber, dtText, dtBool,
  4324. dtMap, dtSeq, dtScalar, dtAny);
  4325. var
  4326. datatypes: ISuperObject;
  4327. names: ISuperObject;
  4328. function FindInheritedProperty(const prop: PSOChar; p: ISuperObject): ISuperObject;
  4329. var
  4330. o: ISuperObject;
  4331. e: TSuperAvlEntry;
  4332. begin
  4333. o := p[prop];
  4334. if o <> nil then
  4335. result := o else
  4336. begin
  4337. o := p['inherit'];
  4338. if (o <> nil) and ObjectIsType(o, stString) then
  4339. begin
  4340. e := names.AsObject.Search(o.AsString);
  4341. if (e <> nil) then
  4342. Result := FindInheritedProperty(prop, e.Value) else
  4343. Result := nil;
  4344. end else
  4345. Result := nil;
  4346. end;
  4347. end;
  4348. function FindDataType(o: ISuperObject): TDataType;
  4349. var
  4350. e: TSuperAvlEntry;
  4351. obj: ISuperObject;
  4352. begin
  4353. obj := FindInheritedProperty('type', o);
  4354. if obj <> nil then
  4355. begin
  4356. e := datatypes.AsObject.Search(obj.AsString);
  4357. if e <> nil then
  4358. Result := TDataType(e.Value.AsInteger) else
  4359. Result := dtUnknown;
  4360. end else
  4361. Result := dtUnknown;
  4362. end;
  4363. procedure GetNames(o: ISuperObject);
  4364. var
  4365. obj: ISuperObject;
  4366. f: TSuperObjectIter;
  4367. begin
  4368. obj := o['name'];
  4369. if ObjectIsType(obj, stString) then
  4370. names[obj.AsString] := o;
  4371. case FindDataType(o) of
  4372. dtMap:
  4373. begin
  4374. obj := o['mapping'];
  4375. if ObjectIsType(obj, stObject) then
  4376. begin
  4377. if ObjectFindFirst(obj, f) then
  4378. repeat
  4379. if ObjectIsType(f.val, stObject) then
  4380. GetNames(f.val);
  4381. until not ObjectFindNext(f);
  4382. ObjectFindClose(f);
  4383. end;
  4384. end;
  4385. dtSeq:
  4386. begin
  4387. obj := o['sequence'];
  4388. if ObjectIsType(obj, stObject) then
  4389. GetNames(obj);
  4390. end;
  4391. end;
  4392. end;
  4393. function FindInheritedField(const prop: SOString; p: ISuperObject): ISuperObject;
  4394. var
  4395. o: ISuperObject;
  4396. e: TSuperAvlEntry;
  4397. begin
  4398. o := p['mapping'];
  4399. if ObjectIsType(o, stObject) then
  4400. begin
  4401. o := o.AsObject.GetO(prop);
  4402. if o <> nil then
  4403. begin
  4404. Result := o;
  4405. Exit;
  4406. end;
  4407. end;
  4408. o := p['inherit'];
  4409. if ObjectIsType(o, stString) then
  4410. begin
  4411. e := names.AsObject.Search(o.AsString);
  4412. if (e <> nil) then
  4413. Result := FindInheritedField(prop, e.Value) else
  4414. Result := nil;
  4415. end else
  4416. Result := nil;
  4417. end;
  4418. function InheritedFieldExist(const obj: ISuperObject; p: ISuperObject; const name: SOString = ''): boolean;
  4419. var
  4420. o: ISuperObject;
  4421. e: TSuperAvlEntry;
  4422. j: TSuperAvlIterator;
  4423. begin
  4424. Result := true;
  4425. o := p['mapping'];
  4426. if ObjectIsType(o, stObject) then
  4427. begin
  4428. j := TSuperAvlIterator.Create(o.AsObject);
  4429. try
  4430. j.First;
  4431. e := j.GetIter;
  4432. while e <> nil do
  4433. begin
  4434. if obj.AsObject.Search(e.Name) = nil then
  4435. begin
  4436. Result := False;
  4437. if assigned(callback) then
  4438. callback(sender, veFieldNotFound, name + '.' + e.Name);
  4439. end;
  4440. j.Next;
  4441. e := j.GetIter;
  4442. end;
  4443. finally
  4444. j.Free;
  4445. end;
  4446. end;
  4447. o := p['inherit'];
  4448. if ObjectIsType(o, stString) then
  4449. begin
  4450. e := names.AsObject.Search(o.AsString);
  4451. if (e <> nil) then
  4452. Result := InheritedFieldExist(obj, e.Value, name) and Result;
  4453. end;
  4454. end;
  4455. function getInheritedBool(f: PSOChar; p: ISuperObject; default: boolean = false): boolean;
  4456. var
  4457. o: ISuperObject;
  4458. begin
  4459. o := FindInheritedProperty(f, p);
  4460. case ObjectGetType(o) of
  4461. stBoolean: Result := o.AsBoolean;
  4462. stNull: Result := Default;
  4463. else
  4464. Result := default;
  4465. if assigned(callback) then
  4466. callback(sender, veRuleMalformated, f);
  4467. end;
  4468. end;
  4469. procedure GetInheritedFieldList(list: ISuperObject; p: ISuperObject);
  4470. var
  4471. o: ISuperObject;
  4472. e: TSuperAvlEntry;
  4473. i: TSuperAvlIterator;
  4474. begin
  4475. Result := true;
  4476. o := p['mapping'];
  4477. if ObjectIsType(o, stObject) then
  4478. begin
  4479. i := TSuperAvlIterator.Create(o.AsObject);
  4480. try
  4481. i.First;
  4482. e := i.GetIter;
  4483. while e <> nil do
  4484. begin
  4485. if list.AsObject.Search(e.Name) = nil then
  4486. list[e.Name] := e.Value;
  4487. i.Next;
  4488. e := i.GetIter;
  4489. end;
  4490. finally
  4491. i.Free;
  4492. end;
  4493. end;
  4494. o := p['inherit'];
  4495. if ObjectIsType(o, stString) then
  4496. begin
  4497. e := names.AsObject.Search(o.AsString);
  4498. if (e <> nil) then
  4499. GetInheritedFieldList(list, e.Value);
  4500. end;
  4501. end;
  4502. function CheckEnum(o: ISuperObject; p: ISuperObject; name: SOString = ''): boolean;
  4503. var
  4504. enum: ISuperObject;
  4505. i: integer;
  4506. begin
  4507. Result := false;
  4508. enum := FindInheritedProperty('enum', p);
  4509. case ObjectGetType(enum) of
  4510. stArray:
  4511. for i := 0 to enum.AsArray.Length - 1 do
  4512. if (o.AsString = enum.AsArray[i].AsString) then
  4513. begin
  4514. Result := true;
  4515. exit;
  4516. end;
  4517. stNull: Result := true;
  4518. else
  4519. Result := false;
  4520. if assigned(callback) then
  4521. callback(sender, veRuleMalformated, '');
  4522. Exit;
  4523. end;
  4524. if (not Result) and assigned(callback) then
  4525. callback(sender, veValueNotInEnum, name);
  4526. end;
  4527. function CheckLength(len: integer; p: ISuperObject; const objpath: SOString): boolean;
  4528. var
  4529. length, o: ISuperObject;
  4530. begin
  4531. result := true;
  4532. length := FindInheritedProperty('length', p);
  4533. case ObjectGetType(length) of
  4534. stObject:
  4535. begin
  4536. o := length.AsObject.GetO('min');
  4537. if (o <> nil) and (o.AsInteger > len) then
  4538. begin
  4539. Result := false;
  4540. if assigned(callback) then
  4541. callback(sender, veInvalidLength, objpath);
  4542. end;
  4543. o := length.AsObject.GetO('max');
  4544. if (o <> nil) and (o.AsInteger < len) then
  4545. begin
  4546. Result := false;
  4547. if assigned(callback) then
  4548. callback(sender, veInvalidLength, objpath);
  4549. end;
  4550. o := length.AsObject.GetO('minex');
  4551. if (o <> nil) and (o.AsInteger >= len) then
  4552. begin
  4553. Result := false;
  4554. if assigned(callback) then
  4555. callback(sender, veInvalidLength, objpath);
  4556. end;
  4557. o := length.AsObject.GetO('maxex');
  4558. if (o <> nil) and (o.AsInteger <= len) then
  4559. begin
  4560. Result := false;
  4561. if assigned(callback) then
  4562. callback(sender, veInvalidLength, objpath);
  4563. end;
  4564. end;
  4565. stNull: ;
  4566. else
  4567. Result := false;
  4568. if assigned(callback) then
  4569. callback(sender, veRuleMalformated, '');
  4570. end;
  4571. end;
  4572. function CheckRange(obj: ISuperObject; p: ISuperObject; const objpath: SOString): boolean;
  4573. var
  4574. length, o: ISuperObject;
  4575. begin
  4576. result := true;
  4577. length := FindInheritedProperty('range', p);
  4578. case ObjectGetType(length) of
  4579. stObject:
  4580. begin
  4581. o := length.AsObject.GetO('min');
  4582. if (o <> nil) and (o.Compare(obj) = cpGreat) then
  4583. begin
  4584. Result := false;
  4585. if assigned(callback) then
  4586. callback(sender, veInvalidRange, objpath);
  4587. end;
  4588. o := length.AsObject.GetO('max');
  4589. if (o <> nil) and (o.Compare(obj) = cpLess) then
  4590. begin
  4591. Result := false;
  4592. if assigned(callback) then
  4593. callback(sender, veInvalidRange, objpath);
  4594. end;
  4595. o := length.AsObject.GetO('minex');
  4596. if (o <> nil) and (o.Compare(obj) in [cpGreat, cpEqu]) then
  4597. begin
  4598. Result := false;
  4599. if assigned(callback) then
  4600. callback(sender, veInvalidRange, objpath);
  4601. end;
  4602. o := length.AsObject.GetO('maxex');
  4603. if (o <> nil) and (o.Compare(obj) in [cpLess, cpEqu]) then
  4604. begin
  4605. Result := false;
  4606. if assigned(callback) then
  4607. callback(sender, veInvalidRange, objpath);
  4608. end;
  4609. end;
  4610. stNull: ;
  4611. else
  4612. Result := false;
  4613. if assigned(callback) then
  4614. callback(sender, veRuleMalformated, '');
  4615. end;
  4616. end;
  4617. function process(o: ISuperObject; p: ISuperObject; objpath: SOString = ''): boolean;
  4618. var
  4619. ite: TSuperAvlIterator;
  4620. ent: TSuperAvlEntry;
  4621. p2, o2, sequence: ISuperObject;
  4622. s: SOString;
  4623. i: integer;
  4624. uniquelist, fieldlist: ISuperObject;
  4625. begin
  4626. Result := true;
  4627. if (o = nil) then
  4628. begin
  4629. if getInheritedBool('required', p) then
  4630. begin
  4631. if assigned(callback) then
  4632. callback(sender, veFieldIsRequired, objpath);
  4633. result := false;
  4634. end;
  4635. end else
  4636. case FindDataType(p) of
  4637. dtStr:
  4638. case ObjectGetType(o) of
  4639. stString:
  4640. begin
  4641. Result := Result and CheckLength(Length(o.AsString), p, objpath);
  4642. Result := Result and CheckRange(o, p, objpath);
  4643. end;
  4644. else
  4645. if assigned(callback) then
  4646. callback(sender, veInvalidDataType, objpath);
  4647. result := false;
  4648. end;
  4649. dtBool:
  4650. case ObjectGetType(o) of
  4651. stBoolean:
  4652. begin
  4653. Result := Result and CheckRange(o, p, objpath);
  4654. end;
  4655. else
  4656. if assigned(callback) then
  4657. callback(sender, veInvalidDataType, objpath);
  4658. result := false;
  4659. end;
  4660. dtInt:
  4661. case ObjectGetType(o) of
  4662. stInt:
  4663. begin
  4664. Result := Result and CheckRange(o, p, objpath);
  4665. end;
  4666. else
  4667. if assigned(callback) then
  4668. callback(sender, veInvalidDataType, objpath);
  4669. result := false;
  4670. end;
  4671. dtFloat:
  4672. case ObjectGetType(o) of
  4673. stDouble, stCurrency:
  4674. begin
  4675. Result := Result and CheckRange(o, p, objpath);
  4676. end;
  4677. else
  4678. if assigned(callback) then
  4679. callback(sender, veInvalidDataType, objpath);
  4680. result := false;
  4681. end;
  4682. dtMap:
  4683. case ObjectGetType(o) of
  4684. stObject:
  4685. begin
  4686. // all objects have and match a rule ?
  4687. ite := TSuperAvlIterator.Create(o.AsObject);
  4688. try
  4689. ite.First;
  4690. ent := ite.GetIter;
  4691. while ent <> nil do
  4692. begin
  4693. p2 := FindInheritedField(ent.Name, p);
  4694. if ObjectIsType(p2, stObject) then
  4695. result := process(ent.Value, p2, objpath + '.' + ent.Name) and result else
  4696. begin
  4697. if assigned(callback) then
  4698. callback(sender, veUnexpectedField, objpath + '.' + ent.Name);
  4699. result := false; // field have no rule
  4700. end;
  4701. ite.Next;
  4702. ent := ite.GetIter;
  4703. end;
  4704. finally
  4705. ite.Free;
  4706. end;
  4707. // all expected field exists ?
  4708. Result := InheritedFieldExist(o, p, objpath) and Result;
  4709. end;
  4710. stNull: {nop};
  4711. else
  4712. result := false;
  4713. if assigned(callback) then
  4714. callback(sender, veRuleMalformated, objpath);
  4715. end;
  4716. dtSeq:
  4717. case ObjectGetType(o) of
  4718. stArray:
  4719. begin
  4720. sequence := FindInheritedProperty('sequence', p);
  4721. if sequence <> nil then
  4722. case ObjectGetType(sequence) of
  4723. stObject:
  4724. begin
  4725. for i := 0 to o.AsArray.Length - 1 do
  4726. result := process(o.AsArray.GetO(i), sequence, objpath + '[' + IntToStr(i) + ']') and result;
  4727. if getInheritedBool('unique', sequence) then
  4728. begin
  4729. // type is unique ?
  4730. uniquelist := TSuperObject.Create(stObject);
  4731. try
  4732. for i := 0 to o.AsArray.Length - 1 do
  4733. begin
  4734. s := o.AsArray.GetO(i).AsString;
  4735. if (s <> '') then
  4736. begin
  4737. if uniquelist.AsObject.Search(s) = nil then
  4738. uniquelist[s] := nil else
  4739. begin
  4740. Result := False;
  4741. if Assigned(callback) then
  4742. callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + ']');
  4743. end;
  4744. end;
  4745. end;
  4746. finally
  4747. uniquelist := nil;
  4748. end;
  4749. end;
  4750. // field is unique ?
  4751. if (FindDataType(sequence) = dtMap) then
  4752. begin
  4753. fieldlist := TSuperObject.Create(stObject);
  4754. try
  4755. GetInheritedFieldList(fieldlist, sequence);
  4756. ite := TSuperAvlIterator.Create(fieldlist.AsObject);
  4757. try
  4758. ite.First;
  4759. ent := ite.GetIter;
  4760. while ent <> nil do
  4761. begin
  4762. if getInheritedBool('unique', ent.Value) then
  4763. begin
  4764. uniquelist := TSuperObject.Create(stObject);
  4765. try
  4766. for i := 0 to o.AsArray.Length - 1 do
  4767. begin
  4768. o2 := o.AsArray.GetO(i);
  4769. if o2 <> nil then
  4770. begin
  4771. s := o2.AsObject.GetO(ent.Name).AsString;
  4772. if (s <> '') then
  4773. if uniquelist.AsObject.Search(s) = nil then
  4774. uniquelist[s] := nil else
  4775. begin
  4776. Result := False;
  4777. if Assigned(callback) then
  4778. callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + '].' + ent.name);
  4779. end;
  4780. end;
  4781. end;
  4782. finally
  4783. uniquelist := nil;
  4784. end;
  4785. end;
  4786. ite.Next;
  4787. ent := ite.GetIter;
  4788. end;
  4789. finally
  4790. ite.Free;
  4791. end;
  4792. finally
  4793. fieldlist := nil;
  4794. end;
  4795. end;
  4796. end;
  4797. stNull: {nop};
  4798. else
  4799. result := false;
  4800. if assigned(callback) then
  4801. callback(sender, veRuleMalformated, objpath);
  4802. end;
  4803. Result := Result and CheckLength(o.AsArray.Length, p, objpath);
  4804. end;
  4805. else
  4806. result := false;
  4807. if assigned(callback) then
  4808. callback(sender, veRuleMalformated, objpath);
  4809. end;
  4810. dtNumber:
  4811. case ObjectGetType(o) of
  4812. stInt,
  4813. stDouble, stCurrency:
  4814. begin
  4815. Result := Result and CheckRange(o, p, objpath);
  4816. end;
  4817. else
  4818. if assigned(callback) then
  4819. callback(sender, veInvalidDataType, objpath);
  4820. result := false;
  4821. end;
  4822. dtText:
  4823. case ObjectGetType(o) of
  4824. stInt,
  4825. stDouble,
  4826. stCurrency,
  4827. stString:
  4828. begin
  4829. result := result and CheckLength(Length(o.AsString), p, objpath);
  4830. Result := Result and CheckRange(o, p, objpath);
  4831. end;
  4832. else
  4833. if assigned(callback) then
  4834. callback(sender, veInvalidDataType, objpath);
  4835. result := false;
  4836. end;
  4837. dtScalar:
  4838. case ObjectGetType(o) of
  4839. stBoolean,
  4840. stDouble,
  4841. stCurrency,
  4842. stInt,
  4843. stString:
  4844. begin
  4845. result := result and CheckLength(Length(o.AsString), p, objpath);
  4846. Result := Result and CheckRange(o, p, objpath);
  4847. end;
  4848. else
  4849. if assigned(callback) then
  4850. callback(sender, veInvalidDataType, objpath);
  4851. result := false;
  4852. end;
  4853. dtAny:;
  4854. else
  4855. if assigned(callback) then
  4856. callback(sender, veRuleMalformated, objpath);
  4857. result := false;
  4858. end;
  4859. Result := Result and CheckEnum(o, p, objpath)
  4860. end;
  4861. var
  4862. j: integer;
  4863. begin
  4864. Result := False;
  4865. datatypes := TSuperObject.Create(stObject);
  4866. names := TSuperObject.Create;
  4867. try
  4868. datatypes.I['str'] := ord(dtStr);
  4869. datatypes.I['int'] := ord(dtInt);
  4870. datatypes.I['float'] := ord(dtFloat);
  4871. datatypes.I['number'] := ord(dtNumber);
  4872. datatypes.I['text'] := ord(dtText);
  4873. datatypes.I['bool'] := ord(dtBool);
  4874. datatypes.I['map'] := ord(dtMap);
  4875. datatypes.I['seq'] := ord(dtSeq);
  4876. datatypes.I['scalar'] := ord(dtScalar);
  4877. datatypes.I['any'] := ord(dtAny);
  4878. if ObjectIsType(defs, stArray) then
  4879. for j := 0 to defs.AsArray.Length - 1 do
  4880. if ObjectIsType(defs.AsArray[j], stObject) then
  4881. GetNames(defs.AsArray[j]) else
  4882. begin
  4883. if assigned(callback) then
  4884. callback(sender, veRuleMalformated, '');
  4885. Exit;
  4886. end;
  4887. if ObjectIsType(rules, stObject) then
  4888. GetNames(rules) else
  4889. begin
  4890. if assigned(callback) then
  4891. callback(sender, veRuleMalformated, '');
  4892. Exit;
  4893. end;
  4894. Result := process(self, rules);
  4895. finally
  4896. datatypes := nil;
  4897. names := nil;
  4898. end;
  4899. end;
  4900. function TSuperObject._AddRef: Integer; stdcall;
  4901. begin
  4902. Result := InterlockedIncrement(FRefCount);
  4903. end;
  4904. function TSuperObject._Release: Integer; stdcall;
  4905. begin
  4906. Result := InterlockedDecrement(FRefCount);
  4907. if Result = 0 then
  4908. Destroy;
  4909. end;
  4910. function TSuperObject.Compare(const str: SOString): TSuperCompareResult;
  4911. begin
  4912. Result := Compare(TSuperObject.ParseString(PSOChar(str), False));
  4913. end;
  4914. function TSuperObject.Compare(const obj: ISuperObject): TSuperCompareResult;
  4915. function GetIntCompResult(const i: int64): TSuperCompareResult;
  4916. begin
  4917. if i < 0 then result := cpLess else
  4918. if i = 0 then result := cpEqu else
  4919. Result := cpGreat;
  4920. end;
  4921. function GetDblCompResult(const d: double): TSuperCompareResult;
  4922. begin
  4923. if d < 0 then result := cpLess else
  4924. if d = 0 then result := cpEqu else
  4925. Result := cpGreat;
  4926. end;
  4927. begin
  4928. case DataType of
  4929. stBoolean:
  4930. case ObjectGetType(obj) of
  4931. stBoolean: Result := GetIntCompResult(ord(FO.c_boolean) - ord(obj.AsBoolean));
  4932. stDouble: Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsDouble);
  4933. stCurrency:Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsCurrency);
  4934. stInt: Result := GetIntCompResult(ord(FO.c_boolean) - obj.AsInteger);
  4935. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4936. else
  4937. Result := cpError;
  4938. end;
  4939. stDouble:
  4940. case ObjectGetType(obj) of
  4941. stBoolean: Result := GetDblCompResult(FO.c_double - ord(obj.AsBoolean));
  4942. stDouble: Result := GetDblCompResult(FO.c_double - obj.AsDouble);
  4943. stCurrency:Result := GetDblCompResult(FO.c_double - obj.AsCurrency);
  4944. stInt: Result := GetDblCompResult(FO.c_double - obj.AsInteger);
  4945. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4946. else
  4947. Result := cpError;
  4948. end;
  4949. stCurrency:
  4950. case ObjectGetType(obj) of
  4951. stBoolean: Result := GetDblCompResult(FO.c_currency - ord(obj.AsBoolean));
  4952. stDouble: Result := GetDblCompResult(FO.c_currency - obj.AsDouble);
  4953. stCurrency:Result := GetDblCompResult(FO.c_currency - obj.AsCurrency);
  4954. stInt: Result := GetDblCompResult(FO.c_currency - obj.AsInteger);
  4955. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4956. else
  4957. Result := cpError;
  4958. end;
  4959. stInt:
  4960. case ObjectGetType(obj) of
  4961. stBoolean: Result := GetIntCompResult(FO.c_int - ord(obj.AsBoolean));
  4962. stDouble: Result := GetDblCompResult(FO.c_int - obj.AsDouble);
  4963. stCurrency:Result := GetDblCompResult(FO.c_int - obj.AsCurrency);
  4964. stInt: Result := GetIntCompResult(FO.c_int - obj.AsInteger);
  4965. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4966. else
  4967. Result := cpError;
  4968. end;
  4969. stString:
  4970. case ObjectGetType(obj) of
  4971. stBoolean,
  4972. stDouble,
  4973. stCurrency,
  4974. stInt,
  4975. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4976. else
  4977. Result := cpError;
  4978. end;
  4979. else
  4980. Result := cpError;
  4981. end;
  4982. end;
  4983. {$IFDEF SUPER_METHOD}
  4984. function TSuperObject.AsMethod: TSuperMethod;
  4985. begin
  4986. if FDataType = stMethod then
  4987. Result := FO.c_method else
  4988. Result := nil;
  4989. end;
  4990. {$ENDIF}
  4991. {$IFDEF SUPER_METHOD}
  4992. constructor TSuperObject.Create(m: TSuperMethod);
  4993. begin
  4994. Create(stMethod);
  4995. FO.c_method := m;
  4996. end;
  4997. {$ENDIF}
  4998. {$IFDEF SUPER_METHOD}
  4999. function TSuperObject.GetM(const path: SOString): TSuperMethod;
  5000. var
  5001. v: ISuperObject;
  5002. begin
  5003. v := ParseString(PSOChar(path), False, True, Self);
  5004. if (v <> nil) and (ObjectGetType(v) = stMethod) then
  5005. Result := v.AsMethod else
  5006. Result := nil;
  5007. end;
  5008. {$ENDIF}
  5009. {$IFDEF SUPER_METHOD}
  5010. procedure TSuperObject.PutM(const path: SOString; Value: TSuperMethod);
  5011. begin
  5012. ParseString(PSOChar(path), False, True, Self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  5013. end;
  5014. {$ENDIF}
  5015. {$IFDEF SUPER_METHOD}
  5016. function TSuperObject.call(const path: SOString; const param: ISuperObject): ISuperObject;
  5017. begin
  5018. Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], param);
  5019. end;
  5020. {$ENDIF}
  5021. {$IFDEF SUPER_METHOD}
  5022. function TSuperObject.call(const path, param: SOString): ISuperObject;
  5023. begin
  5024. Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], TSuperObject.ParseString(PSOChar(param), False));
  5025. end;
  5026. {$ENDIF}
  5027. function TSuperObject.GetProcessing: boolean;
  5028. begin
  5029. Result := FProcessing;
  5030. end;
  5031. procedure TSuperObject.SetDataPtr(const Value: Pointer);
  5032. begin
  5033. FDataPtr := Value;
  5034. end;
  5035. procedure TSuperObject.SetProcessing(value: boolean);
  5036. begin
  5037. FProcessing := value;
  5038. end;
  5039. { TSuperArray }
  5040. function TSuperArray.Add(const Data: ISuperObject): Integer;
  5041. begin
  5042. Result := FLength;
  5043. PutO(Result, data);
  5044. end;
  5045. function TSuperArray.Add(Data: SuperInt): Integer;
  5046. begin
  5047. Result := Add(TSuperObject.Create(Data));
  5048. end;
  5049. function TSuperArray.Add(const Data: SOString): Integer;
  5050. begin
  5051. Result := Add(TSuperObject.Create(Data));
  5052. end;
  5053. function TSuperArray.Add(Data: Boolean): Integer;
  5054. begin
  5055. Result := Add(TSuperObject.Create(Data));
  5056. end;
  5057. function TSuperArray.Add(Data: Double): Integer;
  5058. begin
  5059. Result := Add(TSuperObject.Create(Data));
  5060. end;
  5061. function TSuperArray.AddC(const Data: Currency): Integer;
  5062. begin
  5063. Result := Add(TSuperObject.CreateCurrency(Data));
  5064. end;
  5065. function TSuperArray.Delete(index: Integer): ISuperObject;
  5066. begin
  5067. if (Index >= 0) and (Index < FLength) then
  5068. begin
  5069. Result := FArray^[index];
  5070. FArray^[index] := nil;
  5071. Dec(FLength);
  5072. if Index < FLength then
  5073. begin
  5074. Move(FArray^[index + 1], FArray^[index],
  5075. (FLength - index) * SizeOf(Pointer));
  5076. Pointer(FArray^[FLength]) := nil;
  5077. end;
  5078. end;
  5079. end;
  5080. procedure TSuperArray.Insert(index: Integer; const value: ISuperObject);
  5081. begin
  5082. if (Index >= 0) then
  5083. if (index < FLength) then
  5084. begin
  5085. if FLength = FSize then
  5086. Expand(index);
  5087. if Index < FLength then
  5088. Move(FArray^[index], FArray^[index + 1],
  5089. (FLength - index) * SizeOf(Pointer));
  5090. Pointer(FArray^[index]) := nil;
  5091. FArray^[index] := value;
  5092. Inc(FLength);
  5093. end else
  5094. PutO(index, value);
  5095. end;
  5096. procedure TSuperArray.Clear(all: boolean);
  5097. var
  5098. j: Integer;
  5099. begin
  5100. for j := 0 to FLength - 1 do
  5101. if FArray^[j] <> nil then
  5102. begin
  5103. if all then
  5104. FArray^[j].Clear(all);
  5105. FArray^[j] := nil;
  5106. end;
  5107. FLength := 0;
  5108. end;
  5109. procedure TSuperArray.Pack(all: boolean);
  5110. var
  5111. PackedCount, StartIndex, EndIndex, j: Integer;
  5112. begin
  5113. if FLength > 0 then
  5114. begin
  5115. PackedCount := 0;
  5116. StartIndex := 0;
  5117. repeat
  5118. while (StartIndex < FLength) and (FArray^[StartIndex] = nil) do
  5119. Inc(StartIndex);
  5120. if StartIndex < FLength then
  5121. begin
  5122. EndIndex := StartIndex;
  5123. while (EndIndex < FLength) and (FArray^[EndIndex] <> nil) do
  5124. Inc(EndIndex);
  5125. Dec(EndIndex);
  5126. if StartIndex > PackedCount then
  5127. Move(FArray^[StartIndex], FArray^[PackedCount], (EndIndex - StartIndex + 1) * SizeOf(Pointer));
  5128. Inc(PackedCount, EndIndex - StartIndex + 1);
  5129. StartIndex := EndIndex + 1;
  5130. end;
  5131. until StartIndex >= FLength;
  5132. FillChar(FArray^[PackedCount], (FLength - PackedCount) * sizeof(Pointer), 0);
  5133. FLength := PackedCount;
  5134. if all then
  5135. for j := 0 to FLength - 1 do
  5136. FArray^[j].Pack(all);
  5137. end;
  5138. end;
  5139. constructor TSuperArray.Create;
  5140. begin
  5141. inherited Create;
  5142. FSize := SUPER_ARRAY_LIST_DEFAULT_SIZE;
  5143. FLength := 0;
  5144. GetMem(FArray, sizeof(Pointer) * FSize);
  5145. FillChar(FArray^, sizeof(Pointer) * FSize, 0);
  5146. end;
  5147. destructor TSuperArray.Destroy;
  5148. begin
  5149. Clear;
  5150. FreeMem(FArray);
  5151. inherited;
  5152. end;
  5153. procedure TSuperArray.Expand(max: Integer);
  5154. var
  5155. new_size: Integer;
  5156. begin
  5157. if (max < FSize) then
  5158. Exit;
  5159. if max < (FSize shl 1) then
  5160. new_size := (FSize shl 1) else
  5161. new_size := max + 1;
  5162. ReallocMem(FArray, new_size * sizeof(Pointer));
  5163. FillChar(FArray^[FSize], (new_size - FSize) * sizeof(Pointer), 0);
  5164. FSize := new_size;
  5165. end;
  5166. function TSuperArray.GetO(const index: Integer): ISuperObject;
  5167. begin
  5168. if(index >= FLength) then
  5169. Result := nil else
  5170. Result := FArray^[index];
  5171. end;
  5172. function TSuperArray.GetB(const index: integer): Boolean;
  5173. var
  5174. obj: ISuperObject;
  5175. begin
  5176. obj := GetO(index);
  5177. if obj <> nil then
  5178. Result := obj.AsBoolean else
  5179. Result := false;
  5180. end;
  5181. function TSuperArray.GetD(const index: integer): Double;
  5182. var
  5183. obj: ISuperObject;
  5184. begin
  5185. obj := GetO(index);
  5186. if obj <> nil then
  5187. Result := obj.AsDouble else
  5188. Result := 0.0;
  5189. end;
  5190. function TSuperArray.GetI(const index: integer): SuperInt;
  5191. var
  5192. obj: ISuperObject;
  5193. begin
  5194. obj := GetO(index);
  5195. if obj <> nil then
  5196. Result := obj.AsInteger else
  5197. Result := 0;
  5198. end;
  5199. function TSuperArray.GetS(const index: integer): SOString;
  5200. var
  5201. obj: ISuperObject;
  5202. begin
  5203. obj := GetO(index);
  5204. if obj <> nil then
  5205. Result := obj.AsString else
  5206. Result := '';
  5207. end;
  5208. procedure TSuperArray.PutO(const index: Integer; const Value: ISuperObject);
  5209. begin
  5210. Expand(index);
  5211. FArray^[index] := value;
  5212. if(FLength <= index) then FLength := index + 1;
  5213. end;
  5214. function TSuperArray.GetN(const index: integer): ISuperObject;
  5215. begin
  5216. Result := GetO(index);
  5217. if Result = nil then
  5218. Result := TSuperObject.Create(stNull);
  5219. end;
  5220. procedure TSuperArray.PutN(const index: integer; const Value: ISuperObject);
  5221. begin
  5222. if Value <> nil then
  5223. PutO(index, Value) else
  5224. PutO(index, TSuperObject.Create(stNull));
  5225. end;
  5226. procedure TSuperArray.PutB(const index: integer; Value: Boolean);
  5227. begin
  5228. PutO(index, TSuperObject.Create(Value));
  5229. end;
  5230. procedure TSuperArray.PutD(const index: integer; Value: Double);
  5231. begin
  5232. PutO(index, TSuperObject.Create(Value));
  5233. end;
  5234. function TSuperArray.GetC(const index: integer): Currency;
  5235. var
  5236. obj: ISuperObject;
  5237. begin
  5238. obj := GetO(index);
  5239. if obj <> nil then
  5240. Result := obj.AsCurrency else
  5241. Result := 0.0;
  5242. end;
  5243. procedure TSuperArray.PutC(const index: integer; Value: Currency);
  5244. begin
  5245. PutO(index, TSuperObject.CreateCurrency(Value));
  5246. end;
  5247. procedure TSuperArray.PutI(const index: integer; Value: SuperInt);
  5248. begin
  5249. PutO(index, TSuperObject.Create(Value));
  5250. end;
  5251. procedure TSuperArray.PutS(const index: integer; const Value: SOString);
  5252. begin
  5253. PutO(index, TSuperObject.Create(Value));
  5254. end;
  5255. {$IFDEF SUPER_METHOD}
  5256. function TSuperArray.GetM(const index: integer): TSuperMethod;
  5257. var
  5258. v: ISuperObject;
  5259. begin
  5260. v := GetO(index);
  5261. if (ObjectGetType(v) = stMethod) then
  5262. Result := v.AsMethod else
  5263. Result := nil;
  5264. end;
  5265. {$ENDIF}
  5266. {$IFDEF SUPER_METHOD}
  5267. procedure TSuperArray.PutM(const index: integer; Value: TSuperMethod);
  5268. begin
  5269. PutO(index, TSuperObject.Create(Value));
  5270. end;
  5271. {$ENDIF}
  5272. { TSuperWriterString }
  5273. function TSuperWriterString.Append(buf: PSOChar; Size: Integer): Integer;
  5274. function max(a, b: Integer): integer; begin if a > b then Result := a else Result := b end;
  5275. begin
  5276. Result := size;
  5277. if Size > 0 then
  5278. begin
  5279. if (FSize - FBPos <= size) then
  5280. begin
  5281. FSize := max(FSize * 2, FBPos + size + 8);
  5282. ReallocMem(FBuf, FSize * SizeOf(SOChar));
  5283. end;
  5284. // fast move
  5285. case size of
  5286. 1: FBuf[FBPos] := buf^;
  5287. 2: PInteger(@FBuf[FBPos])^ := PInteger(buf)^;
  5288. 4: PInt64(@FBuf[FBPos])^ := PInt64(buf)^;
  5289. else
  5290. move(buf^, FBuf[FBPos], size * SizeOf(SOChar));
  5291. end;
  5292. inc(FBPos, size);
  5293. FBuf[FBPos] := #0;
  5294. end;
  5295. end;
  5296. function TSuperWriterString.Append(buf: PSOChar): Integer;
  5297. begin
  5298. Result := Append(buf, strlen(buf));
  5299. end;
  5300. constructor TSuperWriterString.Create;
  5301. begin
  5302. inherited;
  5303. FSize := 32;
  5304. FBPos := 0;
  5305. GetMem(FBuf, FSize * SizeOf(SOChar));
  5306. end;
  5307. destructor TSuperWriterString.Destroy;
  5308. begin
  5309. inherited;
  5310. if FBuf <> nil then
  5311. FreeMem(FBuf)
  5312. end;
  5313. function TSuperWriterString.GetString: SOString;
  5314. begin
  5315. SetString(Result, FBuf, FBPos);
  5316. end;
  5317. procedure TSuperWriterString.Reset;
  5318. begin
  5319. FBuf[0] := #0;
  5320. FBPos := 0;
  5321. end;
  5322. procedure TSuperWriterString.TrimRight;
  5323. begin
  5324. while (FBPos > 0) and (FBuf[FBPos-1] < #256) and (AnsiChar(FBuf[FBPos-1]) in [#32, #13, #10]) do
  5325. begin
  5326. dec(FBPos);
  5327. FBuf[FBPos] := #0;
  5328. end;
  5329. end;
  5330. { TSuperWriterStream }
  5331. function TSuperWriterStream.Append(buf: PSOChar): Integer;
  5332. begin
  5333. Result := Append(buf, StrLen(buf));
  5334. end;
  5335. constructor TSuperWriterStream.Create(AStream: TStream);
  5336. begin
  5337. inherited Create;
  5338. FStream := AStream;
  5339. end;
  5340. procedure TSuperWriterStream.Reset;
  5341. begin
  5342. FStream.Size := 0;
  5343. end;
  5344. { TSuperWriterStream }
  5345. function TSuperAnsiWriterStream.Append(buf: PSOChar; Size: Integer): Integer;
  5346. var
  5347. Buffer: array[0..1023] of AnsiChar;
  5348. pBuffer: PAnsiChar;
  5349. i: Integer;
  5350. begin
  5351. if Size = 1 then
  5352. Result := FStream.Write(buf^, Size) else
  5353. begin
  5354. if Size > SizeOf(Buffer) then
  5355. GetMem(pBuffer, Size) else
  5356. pBuffer := @Buffer;
  5357. try
  5358. for i := 0 to Size - 1 do
  5359. pBuffer[i] := AnsiChar(buf[i]);
  5360. Result := FStream.Write(pBuffer^, Size);
  5361. finally
  5362. if pBuffer <> @Buffer then
  5363. FreeMem(pBuffer);
  5364. end;
  5365. end;
  5366. end;
  5367. { TSuperUnicodeWriterStream }
  5368. function TSuperUnicodeWriterStream.Append(buf: PSOChar; Size: Integer): Integer;
  5369. begin
  5370. Result := FStream.Write(buf^, Size * 2);
  5371. end;
  5372. { TSuperWriterFake }
  5373. function TSuperWriterFake.Append(buf: PSOChar; Size: Integer): Integer;
  5374. begin
  5375. inc(FSize, Size);
  5376. Result := FSize;
  5377. end;
  5378. function TSuperWriterFake.Append(buf: PSOChar): Integer;
  5379. begin
  5380. inc(FSize, Strlen(buf));
  5381. Result := FSize;
  5382. end;
  5383. constructor TSuperWriterFake.Create;
  5384. begin
  5385. inherited Create;
  5386. FSize := 0;
  5387. end;
  5388. procedure TSuperWriterFake.Reset;
  5389. begin
  5390. FSize := 0;
  5391. end;
  5392. { TSuperWriterSock }
  5393. function TSuperWriterSock.Append(buf: PSOChar; Size: Integer): Integer;
  5394. var
  5395. Buffer: array[0..1023] of AnsiChar;
  5396. pBuffer: PAnsiChar;
  5397. i: Integer;
  5398. begin
  5399. if Size = 1 then
  5400. {$IFDEF FPC}
  5401. Result := fpsend(FSocket, buf, size, 0) else
  5402. {$ELSE}
  5403. Result := send(FSocket, buf^, size, 0) else
  5404. {$ENDIF}
  5405. begin
  5406. if Size > SizeOf(Buffer) then
  5407. GetMem(pBuffer, Size) else
  5408. pBuffer := @Buffer;
  5409. try
  5410. for i := 0 to Size - 1 do
  5411. pBuffer[i] := AnsiChar(buf[i]);
  5412. {$IFDEF FPC}
  5413. Result := fpsend(FSocket, pBuffer, size, 0);
  5414. {$ELSE}
  5415. Result := send(FSocket, pBuffer^, size, 0);
  5416. {$ENDIF}
  5417. finally
  5418. if pBuffer <> @Buffer then
  5419. FreeMem(pBuffer);
  5420. end;
  5421. end;
  5422. inc(FSize, Result);
  5423. end;
  5424. function TSuperWriterSock.Append(buf: PSOChar): Integer;
  5425. begin
  5426. Result := Append(buf, StrLen(buf));
  5427. end;
  5428. constructor TSuperWriterSock.Create(ASocket: Integer);
  5429. begin
  5430. inherited Create;
  5431. FSocket := ASocket;
  5432. FSize := 0;
  5433. end;
  5434. procedure TSuperWriterSock.Reset;
  5435. begin
  5436. FSize := 0;
  5437. end;
  5438. { TSuperTokenizer }
  5439. constructor TSuperTokenizer.Create;
  5440. begin
  5441. pb := TSuperWriterString.Create;
  5442. line := 1;
  5443. col := 0;
  5444. Reset;
  5445. end;
  5446. destructor TSuperTokenizer.Destroy;
  5447. begin
  5448. Reset;
  5449. pb.Free;
  5450. inherited;
  5451. end;
  5452. procedure TSuperTokenizer.Reset;
  5453. var
  5454. i: integer;
  5455. begin
  5456. for i := depth downto 0 do
  5457. ResetLevel(i);
  5458. depth := 0;
  5459. err := teSuccess;
  5460. end;
  5461. procedure TSuperTokenizer.ResetLevel(adepth: integer);
  5462. begin
  5463. stack[adepth].state := tsEatws;
  5464. stack[adepth].saved_state := tsStart;
  5465. stack[adepth].current := nil;
  5466. stack[adepth].field_name := '';
  5467. stack[adepth].obj := nil;
  5468. stack[adepth].parent := nil;
  5469. stack[adepth].gparent := nil;
  5470. end;
  5471. { TSuperAvlTree }
  5472. constructor TSuperAvlTree.Create;
  5473. begin
  5474. FRoot := nil;
  5475. FCount := 0;
  5476. end;
  5477. destructor TSuperAvlTree.Destroy;
  5478. begin
  5479. Clear;
  5480. inherited;
  5481. end;
  5482. function TSuperAvlTree.IsEmpty: boolean;
  5483. begin
  5484. result := FRoot = nil;
  5485. end;
  5486. function TSuperAvlTree.balance(bal: TSuperAvlEntry): TSuperAvlEntry;
  5487. var
  5488. deep, old: TSuperAvlEntry;
  5489. bf: integer;
  5490. begin
  5491. if (bal.FBf > 0) then
  5492. begin
  5493. deep := bal.FGt;
  5494. if (deep.FBf < 0) then
  5495. begin
  5496. old := bal;
  5497. bal := deep.FLt;
  5498. old.FGt := bal.FLt;
  5499. deep.FLt := bal.FGt;
  5500. bal.FLt := old;
  5501. bal.FGt := deep;
  5502. bf := bal.FBf;
  5503. if (bf <> 0) then
  5504. begin
  5505. if (bf > 0) then
  5506. begin
  5507. old.FBf := -1;
  5508. deep.FBf := 0;
  5509. end else
  5510. begin
  5511. deep.FBf := 1;
  5512. old.FBf := 0;
  5513. end;
  5514. bal.FBf := 0;
  5515. end else
  5516. begin
  5517. old.FBf := 0;
  5518. deep.FBf := 0;
  5519. end;
  5520. end else
  5521. begin
  5522. bal.FGt := deep.FLt;
  5523. deep.FLt := bal;
  5524. if (deep.FBf = 0) then
  5525. begin
  5526. deep.FBf := -1;
  5527. bal.FBf := 1;
  5528. end else
  5529. begin
  5530. deep.FBf := 0;
  5531. bal.FBf := 0;
  5532. end;
  5533. bal := deep;
  5534. end;
  5535. end else
  5536. begin
  5537. (* "Less than" subtree is deeper. *)
  5538. deep := bal.FLt;
  5539. if (deep.FBf > 0) then
  5540. begin
  5541. old := bal;
  5542. bal := deep.FGt;
  5543. old.FLt := bal.FGt;
  5544. deep.FGt := bal.FLt;
  5545. bal.FGt := old;
  5546. bal.FLt := deep;
  5547. bf := bal.FBf;
  5548. if (bf <> 0) then
  5549. begin
  5550. if (bf < 0) then
  5551. begin
  5552. old.FBf := 1;
  5553. deep.FBf := 0;
  5554. end else
  5555. begin
  5556. deep.FBf := -1;
  5557. old.FBf := 0;
  5558. end;
  5559. bal.FBf := 0;
  5560. end else
  5561. begin
  5562. old.FBf := 0;
  5563. deep.FBf := 0;
  5564. end;
  5565. end else
  5566. begin
  5567. bal.FLt := deep.FGt;
  5568. deep.FGt := bal;
  5569. if (deep.FBf = 0) then
  5570. begin
  5571. deep.FBf := 1;
  5572. bal.FBf := -1;
  5573. end else
  5574. begin
  5575. deep.FBf := 0;
  5576. bal.FBf := 0;
  5577. end;
  5578. bal := deep;
  5579. end;
  5580. end;
  5581. Result := bal;
  5582. end;
  5583. function TSuperAvlTree.Insert(h: TSuperAvlEntry): TSuperAvlEntry;
  5584. var
  5585. unbal, parentunbal, hh, parent: TSuperAvlEntry;
  5586. depth, unbaldepth: longint;
  5587. cmp: integer;
  5588. unbalbf: integer;
  5589. branch: TSuperAvlBitArray;
  5590. p: Pointer;
  5591. begin
  5592. inc(FCount);
  5593. h.FLt := nil;
  5594. h.FGt := nil;
  5595. h.FBf := 0;
  5596. branch := [];
  5597. if (FRoot = nil) then
  5598. FRoot := h
  5599. else
  5600. begin
  5601. unbal := nil;
  5602. parentunbal := nil;
  5603. depth := 0;
  5604. unbaldepth := 0;
  5605. hh := FRoot;
  5606. parent := nil;
  5607. repeat
  5608. if (hh.FBf <> 0) then
  5609. begin
  5610. unbal := hh;
  5611. parentunbal := parent;
  5612. unbaldepth := depth;
  5613. end;
  5614. if hh.FHash <> h.FHash then
  5615. begin
  5616. if hh.FHash < h.FHash then cmp := -1 else
  5617. if hh.FHash > h.FHash then cmp := 1 else
  5618. cmp := 0;
  5619. end else
  5620. cmp := CompareNodeNode(h, hh);
  5621. if (cmp = 0) then
  5622. begin
  5623. Result := hh;
  5624. //exchange data
  5625. p := hh.Ptr;
  5626. hh.FPtr := h.Ptr;
  5627. h.FPtr := p;
  5628. doDeleteEntry(h, false);
  5629. dec(FCount);
  5630. exit;
  5631. end;
  5632. parent := hh;
  5633. if (cmp > 0) then
  5634. begin
  5635. hh := hh.FGt;
  5636. include(branch, depth);
  5637. end else
  5638. begin
  5639. hh := hh.FLt;
  5640. exclude(branch, depth);
  5641. end;
  5642. inc(depth);
  5643. until (hh = nil);
  5644. if (cmp < 0) then
  5645. parent.FLt := h else
  5646. parent.FGt := h;
  5647. depth := unbaldepth;
  5648. if (unbal = nil) then
  5649. hh := FRoot
  5650. else
  5651. begin
  5652. if depth in branch then
  5653. cmp := 1 else
  5654. cmp := -1;
  5655. inc(depth);
  5656. unbalbf := unbal.FBf;
  5657. if (cmp < 0) then
  5658. dec(unbalbf) else
  5659. inc(unbalbf);
  5660. if cmp < 0 then
  5661. hh := unbal.FLt else
  5662. hh := unbal.FGt;
  5663. if ((unbalbf <> -2) and (unbalbf <> 2)) then
  5664. begin
  5665. unbal.FBf := unbalbf;
  5666. unbal := nil;
  5667. end;
  5668. end;
  5669. if (hh <> nil) then
  5670. while (h <> hh) do
  5671. begin
  5672. if depth in branch then
  5673. cmp := 1 else
  5674. cmp := -1;
  5675. inc(depth);
  5676. if (cmp < 0) then
  5677. begin
  5678. hh.FBf := -1;
  5679. hh := hh.FLt;
  5680. end else (* cmp > 0 *)
  5681. begin
  5682. hh.FBf := 1;
  5683. hh := hh.FGt;
  5684. end;
  5685. end;
  5686. if (unbal <> nil) then
  5687. begin
  5688. unbal := balance(unbal);
  5689. if (parentunbal = nil) then
  5690. FRoot := unbal
  5691. else
  5692. begin
  5693. depth := unbaldepth - 1;
  5694. if depth in branch then
  5695. cmp := 1 else
  5696. cmp := -1;
  5697. if (cmp < 0) then
  5698. parentunbal.FLt := unbal else
  5699. parentunbal.FGt := unbal;
  5700. end;
  5701. end;
  5702. end;
  5703. result := h;
  5704. end;
  5705. function TSuperAvlTree.Search(const k: SOString; st: TSuperAvlSearchTypes): TSuperAvlEntry;
  5706. var
  5707. cmp, target_cmp: integer;
  5708. match_h, h: TSuperAvlEntry;
  5709. ha: Cardinal;
  5710. begin
  5711. ha := TSuperAvlEntry.Hash(k);
  5712. match_h := nil;
  5713. h := FRoot;
  5714. if (stLess in st) then
  5715. target_cmp := 1 else
  5716. if (stGreater in st) then
  5717. target_cmp := -1 else
  5718. target_cmp := 0;
  5719. while (h <> nil) do
  5720. begin
  5721. if h.FHash < ha then cmp := -1 else
  5722. if h.FHash > ha then cmp := 1 else
  5723. cmp := 0;
  5724. if cmp = 0 then
  5725. cmp := CompareKeyNode(PSOChar(k), h);
  5726. if (cmp = 0) then
  5727. begin
  5728. if (stEqual in st) then
  5729. begin
  5730. match_h := h;
  5731. break;
  5732. end;
  5733. cmp := -target_cmp;
  5734. end
  5735. else
  5736. if (target_cmp <> 0) then
  5737. if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then
  5738. match_h := h;
  5739. if cmp < 0 then
  5740. h := h.FLt else
  5741. h := h.FGt;
  5742. end;
  5743. result := match_h;
  5744. end;
  5745. function TSuperAvlTree.Delete(const k: SOString): ISuperObject;
  5746. var
  5747. depth, rm_depth: longint;
  5748. branch: TSuperAvlBitArray;
  5749. h, parent, child, path, rm, parent_rm: TSuperAvlEntry;
  5750. cmp, cmp_shortened_sub_with_path, reduced_depth, bf: integer;
  5751. ha: Cardinal;
  5752. begin
  5753. ha := TSuperAvlEntry.Hash(k);
  5754. cmp_shortened_sub_with_path := 0;
  5755. branch := [];
  5756. depth := 0;
  5757. h := FRoot;
  5758. parent := nil;
  5759. while true do
  5760. begin
  5761. if (h = nil) then
  5762. exit;
  5763. if h.FHash < ha then cmp := -1 else
  5764. if h.FHash > ha then cmp := 1 else
  5765. cmp := 0;
  5766. if cmp = 0 then
  5767. cmp := CompareKeyNode(k, h);
  5768. if (cmp = 0) then
  5769. break;
  5770. parent := h;
  5771. if (cmp > 0) then
  5772. begin
  5773. h := h.FGt;
  5774. include(branch, depth)
  5775. end else
  5776. begin
  5777. h := h.FLt;
  5778. exclude(branch, depth)
  5779. end;
  5780. inc(depth);
  5781. cmp_shortened_sub_with_path := cmp;
  5782. end;
  5783. rm := h;
  5784. parent_rm := parent;
  5785. rm_depth := depth;
  5786. if (h.FBf < 0) then
  5787. begin
  5788. child := h.FLt;
  5789. exclude(branch, depth);
  5790. cmp := -1;
  5791. end else
  5792. begin
  5793. child := h.FGt;
  5794. include(branch, depth);
  5795. cmp := 1;
  5796. end;
  5797. inc(depth);
  5798. if (child <> nil) then
  5799. begin
  5800. cmp := -cmp;
  5801. repeat
  5802. parent := h;
  5803. h := child;
  5804. if (cmp < 0) then
  5805. begin
  5806. child := h.FLt;
  5807. exclude(branch, depth);
  5808. end else
  5809. begin
  5810. child := h.FGt;
  5811. include(branch, depth);
  5812. end;
  5813. inc(depth);
  5814. until (child = nil);
  5815. if (parent = rm) then
  5816. cmp_shortened_sub_with_path := -cmp else
  5817. cmp_shortened_sub_with_path := cmp;
  5818. if cmp > 0 then
  5819. child := h.FLt else
  5820. child := h.FGt;
  5821. end;
  5822. if (parent = nil) then
  5823. FRoot := child else
  5824. if (cmp_shortened_sub_with_path < 0) then
  5825. parent.FLt := child else
  5826. parent.FGt := child;
  5827. if parent = rm then
  5828. path := h else
  5829. path := parent;
  5830. if (h <> rm) then
  5831. begin
  5832. h.FLt := rm.FLt;
  5833. h.FGt := rm.FGt;
  5834. h.FBf := rm.FBf;
  5835. if (parent_rm = nil) then
  5836. FRoot := h
  5837. else
  5838. begin
  5839. depth := rm_depth - 1;
  5840. if (depth in branch) then
  5841. parent_rm.FGt := h else
  5842. parent_rm.FLt := h;
  5843. end;
  5844. end;
  5845. if (path <> nil) then
  5846. begin
  5847. h := FRoot;
  5848. parent := nil;
  5849. depth := 0;
  5850. while (h <> path) do
  5851. begin
  5852. if (depth in branch) then
  5853. begin
  5854. child := h.FGt;
  5855. h.FGt := parent;
  5856. end else
  5857. begin
  5858. child := h.FLt;
  5859. h.FLt := parent;
  5860. end;
  5861. inc(depth);
  5862. parent := h;
  5863. h := child;
  5864. end;
  5865. reduced_depth := 1;
  5866. cmp := cmp_shortened_sub_with_path;
  5867. while true do
  5868. begin
  5869. if (reduced_depth <> 0) then
  5870. begin
  5871. bf := h.FBf;
  5872. if (cmp < 0) then
  5873. inc(bf) else
  5874. dec(bf);
  5875. if ((bf = -2) or (bf = 2)) then
  5876. begin
  5877. h := balance(h);
  5878. bf := h.FBf;
  5879. end else
  5880. h.FBf := bf;
  5881. reduced_depth := integer(bf = 0);
  5882. end;
  5883. if (parent = nil) then
  5884. break;
  5885. child := h;
  5886. h := parent;
  5887. dec(depth);
  5888. if depth in branch then
  5889. cmp := 1 else
  5890. cmp := -1;
  5891. if (cmp < 0) then
  5892. begin
  5893. parent := h.FLt;
  5894. h.FLt := child;
  5895. end else
  5896. begin
  5897. parent := h.FGt;
  5898. h.FGt := child;
  5899. end;
  5900. end;
  5901. FRoot := h;
  5902. end;
  5903. if rm <> nil then
  5904. begin
  5905. Result := rm.GetValue;
  5906. doDeleteEntry(rm, false);
  5907. dec(FCount);
  5908. end;
  5909. end;
  5910. procedure TSuperAvlTree.Pack(all: boolean);
  5911. var
  5912. node1, node2: TSuperAvlEntry;
  5913. list: TList;
  5914. i: Integer;
  5915. begin
  5916. node1 := FRoot;
  5917. list := TList.Create;
  5918. while node1 <> nil do
  5919. begin
  5920. if (node1.FLt = nil) then
  5921. begin
  5922. node2 := node1.FGt;
  5923. if (node1.FPtr = nil) then
  5924. list.Add(node1) else
  5925. if all then
  5926. node1.Value.Pack(all);
  5927. end
  5928. else
  5929. begin
  5930. node2 := node1.FLt;
  5931. node1.FLt := node2.FGt;
  5932. node2.FGt := node1;
  5933. end;
  5934. node1 := node2;
  5935. end;
  5936. for i := 0 to list.Count - 1 do
  5937. Delete(TSuperAvlEntry(list[i]).FName);
  5938. list.Free;
  5939. end;
  5940. procedure TSuperAvlTree.Clear(all: boolean);
  5941. var
  5942. node1, node2: TSuperAvlEntry;
  5943. begin
  5944. node1 := FRoot;
  5945. while node1 <> nil do
  5946. begin
  5947. if (node1.FLt = nil) then
  5948. begin
  5949. node2 := node1.FGt;
  5950. doDeleteEntry(node1, all);
  5951. end
  5952. else
  5953. begin
  5954. node2 := node1.FLt;
  5955. node1.FLt := node2.FGt;
  5956. node2.FGt := node1;
  5957. end;
  5958. node1 := node2;
  5959. end;
  5960. FRoot := nil;
  5961. FCount := 0;
  5962. end;
  5963. function TSuperAvlTree.CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer;
  5964. begin
  5965. Result := StrComp(PSOChar(k), PSOChar(h.FName));
  5966. end;
  5967. function TSuperAvlTree.CompareNodeNode(node1, node2: TSuperAvlEntry): integer;
  5968. begin
  5969. Result := StrComp(PSOChar(node1.FName), PSOChar(node2.FName));
  5970. end;
  5971. { TSuperAvlIterator }
  5972. (* Initialize depth to invalid value, to indicate iterator is
  5973. ** invalid. (Depth is zero-base.) It's not necessary to initialize
  5974. ** iterators prior to passing them to the "start" function.
  5975. *)
  5976. constructor TSuperAvlIterator.Create(tree: TSuperAvlTree);
  5977. begin
  5978. FDepth := not 0;
  5979. FTree := tree;
  5980. end;
  5981. procedure TSuperAvlIterator.Search(const k: SOString; st: TSuperAvlSearchTypes);
  5982. var
  5983. h: TSuperAvlEntry;
  5984. d: longint;
  5985. cmp, target_cmp: integer;
  5986. ha: Cardinal;
  5987. begin
  5988. ha := TSuperAvlEntry.Hash(k);
  5989. h := FTree.FRoot;
  5990. d := 0;
  5991. FDepth := not 0;
  5992. if (h = nil) then
  5993. exit;
  5994. if (stLess in st) then
  5995. target_cmp := 1 else
  5996. if (stGreater in st) then
  5997. target_cmp := -1 else
  5998. target_cmp := 0;
  5999. while true do
  6000. begin
  6001. if h.FHash < ha then cmp := -1 else
  6002. if h.FHash > ha then cmp := 1 else
  6003. cmp := 0;
  6004. if cmp = 0 then
  6005. cmp := FTree.CompareKeyNode(k, h);
  6006. if (cmp = 0) then
  6007. begin
  6008. if (stEqual in st) then
  6009. begin
  6010. FDepth := d;
  6011. break;
  6012. end;
  6013. cmp := -target_cmp;
  6014. end
  6015. else
  6016. if (target_cmp <> 0) then
  6017. if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then
  6018. FDepth := d;
  6019. if cmp < 0 then
  6020. h := h.FLt else
  6021. h := h.FGt;
  6022. if (h = nil) then
  6023. break;
  6024. if (cmp > 0) then
  6025. include(FBranch, d) else
  6026. exclude(FBranch, d);
  6027. FPath[d] := h;
  6028. inc(d);
  6029. end;
  6030. end;
  6031. procedure TSuperAvlIterator.First;
  6032. var
  6033. h: TSuperAvlEntry;
  6034. begin
  6035. h := FTree.FRoot;
  6036. FDepth := not 0;
  6037. FBranch := [];
  6038. while (h <> nil) do
  6039. begin
  6040. if (FDepth <> not 0) then
  6041. FPath[FDepth] := h;
  6042. inc(FDepth);
  6043. h := h.FLt;
  6044. end;
  6045. end;
  6046. procedure TSuperAvlIterator.Last;
  6047. var
  6048. h: TSuperAvlEntry;
  6049. begin
  6050. h := FTree.FRoot;
  6051. FDepth := not 0;
  6052. FBranch := [0..SUPER_AVL_MAX_DEPTH - 1];
  6053. while (h <> nil) do
  6054. begin
  6055. if (FDepth <> not 0) then
  6056. FPath[FDepth] := h;
  6057. inc(FDepth);
  6058. h := h.FGt;
  6059. end;
  6060. end;
  6061. function TSuperAvlIterator.MoveNext: boolean;
  6062. begin
  6063. if FDepth = not 0 then
  6064. First else
  6065. Next;
  6066. Result := GetIter <> nil;
  6067. end;
  6068. function TSuperAvlIterator.GetIter: TSuperAvlEntry;
  6069. begin
  6070. if (FDepth = not 0) then
  6071. begin
  6072. result := nil;
  6073. exit;
  6074. end;
  6075. if FDepth = 0 then
  6076. Result := FTree.FRoot else
  6077. Result := FPath[FDepth - 1];
  6078. end;
  6079. procedure TSuperAvlIterator.Next;
  6080. var
  6081. h: TSuperAvlEntry;
  6082. begin
  6083. if (FDepth <> not 0) then
  6084. begin
  6085. if FDepth = 0 then
  6086. h := FTree.FRoot.FGt else
  6087. h := FPath[FDepth - 1].FGt;
  6088. if (h = nil) then
  6089. repeat
  6090. if (FDepth = 0) then
  6091. begin
  6092. FDepth := not 0;
  6093. break;
  6094. end;
  6095. dec(FDepth);
  6096. until (not (FDepth in FBranch))
  6097. else
  6098. begin
  6099. include(FBranch, FDepth);
  6100. FPath[FDepth] := h;
  6101. inc(FDepth);
  6102. while true do
  6103. begin
  6104. h := h.FLt;
  6105. if (h = nil) then
  6106. break;
  6107. exclude(FBranch, FDepth);
  6108. FPath[FDepth] := h;
  6109. inc(FDepth);
  6110. end;
  6111. end;
  6112. end;
  6113. end;
  6114. procedure TSuperAvlIterator.Prior;
  6115. var
  6116. h: TSuperAvlEntry;
  6117. begin
  6118. if (FDepth <> not 0) then
  6119. begin
  6120. if FDepth = 0 then
  6121. h := FTree.FRoot.FLt else
  6122. h := FPath[FDepth - 1].FLt;
  6123. if (h = nil) then
  6124. repeat
  6125. if (FDepth = 0) then
  6126. begin
  6127. FDepth := not 0;
  6128. break;
  6129. end;
  6130. dec(FDepth);
  6131. until (FDepth in FBranch)
  6132. else
  6133. begin
  6134. exclude(FBranch, FDepth);
  6135. FPath[FDepth] := h;
  6136. inc(FDepth);
  6137. while true do
  6138. begin
  6139. h := h.FGt;
  6140. if (h = nil) then
  6141. break;
  6142. include(FBranch, FDepth);
  6143. FPath[FDepth] := h;
  6144. inc(FDepth);
  6145. end;
  6146. end;
  6147. end;
  6148. end;
  6149. procedure TSuperAvlTree.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);
  6150. begin
  6151. Entry.Free;
  6152. end;
  6153. function TSuperAvlTree.GetEnumerator: TSuperAvlIterator;
  6154. begin
  6155. Result := TSuperAvlIterator.Create(Self);
  6156. end;
  6157. { TSuperAvlEntry }
  6158. constructor TSuperAvlEntry.Create(const AName: SOString; Obj: Pointer);
  6159. begin
  6160. FName := AName;
  6161. FPtr := Obj;
  6162. FHash := Hash(FName);
  6163. end;
  6164. function TSuperAvlEntry.GetValue: ISuperObject;
  6165. begin
  6166. Result := ISuperObject(FPtr)
  6167. end;
  6168. class function TSuperAvlEntry.Hash(const k: SOString): Cardinal;
  6169. var
  6170. h: cardinal;
  6171. i: Integer;
  6172. begin
  6173. h := 0;
  6174. for i := 1 to Length(k) do
  6175. h := h*129 + ord(k[i]) + $9e370001;
  6176. Result := h;
  6177. end;
  6178. procedure TSuperAvlEntry.SetValue(const val: ISuperObject);
  6179. begin
  6180. ISuperObject(FPtr) := val;
  6181. end;
  6182. { TSuperTableString }
  6183. function TSuperTableString.GetValues: ISuperObject;
  6184. var
  6185. ite: TSuperAvlIterator;
  6186. obj: TSuperAvlEntry;
  6187. begin
  6188. Result := TSuperObject.Create(stArray);
  6189. ite := TSuperAvlIterator.Create(Self);
  6190. try
  6191. ite.First;
  6192. obj := ite.GetIter;
  6193. while obj <> nil do
  6194. begin
  6195. Result.AsArray.Add(obj.Value);
  6196. ite.Next;
  6197. obj := ite.GetIter;
  6198. end;
  6199. finally
  6200. ite.Free;
  6201. end;
  6202. end;
  6203. function TSuperTableString.GetNames: ISuperObject;
  6204. var
  6205. ite: TSuperAvlIterator;
  6206. obj: TSuperAvlEntry;
  6207. begin
  6208. Result := TSuperObject.Create(stArray);
  6209. ite := TSuperAvlIterator.Create(Self);
  6210. try
  6211. ite.First;
  6212. obj := ite.GetIter;
  6213. while obj <> nil do
  6214. begin
  6215. Result.AsArray.Add(TSuperObject.Create(obj.FName));
  6216. ite.Next;
  6217. obj := ite.GetIter;
  6218. end;
  6219. finally
  6220. ite.Free;
  6221. end;
  6222. end;
  6223. procedure TSuperTableString.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);
  6224. begin
  6225. if Entry.Ptr <> nil then
  6226. begin
  6227. if all then Entry.Value.Clear(true);
  6228. Entry.Value := nil;
  6229. end;
  6230. inherited;
  6231. end;
  6232. function TSuperTableString.Find(const k: SOString; var value: ISuperObject): Boolean;
  6233. var
  6234. e: TSuperAvlEntry;
  6235. begin
  6236. e := Search(k);
  6237. if e <> nil then
  6238. begin
  6239. value := e.Value;
  6240. Result := True;
  6241. end else
  6242. Result := False;
  6243. end;
  6244. function TSuperTableString.Exists(const k: SOString): Boolean;
  6245. begin
  6246. Result := Search(k) <> nil;
  6247. end;
  6248. function TSuperTableString.GetO(const k: SOString): ISuperObject;
  6249. var
  6250. e: TSuperAvlEntry;
  6251. begin
  6252. e := Search(k);
  6253. if e <> nil then
  6254. Result := e.Value else
  6255. Result := nil
  6256. end;
  6257. procedure TSuperTableString.PutO(const k: SOString; const value: ISuperObject);
  6258. var
  6259. entry: TSuperAvlEntry;
  6260. begin
  6261. entry := Insert(TSuperAvlEntry.Create(k, Pointer(value)));
  6262. if entry.FPtr <> nil then
  6263. ISuperObject(entry.FPtr)._AddRef;
  6264. end;
  6265. procedure TSuperTableString.PutS(const k: SOString; const value: SOString);
  6266. begin
  6267. PutO(k, TSuperObject.Create(Value));
  6268. end;
  6269. function TSuperTableString.GetS(const k: SOString): SOString;
  6270. var
  6271. obj: ISuperObject;
  6272. begin
  6273. obj := GetO(k);
  6274. if obj <> nil then
  6275. Result := obj.AsString else
  6276. Result := '';
  6277. end;
  6278. procedure TSuperTableString.PutI(const k: SOString; value: SuperInt);
  6279. begin
  6280. PutO(k, TSuperObject.Create(Value));
  6281. end;
  6282. function TSuperTableString.GetI(const k: SOString): SuperInt;
  6283. var
  6284. obj: ISuperObject;
  6285. begin
  6286. obj := GetO(k);
  6287. if obj <> nil then
  6288. Result := obj.AsInteger else
  6289. Result := 0;
  6290. end;
  6291. procedure TSuperTableString.PutD(const k: SOString; value: Double);
  6292. begin
  6293. PutO(k, TSuperObject.Create(Value));
  6294. end;
  6295. procedure TSuperTableString.PutC(const k: SOString; value: Currency);
  6296. begin
  6297. PutO(k, TSuperObject.CreateCurrency(Value));
  6298. end;
  6299. function TSuperTableString.GetC(const k: SOString): Currency;
  6300. var
  6301. obj: ISuperObject;
  6302. begin
  6303. obj := GetO(k);
  6304. if obj <> nil then
  6305. Result := obj.AsCurrency else
  6306. Result := 0.0;
  6307. end;
  6308. function TSuperTableString.GetD(const k: SOString): Double;
  6309. var
  6310. obj: ISuperObject;
  6311. begin
  6312. obj := GetO(k);
  6313. if obj <> nil then
  6314. Result := obj.AsDouble else
  6315. Result := 0.0;
  6316. end;
  6317. procedure TSuperTableString.PutB(const k: SOString; value: Boolean);
  6318. begin
  6319. PutO(k, TSuperObject.Create(Value));
  6320. end;
  6321. function TSuperTableString.GetB(const k: SOString): Boolean;
  6322. var
  6323. obj: ISuperObject;
  6324. begin
  6325. obj := GetO(k);
  6326. if obj <> nil then
  6327. Result := obj.AsBoolean else
  6328. Result := False;
  6329. end;
  6330. {$IFDEF SUPER_METHOD}
  6331. procedure TSuperTableString.PutM(const k: SOString; value: TSuperMethod);
  6332. begin
  6333. PutO(k, TSuperObject.Create(Value));
  6334. end;
  6335. {$ENDIF}
  6336. {$IFDEF SUPER_METHOD}
  6337. function TSuperTableString.GetM(const k: SOString): TSuperMethod;
  6338. var
  6339. obj: ISuperObject;
  6340. begin
  6341. obj := GetO(k);
  6342. if obj <> nil then
  6343. Result := obj.AsMethod else
  6344. Result := nil;
  6345. end;
  6346. {$ENDIF}
  6347. procedure TSuperTableString.PutN(const k: SOString; const value: ISuperObject);
  6348. begin
  6349. if value <> nil then
  6350. PutO(k, TSuperObject.Create(stNull)) else
  6351. PutO(k, value);
  6352. end;
  6353. function TSuperTableString.GetN(const k: SOString): ISuperObject;
  6354. var
  6355. obj: ISuperObject;
  6356. begin
  6357. obj := GetO(k);
  6358. if obj <> nil then
  6359. Result := obj else
  6360. Result := TSuperObject.Create(stNull);
  6361. end;
  6362. {$IFDEF HAVE_RTTI}
  6363. { TSuperAttribute }
  6364. constructor TSuperAttribute.Create(const AName: string);
  6365. begin
  6366. FName := AName;
  6367. end;
  6368. { TSuperRttiContext }
  6369. constructor TSuperRttiContext.Create;
  6370. begin
  6371. Context := TRttiContext.Create;
  6372. SerialFromJson := TDictionary<PTypeInfo, TSerialFromJson>.Create;
  6373. SerialToJson := TDictionary<PTypeInfo, TSerialToJson>.Create;
  6374. SerialFromJson.Add(TypeInfo(Boolean), serialfromboolean);
  6375. SerialFromJson.Add(TypeInfo(TDateTime), serialfromdatetime);
  6376. SerialFromJson.Add(TypeInfo(TGUID), serialfromguid);
  6377. SerialToJson.Add(TypeInfo(Boolean), serialtoboolean);
  6378. SerialToJson.Add(TypeInfo(TDateTime), serialtodatetime);
  6379. SerialToJson.Add(TypeInfo(TGUID), serialtoguid);
  6380. end;
  6381. destructor TSuperRttiContext.Destroy;
  6382. begin
  6383. SerialFromJson.Free;
  6384. SerialToJson.Free;
  6385. Context.Free;
  6386. end;
  6387. class function TSuperRttiContext.GetFieldName(r: TRttiField): string;
  6388. var
  6389. o: TCustomAttribute;
  6390. begin
  6391. for o in r.GetAttributes do
  6392. if o is SOName then
  6393. Exit(SOName(o).Name);
  6394. Result := r.Name;
  6395. end;
  6396. class function TSuperRttiContext.GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;
  6397. var
  6398. o: TCustomAttribute;
  6399. begin
  6400. if not ObjectIsType(obj, stNull) then Exit(obj);
  6401. for o in r.GetAttributes do
  6402. if o is SODefault then
  6403. Exit(SO(SODefault(o).Name));
  6404. Result := obj;
  6405. end;
  6406. function TSuperRttiContext.AsType<T>(const obj: ISuperObject): T;
  6407. var
  6408. ret: TValue;
  6409. begin
  6410. if FromJson(TypeInfo(T), obj, ret) then
  6411. Result := ret.AsType<T> else
  6412. raise exception.Create('Marshalling error');
  6413. end;
  6414. function TSuperRttiContext.AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;
  6415. var
  6416. v: TValue;
  6417. begin
  6418. TValue.Make(@obj, TypeInfo(T), v);
  6419. if index <> nil then
  6420. Result := ToJson(v, index) else
  6421. Result := ToJson(v, so);
  6422. end;
  6423. function TSuperRttiContext.FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject;
  6424. var Value: TValue): Boolean;
  6425. procedure FromChar;
  6426. begin
  6427. if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then
  6428. begin
  6429. Value := string(AnsiString(obj.AsString)[1]);
  6430. Result := True;
  6431. end else
  6432. Result := False;
  6433. end;
  6434. procedure FromWideChar;
  6435. begin
  6436. if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then
  6437. begin
  6438. Value := obj.AsString[1];
  6439. Result := True;
  6440. end else
  6441. Result := False;
  6442. end;
  6443. procedure FromInt64;
  6444. var
  6445. i: Int64;
  6446. begin
  6447. case ObjectGetType(obj) of
  6448. stInt:
  6449. begin
  6450. TValue.Make(nil, TypeInfo, Value);
  6451. TValueData(Value).FAsSInt64 := obj.AsInteger;
  6452. Result := True;
  6453. end;
  6454. stString:
  6455. begin
  6456. if TryStrToInt64(obj.AsString, i) then
  6457. begin
  6458. TValue.Make(nil, TypeInfo, Value);
  6459. TValueData(Value).FAsSInt64 := i;
  6460. Result := True;
  6461. end else
  6462. Result := False;
  6463. end;
  6464. else
  6465. Result := False;
  6466. end;
  6467. end;
  6468. procedure FromInt(const obj: ISuperObject);
  6469. var
  6470. TypeData: PTypeData;
  6471. i: Integer;
  6472. o: ISuperObject;
  6473. begin
  6474. case ObjectGetType(obj) of
  6475. stInt, stBoolean:
  6476. begin
  6477. i := obj.AsInteger;
  6478. TypeData := GetTypeData(TypeInfo);
  6479. if TypeData.MaxValue > TypeData.MinValue then
  6480. Result := (i >= TypeData.MinValue) and (i <= TypeData.MaxValue) else
  6481. Result := (i >= TypeData.MinValue) and (i <= Int64(PCardinal(@TypeData.MaxValue)^));
  6482. if Result then
  6483. TValue.Make(@i, TypeInfo, Value);
  6484. end;
  6485. stString:
  6486. begin
  6487. o := SO(obj.AsString);
  6488. if not ObjectIsType(o, stString) then
  6489. FromInt(o) else
  6490. Result := False;
  6491. end;
  6492. else
  6493. Result := False;
  6494. end;
  6495. end;
  6496. procedure fromSet;
  6497. var
  6498. i: Integer;
  6499. begin
  6500. case ObjectGetType(obj) of
  6501. stInt:
  6502. begin
  6503. TValue.Make(nil, TypeInfo, Value);
  6504. TValueData(Value).FAsSLong := obj.AsInteger;
  6505. Result := True;
  6506. end;
  6507. stString:
  6508. begin
  6509. if TryStrToInt(obj.AsString, i) then
  6510. begin
  6511. TValue.Make(nil, TypeInfo, Value);
  6512. TValueData(Value).FAsSLong := i;
  6513. Result := True;
  6514. end else
  6515. Result := False;
  6516. end;
  6517. else
  6518. Result := False;
  6519. end;
  6520. end;
  6521. procedure FromFloat(const obj: ISuperObject);
  6522. var
  6523. o: ISuperObject;
  6524. begin
  6525. case ObjectGetType(obj) of
  6526. stInt, stDouble, stCurrency:
  6527. begin
  6528. TValue.Make(nil, TypeInfo, Value);
  6529. case GetTypeData(TypeInfo).FloatType of
  6530. ftSingle: TValueData(Value).FAsSingle := obj.AsDouble;
  6531. ftDouble: TValueData(Value).FAsDouble := obj.AsDouble;
  6532. ftExtended: TValueData(Value).FAsExtended := obj.AsDouble;
  6533. ftComp: TValueData(Value).FAsSInt64 := obj.AsInteger;
  6534. ftCurr: TValueData(Value).FAsCurr := obj.AsCurrency;
  6535. end;
  6536. Result := True;
  6537. end;
  6538. stString:
  6539. begin
  6540. o := SO(obj.AsString);
  6541. if not ObjectIsType(o, stString) then
  6542. FromFloat(o) else
  6543. Result := False;
  6544. end
  6545. else
  6546. Result := False;
  6547. end;
  6548. end;
  6549. procedure FromString;
  6550. begin
  6551. case ObjectGetType(obj) of
  6552. stObject, stArray:
  6553. Result := False;
  6554. stnull:
  6555. begin
  6556. Value := '';
  6557. Result := True;
  6558. end;
  6559. else
  6560. Value := obj.AsString;
  6561. Result := True;
  6562. end;
  6563. end;
  6564. procedure FromClass;
  6565. var
  6566. f: TRttiField;
  6567. v: TValue;
  6568. begin
  6569. case ObjectGetType(obj) of
  6570. stObject:
  6571. begin
  6572. Result := True;
  6573. if Value.Kind <> tkClass then
  6574. Value := GetTypeData(TypeInfo).ClassType.Create;
  6575. for f in Context.GetType(Value.AsObject.ClassType).GetFields do
  6576. if f.FieldType <> nil then
  6577. begin
  6578. v := TValue.Empty;
  6579. Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);
  6580. if Result then
  6581. f.SetValue(Value.AsObject, v) else
  6582. Exit;
  6583. end;
  6584. end;
  6585. stNull:
  6586. begin
  6587. Value := nil;
  6588. Result := True;
  6589. end
  6590. else
  6591. // error
  6592. Value := nil;
  6593. Result := False;
  6594. end;
  6595. end;
  6596. procedure FromRecord;
  6597. var
  6598. f: TRttiField;
  6599. p: Pointer;
  6600. v: TValue;
  6601. begin
  6602. Result := True;
  6603. TValue.Make(nil, TypeInfo, Value);
  6604. for f in Context.GetType(TypeInfo).GetFields do
  6605. begin
  6606. if ObjectIsType(obj, stObject) and (f.FieldType <> nil) then
  6607. begin
  6608. {$IFDEF VER210}
  6609. p := IValueData(TValueData(Value).FHeapData).GetReferenceToRawData;
  6610. {$ELSE}
  6611. p := TValueData(Value).FValueData.GetReferenceToRawData;
  6612. {$ENDIF}
  6613. Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);
  6614. if Result then
  6615. f.SetValue(p, v) else
  6616. begin
  6617. //Writeln(f.Name);
  6618. Exit;
  6619. end;
  6620. end else
  6621. begin
  6622. Result := False;
  6623. Exit;
  6624. end;
  6625. end;
  6626. end;
  6627. procedure FromDynArray;
  6628. var
  6629. i: Integer;
  6630. p: Pointer;
  6631. pb: PByte;
  6632. val: TValue;
  6633. typ: PTypeData;
  6634. el: PTypeInfo;
  6635. begin
  6636. case ObjectGetType(obj) of
  6637. stArray:
  6638. begin
  6639. i := obj.AsArray.Length;
  6640. p := nil;
  6641. DynArraySetLength(p, TypeInfo, 1, @i);
  6642. pb := p;
  6643. typ := GetTypeData(TypeInfo);
  6644. if typ.elType <> nil then
  6645. el := typ.elType^ else
  6646. el := typ.elType2^;
  6647. Result := True;
  6648. for i := 0 to i - 1 do
  6649. begin
  6650. Result := FromJson(el, obj.AsArray[i], val);
  6651. if not Result then
  6652. Break;
  6653. val.ExtractRawData(pb);
  6654. val := TValue.Empty;
  6655. Inc(pb, typ.elSize);
  6656. end;
  6657. if Result then
  6658. TValue.MakeWithoutCopy(@p, TypeInfo, Value) else
  6659. DynArrayClear(p, TypeInfo);
  6660. end;
  6661. stNull:
  6662. begin
  6663. TValue.MakeWithoutCopy(nil, TypeInfo, Value);
  6664. Result := True;
  6665. end;
  6666. else
  6667. i := 1;
  6668. p := nil;
  6669. DynArraySetLength(p, TypeInfo, 1, @i);
  6670. pb := p;
  6671. typ := GetTypeData(TypeInfo);
  6672. if typ.elType <> nil then
  6673. el := typ.elType^ else
  6674. el := typ.elType2^;
  6675. Result := FromJson(el, obj, val);
  6676. val.ExtractRawData(pb);
  6677. val := TValue.Empty;
  6678. if Result then
  6679. TValue.MakeWithoutCopy(@p, TypeInfo, Value) else
  6680. DynArrayClear(p, TypeInfo);
  6681. end;
  6682. end;
  6683. procedure FromArray;
  6684. var
  6685. ArrayData: PArrayTypeData;
  6686. idx: Integer;
  6687. function ProcessDim(dim: Byte; const o: ISuperobject): Boolean;
  6688. var
  6689. i: Integer;
  6690. v: TValue;
  6691. a: PTypeData;
  6692. begin
  6693. if ObjectIsType(o, stArray) and (ArrayData.Dims[dim-1] <> nil) then
  6694. begin
  6695. a := @GetTypeData(ArrayData.Dims[dim-1]^).ArrayData;
  6696. if (a.MaxValue - a.MinValue + 1) <> o.AsArray.Length then
  6697. begin
  6698. Result := False;
  6699. Exit;
  6700. end;
  6701. Result := True;
  6702. if dim = ArrayData.DimCount then
  6703. for i := a.MinValue to a.MaxValue do
  6704. begin
  6705. Result := FromJson(ArrayData.ElType^, o.AsArray[i], v);
  6706. if not Result then
  6707. Exit;
  6708. Value.SetArrayElement(idx, v);
  6709. inc(idx);
  6710. end
  6711. else
  6712. for i := a.MinValue to a.MaxValue do
  6713. begin
  6714. Result := ProcessDim(dim + 1, o.AsArray[i]);
  6715. if not Result then
  6716. Exit;
  6717. end;
  6718. end else
  6719. Result := False;
  6720. end;
  6721. var
  6722. i: Integer;
  6723. v: TValue;
  6724. begin
  6725. TValue.Make(nil, TypeInfo, Value);
  6726. ArrayData := @GetTypeData(TypeInfo).ArrayData;
  6727. idx := 0;
  6728. if ArrayData.DimCount = 1 then
  6729. begin
  6730. if ObjectIsType(obj, stArray) and (obj.AsArray.Length = ArrayData.ElCount) then
  6731. begin
  6732. Result := True;
  6733. for i := 0 to ArrayData.ElCount - 1 do
  6734. begin
  6735. Result := FromJson(ArrayData.ElType^, obj.AsArray[i], v);
  6736. if not Result then
  6737. Exit;
  6738. Value.SetArrayElement(idx, v);
  6739. v := TValue.Empty;
  6740. inc(idx);
  6741. end;
  6742. end else
  6743. Result := False;
  6744. end else
  6745. Result := ProcessDim(1, obj);
  6746. end;
  6747. procedure FromClassRef;
  6748. var
  6749. r: TRttiType;
  6750. begin
  6751. if ObjectIsType(obj, stString) then
  6752. begin
  6753. r := Context.FindType(obj.AsString);
  6754. if r <> nil then
  6755. begin
  6756. Value := TRttiInstanceType(r).MetaclassType;
  6757. Result := True;
  6758. end else
  6759. Result := False;
  6760. end else
  6761. Result := False;
  6762. end;
  6763. procedure FromUnknown;
  6764. begin
  6765. case ObjectGetType(obj) of
  6766. stBoolean:
  6767. begin
  6768. Value := obj.AsBoolean;
  6769. Result := True;
  6770. end;
  6771. stDouble:
  6772. begin
  6773. Value := obj.AsDouble;
  6774. Result := True;
  6775. end;
  6776. stCurrency:
  6777. begin
  6778. Value := obj.AsCurrency;
  6779. Result := True;
  6780. end;
  6781. stInt:
  6782. begin
  6783. Value := obj.AsInteger;
  6784. Result := True;
  6785. end;
  6786. stString:
  6787. begin
  6788. Value := obj.AsString;
  6789. Result := True;
  6790. end
  6791. else
  6792. Value := nil;
  6793. Result := False;
  6794. end;
  6795. end;
  6796. procedure FromInterface;
  6797. const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}';
  6798. var
  6799. o: ISuperObject;
  6800. begin
  6801. if CompareMem(@GetTypeData(TypeInfo).Guid, @soguid, SizeOf(TGUID)) then
  6802. begin
  6803. if obj <> nil then
  6804. TValue.Make(@obj, TypeInfo, Value) else
  6805. begin
  6806. o := TSuperObject.Create(stNull);
  6807. TValue.Make(@o, TypeInfo, Value);
  6808. end;
  6809. Result := True;
  6810. end else
  6811. Result := False;
  6812. end;
  6813. var
  6814. Serial: TSerialFromJson;
  6815. begin
  6816. if TypeInfo <> nil then
  6817. begin
  6818. if not SerialFromJson.TryGetValue(TypeInfo, Serial) then
  6819. case TypeInfo.Kind of
  6820. tkChar: FromChar;
  6821. tkInt64: FromInt64;
  6822. tkEnumeration, tkInteger: FromInt(obj);
  6823. tkSet: fromSet;
  6824. tkFloat: FromFloat(obj);
  6825. tkString, tkLString, tkUString, tkWString: FromString;
  6826. tkClass: FromClass;
  6827. tkMethod: ;
  6828. tkWChar: FromWideChar;
  6829. tkRecord: FromRecord;
  6830. tkPointer: ;
  6831. tkInterface: FromInterface;
  6832. tkArray: FromArray;
  6833. tkDynArray: FromDynArray;
  6834. tkClassRef: FromClassRef;
  6835. else
  6836. FromUnknown
  6837. end else
  6838. begin
  6839. TValue.Make(nil, TypeInfo, Value);
  6840. Result := Serial(Self, obj, Value);
  6841. end;
  6842. end else
  6843. Result := False;
  6844. end;
  6845. function TSuperRttiContext.ToJson(var value: TValue; const index: ISuperObject): ISuperObject;
  6846. procedure ToInt64;
  6847. begin
  6848. Result := TSuperObject.Create(SuperInt(Value.AsInt64));
  6849. end;
  6850. procedure ToChar;
  6851. begin
  6852. Result := TSuperObject.Create(string(Value.AsType<AnsiChar>));
  6853. end;
  6854. procedure ToInteger;
  6855. begin
  6856. Result := TSuperObject.Create(TValueData(Value).FAsSLong);
  6857. end;
  6858. procedure ToFloat;
  6859. begin
  6860. case Value.TypeData.FloatType of
  6861. ftSingle: Result := TSuperObject.Create(TValueData(Value).FAsSingle);
  6862. ftDouble: Result := TSuperObject.Create(TValueData(Value).FAsDouble);
  6863. ftExtended: Result := TSuperObject.Create(TValueData(Value).FAsExtended);
  6864. ftComp: Result := TSuperObject.Create(TValueData(Value).FAsSInt64);
  6865. ftCurr: Result := TSuperObject.CreateCurrency(TValueData(Value).FAsCurr);
  6866. end;
  6867. end;
  6868. procedure ToString;
  6869. begin
  6870. Result := TSuperObject.Create(string(Value.AsType<string>));
  6871. end;
  6872. procedure ToClass;
  6873. var
  6874. o: ISuperObject;
  6875. f: TRttiField;
  6876. v: TValue;
  6877. begin
  6878. if TValueData(Value).FAsObject <> nil then
  6879. begin
  6880. o := index[IntToStr(Integer(Value.AsObject))];
  6881. if o = nil then
  6882. begin
  6883. Result := TSuperObject.Create(stObject);
  6884. index[IntToStr(Integer(Value.AsObject))] := Result;
  6885. for f in Context.GetType(Value.AsObject.ClassType).GetFields do
  6886. if f.FieldType <> nil then
  6887. begin
  6888. v := f.GetValue(Value.AsObject);
  6889. Result.AsObject[GetFieldName(f)] := ToJson(v, index);
  6890. end
  6891. end else
  6892. Result := o;
  6893. end else
  6894. Result := nil;
  6895. end;
  6896. procedure ToWChar;
  6897. begin
  6898. Result := TSuperObject.Create(string(Value.AsType<WideChar>));
  6899. end;
  6900. procedure ToVariant;
  6901. begin
  6902. Result := SO(Value.AsVariant);
  6903. end;
  6904. procedure ToRecord;
  6905. var
  6906. f: TRttiField;
  6907. v: TValue;
  6908. begin
  6909. Result := TSuperObject.Create(stObject);
  6910. for f in Context.GetType(Value.TypeInfo).GetFields do
  6911. begin
  6912. {$IFDEF VER210}
  6913. v := f.GetValue(IValueData(TValueData(Value).FHeapData).GetReferenceToRawData);
  6914. {$ELSE}
  6915. v := f.GetValue(TValueData(Value).FValueData.GetReferenceToRawData);
  6916. {$ENDIF}
  6917. Result.AsObject[GetFieldName(f)] := ToJson(v, index);
  6918. end;
  6919. end;
  6920. procedure ToArray;
  6921. var
  6922. idx: Integer;
  6923. ArrayData: PArrayTypeData;
  6924. procedure ProcessDim(dim: Byte; const o: ISuperObject);
  6925. var
  6926. dt: PTypeData;
  6927. i: Integer;
  6928. o2: ISuperObject;
  6929. v: TValue;
  6930. begin
  6931. if ArrayData.Dims[dim-1] = nil then Exit;
  6932. dt := GetTypeData(ArrayData.Dims[dim-1]^);
  6933. if Dim = ArrayData.DimCount then
  6934. for i := dt.MinValue to dt.MaxValue do
  6935. begin
  6936. v := Value.GetArrayElement(idx);
  6937. o.AsArray.Add(toJSon(v, index));
  6938. inc(idx);
  6939. end
  6940. else
  6941. for i := dt.MinValue to dt.MaxValue do
  6942. begin
  6943. o2 := TSuperObject.Create(stArray);
  6944. o.AsArray.Add(o2);
  6945. ProcessDim(dim + 1, o2);
  6946. end;
  6947. end;
  6948. var
  6949. i: Integer;
  6950. v: TValue;
  6951. begin
  6952. Result := TSuperObject.Create(stArray);
  6953. ArrayData := @Value.TypeData.ArrayData;
  6954. idx := 0;
  6955. if ArrayData.DimCount = 1 then
  6956. for i := 0 to ArrayData.ElCount - 1 do
  6957. begin
  6958. v := Value.GetArrayElement(i);
  6959. Result.AsArray.Add(toJSon(v, index))
  6960. end
  6961. else
  6962. ProcessDim(1, Result);
  6963. end;
  6964. procedure ToDynArray;
  6965. var
  6966. i: Integer;
  6967. v: TValue;
  6968. begin
  6969. Result := TSuperObject.Create(stArray);
  6970. for i := 0 to Value.GetArrayLength - 1 do
  6971. begin
  6972. v := Value.GetArrayElement(i);
  6973. Result.AsArray.Add(toJSon(v, index));
  6974. end;
  6975. end;
  6976. procedure ToClassRef;
  6977. begin
  6978. if TValueData(Value).FAsClass <> nil then
  6979. Result := TSuperObject.Create(string(
  6980. TValueData(Value).FAsClass.UnitName + '.' +
  6981. TValueData(Value).FAsClass.ClassName)) else
  6982. Result := nil;
  6983. end;
  6984. procedure ToInterface;
  6985. {$IFNDEF VER210}
  6986. var
  6987. intf: IInterface;
  6988. {$ENDIF}
  6989. begin
  6990. {$IFDEF VER210}
  6991. if TValueData(Value).FHeapData <> nil then
  6992. TValueData(Value).FHeapData.QueryInterface(ISuperObject, Result) else
  6993. Result := nil;
  6994. {$ELSE}
  6995. if TValueData(Value).FValueData <> nil then
  6996. begin
  6997. intf := IInterface(PPointer(TValueData(Value).FValueData.GetReferenceToRawData)^);
  6998. if intf <> nil then
  6999. intf.QueryInterface(ISuperObject, Result) else
  7000. Result := nil;
  7001. end else
  7002. Result := nil;
  7003. {$ENDIF}
  7004. end;
  7005. var
  7006. Serial: TSerialToJson;
  7007. begin
  7008. if not SerialToJson.TryGetValue(value.TypeInfo, Serial) then
  7009. case Value.Kind of
  7010. tkInt64: ToInt64;
  7011. tkChar: ToChar;
  7012. tkSet, tkInteger, tkEnumeration: ToInteger;
  7013. tkFloat: ToFloat;
  7014. tkString, tkLString, tkUString, tkWString: ToString;
  7015. tkClass: ToClass;
  7016. tkWChar: ToWChar;
  7017. tkVariant: ToVariant;
  7018. tkRecord: ToRecord;
  7019. tkArray: ToArray;
  7020. tkDynArray: ToDynArray;
  7021. tkClassRef: ToClassRef;
  7022. tkInterface: ToInterface;
  7023. else
  7024. result := nil;
  7025. end else
  7026. Result := Serial(Self, value, index);
  7027. end;
  7028. { TSuperObjectHelper }
  7029. constructor TSuperObjectHelper.FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil);
  7030. var
  7031. v: TValue;
  7032. ctxowned: Boolean;
  7033. begin
  7034. if ctx = nil then
  7035. begin
  7036. ctx := TSuperRttiContext.Create;
  7037. ctxowned := True;
  7038. end else
  7039. ctxowned := False;
  7040. try
  7041. v := Self;
  7042. if not ctx.FromJson(v.TypeInfo, obj, v) then
  7043. raise Exception.Create('Invalid object');
  7044. finally
  7045. if ctxowned then
  7046. ctx.Free;
  7047. end;
  7048. end;
  7049. constructor TSuperObjectHelper.FromJson(const str: string; ctx: TSuperRttiContext = nil);
  7050. begin
  7051. FromJson(SO(str), ctx);
  7052. end;
  7053. function TSuperObjectHelper.ToJson(ctx: TSuperRttiContext = nil): ISuperObject;
  7054. var
  7055. v: TValue;
  7056. ctxowned: boolean;
  7057. begin
  7058. if ctx = nil then
  7059. begin
  7060. ctx := TSuperRttiContext.Create;
  7061. ctxowned := True;
  7062. end else
  7063. ctxowned := False;
  7064. try
  7065. v := Self;
  7066. Result := ctx.ToJson(v, SO);
  7067. finally
  7068. if ctxowned then
  7069. ctx.Free;
  7070. end;
  7071. end;
  7072. {$ENDIF}
  7073. {$IFDEF DEBUG}
  7074. initialization
  7075. finalization
  7076. //Assert(debugcount = 0, 'Memory leak');
  7077. {$ENDIF}
  7078. end.