superobject.pas 196 KB

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