yyjson.h 296 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846
  1. /*==============================================================================
  2. Copyright (c) 2020 YaoYuan <ibireme@gmail.com>
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in all
  10. copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17. SOFTWARE.
  18. *============================================================================*/
  19. /**
  20. @file yyjson.h
  21. @date 2019-03-09
  22. @author YaoYuan
  23. */
  24. #ifndef YYJSON_H
  25. #define YYJSON_H
  26. /*==============================================================================
  27. * Header Files
  28. *============================================================================*/
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stddef.h>
  32. #include <limits.h>
  33. #include <string.h>
  34. #include <float.h>
  35. /*==============================================================================
  36. * Compile-time Options
  37. *============================================================================*/
  38. /*
  39. Define as 1 to disable JSON reader if JSON parsing is not required.
  40. This will disable these functions at compile-time:
  41. - yyjson_read()
  42. - yyjson_read_opts()
  43. - yyjson_read_file()
  44. - yyjson_read_number()
  45. - yyjson_mut_read_number()
  46. This will reduce the binary size by about 60%.
  47. */
  48. #ifndef YYJSON_DISABLE_READER
  49. #endif
  50. /*
  51. Define as 1 to disable JSON writer if JSON serialization is not required.
  52. This will disable these functions at compile-time:
  53. - yyjson_write()
  54. - yyjson_write_file()
  55. - yyjson_write_opts()
  56. - yyjson_val_write()
  57. - yyjson_val_write_file()
  58. - yyjson_val_write_opts()
  59. - yyjson_mut_write()
  60. - yyjson_mut_write_file()
  61. - yyjson_mut_write_opts()
  62. - yyjson_mut_val_write()
  63. - yyjson_mut_val_write_file()
  64. - yyjson_mut_val_write_opts()
  65. This will reduce the binary size by about 30%.
  66. */
  67. #ifndef YYJSON_DISABLE_WRITER
  68. #endif
  69. /*
  70. Define as 1 to disable JSON Pointer, JSON Patch and JSON Merge Patch supports.
  71. This will disable these functions at compile-time:
  72. - yyjson_ptr_xxx()
  73. - yyjson_mut_ptr_xxx()
  74. - yyjson_doc_ptr_xxx()
  75. - yyjson_mut_doc_ptr_xxx()
  76. - yyjson_patch()
  77. - yyjson_mut_patch()
  78. - yyjson_merge_patch()
  79. - yyjson_mut_merge_patch()
  80. */
  81. #ifndef YYJSON_DISABLE_UTILS
  82. #endif
  83. /*
  84. Define as 1 to disable the fast floating-point number conversion in yyjson,
  85. and use libc's `strtod/snprintf` instead.
  86. This will reduce the binary size by about 30%, but significantly slow down the
  87. floating-point read/write speed.
  88. */
  89. #ifndef YYJSON_DISABLE_FAST_FP_CONV
  90. #endif
  91. /*
  92. Define as 1 to disable non-standard JSON support at compile-time:
  93. - Reading and writing inf/nan literal, such as `NaN`, `-Infinity`.
  94. - Single line and multiple line comments.
  95. - Single trailing comma at the end of an object or array.
  96. - Invalid unicode in string value.
  97. This will also invalidate these run-time options:
  98. - YYJSON_READ_ALLOW_INF_AND_NAN
  99. - YYJSON_READ_ALLOW_COMMENTS
  100. - YYJSON_READ_ALLOW_TRAILING_COMMAS
  101. - YYJSON_READ_ALLOW_INVALID_UNICODE
  102. - YYJSON_WRITE_ALLOW_INF_AND_NAN
  103. - YYJSON_WRITE_ALLOW_INVALID_UNICODE
  104. This will reduce the binary size by about 10%, and speed up the reading and
  105. writing speed by about 2% to 6%.
  106. */
  107. #ifndef YYJSON_DISABLE_NON_STANDARD
  108. #endif
  109. /*
  110. Define as 1 to disable UTF-8 validation at compile time.
  111. If all input strings are guaranteed to be valid UTF-8 encoding (for example,
  112. some language's String object has already validated the encoding), using this
  113. flag can avoid redundant UTF-8 validation in yyjson.
  114. This flag can speed up the reading and writing speed of non-ASCII encoded
  115. strings by about 3% to 7%.
  116. Note: If this flag is used while passing in illegal UTF-8 strings, the
  117. following errors may occur:
  118. - Escaped characters may be ignored when parsing JSON strings.
  119. - Ending quotes may be ignored when parsing JSON strings, causing the string
  120. to be concatenated to the next value.
  121. - When accessing `yyjson_mut_val` for serialization, the string ending may be
  122. accessed out of bounds, causing a segmentation fault.
  123. */
  124. #ifndef YYJSON_DISABLE_UTF8_VALIDATION
  125. #endif
  126. /*
  127. Define as 1 to indicate that the target architecture does not support unaligned
  128. memory access. Please refer to the comments in the C file for details.
  129. */
  130. #ifndef YYJSON_DISABLE_UNALIGNED_MEMORY_ACCESS
  131. #endif
  132. /* Define as 1 to export symbols when building this library as Windows DLL. */
  133. #ifndef YYJSON_EXPORTS
  134. #endif
  135. /* Define as 1 to import symbols when using this library as Windows DLL. */
  136. #ifndef YYJSON_IMPORTS
  137. #endif
  138. /* Define as 1 to include <stdint.h> for compiler which doesn't support C99. */
  139. #ifndef YYJSON_HAS_STDINT_H
  140. #endif
  141. /* Define as 1 to include <stdbool.h> for compiler which doesn't support C99. */
  142. #ifndef YYJSON_HAS_STDBOOL_H
  143. #endif
  144. /*==============================================================================
  145. * Compiler Macros
  146. *============================================================================*/
  147. /** compiler version (MSVC) */
  148. #ifdef _MSC_VER
  149. # define YYJSON_MSC_VER _MSC_VER
  150. #else
  151. # define YYJSON_MSC_VER 0
  152. #endif
  153. /** compiler version (GCC) */
  154. #ifdef __GNUC__
  155. # define YYJSON_GCC_VER __GNUC__
  156. # if defined(__GNUC_PATCHLEVEL__)
  157. # define yyjson_gcc_available(major, minor, patch) \
  158. ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \
  159. >= (major * 10000 + minor * 100 + patch))
  160. # else
  161. # define yyjson_gcc_available(major, minor, patch) \
  162. ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) \
  163. >= (major * 10000 + minor * 100 + patch))
  164. # endif
  165. #else
  166. # define YYJSON_GCC_VER 0
  167. # define yyjson_gcc_available(major, minor, patch) 0
  168. #endif
  169. /** real gcc check */
  170. #if !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__ICC) && \
  171. defined(__GNUC__)
  172. # define YYJSON_IS_REAL_GCC 1
  173. #else
  174. # define YYJSON_IS_REAL_GCC 0
  175. #endif
  176. /** C version (STDC) */
  177. #if defined(__STDC__) && (__STDC__ >= 1) && defined(__STDC_VERSION__)
  178. # define YYJSON_STDC_VER __STDC_VERSION__
  179. #else
  180. # define YYJSON_STDC_VER 0
  181. #endif
  182. /** C++ version */
  183. #if defined(__cplusplus)
  184. # define YYJSON_CPP_VER __cplusplus
  185. #else
  186. # define YYJSON_CPP_VER 0
  187. #endif
  188. /** compiler builtin check (since gcc 10.0, clang 2.6, icc 2021) */
  189. #ifndef yyjson_has_builtin
  190. # ifdef __has_builtin
  191. # define yyjson_has_builtin(x) __has_builtin(x)
  192. # else
  193. # define yyjson_has_builtin(x) 0
  194. # endif
  195. #endif
  196. /** compiler attribute check (since gcc 5.0, clang 2.9, icc 17) */
  197. #ifndef yyjson_has_attribute
  198. # ifdef __has_attribute
  199. # define yyjson_has_attribute(x) __has_attribute(x)
  200. # else
  201. # define yyjson_has_attribute(x) 0
  202. # endif
  203. #endif
  204. /** compiler feature check (since clang 2.6, icc 17) */
  205. #ifndef yyjson_has_feature
  206. # ifdef __has_feature
  207. # define yyjson_has_feature(x) __has_feature(x)
  208. # else
  209. # define yyjson_has_feature(x) 0
  210. # endif
  211. #endif
  212. /** include check (since gcc 5.0, clang 2.7, icc 16, msvc 2017 15.3) */
  213. #ifndef yyjson_has_include
  214. # ifdef __has_include
  215. # define yyjson_has_include(x) __has_include(x)
  216. # else
  217. # define yyjson_has_include(x) 0
  218. # endif
  219. #endif
  220. /** inline for compiler */
  221. #ifndef yyjson_inline
  222. # if YYJSON_MSC_VER >= 1200
  223. # define yyjson_inline __forceinline
  224. # elif defined(_MSC_VER)
  225. # define yyjson_inline __inline
  226. # elif yyjson_has_attribute(always_inline) || YYJSON_GCC_VER >= 4
  227. # define yyjson_inline __inline__ __attribute__((always_inline))
  228. # elif defined(__clang__) || defined(__GNUC__)
  229. # define yyjson_inline __inline__
  230. # elif defined(__cplusplus) || YYJSON_STDC_VER >= 199901L
  231. # define yyjson_inline inline
  232. # else
  233. # define yyjson_inline
  234. # endif
  235. #endif
  236. /** noinline for compiler */
  237. #ifndef yyjson_noinline
  238. # if YYJSON_MSC_VER >= 1400
  239. # define yyjson_noinline __declspec(noinline)
  240. # elif yyjson_has_attribute(noinline) || YYJSON_GCC_VER >= 4
  241. # define yyjson_noinline __attribute__((noinline))
  242. # else
  243. # define yyjson_noinline
  244. # endif
  245. #endif
  246. /** align for compiler */
  247. #ifndef yyjson_align
  248. # if YYJSON_MSC_VER >= 1300
  249. # define yyjson_align(x) __declspec(align(x))
  250. # elif yyjson_has_attribute(aligned) || defined(__GNUC__)
  251. # define yyjson_align(x) __attribute__((aligned(x)))
  252. # elif YYJSON_CPP_VER >= 201103L
  253. # define yyjson_align(x) alignas(x)
  254. # else
  255. # define yyjson_align(x)
  256. # endif
  257. #endif
  258. /** likely for compiler */
  259. #ifndef yyjson_likely
  260. # if yyjson_has_builtin(__builtin_expect) || \
  261. (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
  262. # define yyjson_likely(expr) __builtin_expect(!!(expr), 1)
  263. # else
  264. # define yyjson_likely(expr) (expr)
  265. # endif
  266. #endif
  267. /** unlikely for compiler */
  268. #ifndef yyjson_unlikely
  269. # if yyjson_has_builtin(__builtin_expect) || \
  270. (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
  271. # define yyjson_unlikely(expr) __builtin_expect(!!(expr), 0)
  272. # else
  273. # define yyjson_unlikely(expr) (expr)
  274. # endif
  275. #endif
  276. /** compile-time constant check for compiler */
  277. #ifndef yyjson_constant_p
  278. # if yyjson_has_builtin(__builtin_constant_p) || (YYJSON_GCC_VER >= 3)
  279. # define YYJSON_HAS_CONSTANT_P 1
  280. # define yyjson_constant_p(value) __builtin_constant_p(value)
  281. # else
  282. # define YYJSON_HAS_CONSTANT_P 0
  283. # define yyjson_constant_p(value) 0
  284. # endif
  285. #endif
  286. /** deprecate warning */
  287. #ifndef yyjson_deprecated
  288. # if YYJSON_MSC_VER >= 1400
  289. # define yyjson_deprecated(msg) __declspec(deprecated(msg))
  290. # elif yyjson_has_feature(attribute_deprecated_with_message) || \
  291. (YYJSON_GCC_VER > 4 || (YYJSON_GCC_VER == 4 && __GNUC_MINOR__ >= 5))
  292. # define yyjson_deprecated(msg) __attribute__((deprecated(msg)))
  293. # elif YYJSON_GCC_VER >= 3
  294. # define yyjson_deprecated(msg) __attribute__((deprecated))
  295. # else
  296. # define yyjson_deprecated(msg)
  297. # endif
  298. #endif
  299. /** function export */
  300. #ifndef yyjson_api
  301. # if defined(_WIN32)
  302. # if defined(YYJSON_EXPORTS) && YYJSON_EXPORTS
  303. # define yyjson_api __declspec(dllexport)
  304. # elif defined(YYJSON_IMPORTS) && YYJSON_IMPORTS
  305. # define yyjson_api __declspec(dllimport)
  306. # else
  307. # define yyjson_api
  308. # endif
  309. # elif yyjson_has_attribute(visibility) || YYJSON_GCC_VER >= 4
  310. # define yyjson_api __attribute__((visibility("default")))
  311. # else
  312. # define yyjson_api
  313. # endif
  314. #endif
  315. /** inline function export */
  316. #ifndef yyjson_api_inline
  317. # define yyjson_api_inline static yyjson_inline
  318. #endif
  319. /** stdint (C89 compatible) */
  320. #if (defined(YYJSON_HAS_STDINT_H) && YYJSON_HAS_STDINT_H) || \
  321. YYJSON_MSC_VER >= 1600 || YYJSON_STDC_VER >= 199901L || \
  322. defined(_STDINT_H) || defined(_STDINT_H_) || \
  323. defined(__CLANG_STDINT_H) || defined(_STDINT_H_INCLUDED) || \
  324. yyjson_has_include(<stdint.h>)
  325. # include <stdint.h>
  326. #elif defined(_MSC_VER)
  327. # if _MSC_VER < 1300
  328. typedef signed char int8_t;
  329. typedef signed short int16_t;
  330. typedef signed int int32_t;
  331. typedef unsigned char uint8_t;
  332. typedef unsigned short uint16_t;
  333. typedef unsigned int uint32_t;
  334. typedef signed __int64 int64_t;
  335. typedef unsigned __int64 uint64_t;
  336. # else
  337. typedef signed __int8 int8_t;
  338. typedef signed __int16 int16_t;
  339. typedef signed __int32 int32_t;
  340. typedef unsigned __int8 uint8_t;
  341. typedef unsigned __int16 uint16_t;
  342. typedef unsigned __int32 uint32_t;
  343. typedef signed __int64 int64_t;
  344. typedef unsigned __int64 uint64_t;
  345. # endif
  346. #else
  347. # if UCHAR_MAX == 0xFFU
  348. typedef signed char int8_t;
  349. typedef unsigned char uint8_t;
  350. # else
  351. # error cannot find 8-bit integer type
  352. # endif
  353. # if USHRT_MAX == 0xFFFFU
  354. typedef unsigned short uint16_t;
  355. typedef signed short int16_t;
  356. # elif UINT_MAX == 0xFFFFU
  357. typedef unsigned int uint16_t;
  358. typedef signed int int16_t;
  359. # else
  360. # error cannot find 16-bit integer type
  361. # endif
  362. # if UINT_MAX == 0xFFFFFFFFUL
  363. typedef unsigned int uint32_t;
  364. typedef signed int int32_t;
  365. # elif ULONG_MAX == 0xFFFFFFFFUL
  366. typedef unsigned long uint32_t;
  367. typedef signed long int32_t;
  368. # elif USHRT_MAX == 0xFFFFFFFFUL
  369. typedef unsigned short uint32_t;
  370. typedef signed short int32_t;
  371. # else
  372. # error cannot find 32-bit integer type
  373. # endif
  374. # if defined(__INT64_TYPE__) && defined(__UINT64_TYPE__)
  375. typedef __INT64_TYPE__ int64_t;
  376. typedef __UINT64_TYPE__ uint64_t;
  377. # elif defined(__GNUC__) || defined(__clang__)
  378. # if !defined(_SYS_TYPES_H) && !defined(__int8_t_defined)
  379. __extension__ typedef long long int64_t;
  380. # endif
  381. __extension__ typedef unsigned long long uint64_t;
  382. # elif defined(_LONG_LONG) || defined(__MWERKS__) || defined(_CRAYC) || \
  383. defined(__SUNPRO_C) || defined(__SUNPRO_CC)
  384. typedef long long int64_t;
  385. typedef unsigned long long uint64_t;
  386. # elif (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || \
  387. defined(__WATCOM_INT64__) || defined (__alpha) || defined (__DECC)
  388. typedef __int64 int64_t;
  389. typedef unsigned __int64 uint64_t;
  390. # else
  391. # error cannot find 64-bit integer type
  392. # endif
  393. #endif
  394. /** stdbool (C89 compatible) */
  395. #if (defined(YYJSON_HAS_STDBOOL_H) && YYJSON_HAS_STDBOOL_H) || \
  396. (yyjson_has_include(<stdbool.h>) && !defined(__STRICT_ANSI__)) || \
  397. YYJSON_MSC_VER >= 1800 || YYJSON_STDC_VER >= 199901L
  398. # include <stdbool.h>
  399. #elif !defined(__bool_true_false_are_defined)
  400. # define __bool_true_false_are_defined 1
  401. # if defined(__cplusplus)
  402. # if defined(__GNUC__) && !defined(__STRICT_ANSI__)
  403. # define _Bool bool
  404. # if __cplusplus < 201103L
  405. # define bool bool
  406. # define false false
  407. # define true true
  408. # endif
  409. # endif
  410. # else
  411. # define bool unsigned char
  412. # define true 1
  413. # define false 0
  414. # endif
  415. #endif
  416. /** char bit check */
  417. #if defined(CHAR_BIT)
  418. # if CHAR_BIT != 8
  419. # error non 8-bit char is not supported
  420. # endif
  421. #endif
  422. /**
  423. Microsoft Visual C++ 6.0 doesn't support converting number from u64 to f64:
  424. error C2520: conversion from unsigned __int64 to double not implemented.
  425. */
  426. #ifndef YYJSON_U64_TO_F64_NO_IMPL
  427. # if (0 < YYJSON_MSC_VER) && (YYJSON_MSC_VER <= 1200)
  428. # define YYJSON_U64_TO_F64_NO_IMPL 1
  429. # else
  430. # define YYJSON_U64_TO_F64_NO_IMPL 0
  431. # endif
  432. #endif
  433. /*==============================================================================
  434. * Compile Hint Begin
  435. *============================================================================*/
  436. /* extern "C" begin */
  437. #ifdef __cplusplus
  438. extern "C" {
  439. #endif
  440. /* warning suppress begin */
  441. #if defined(__clang__)
  442. # pragma clang diagnostic push
  443. # pragma clang diagnostic ignored "-Wunused-function"
  444. # pragma clang diagnostic ignored "-Wunused-parameter"
  445. #elif defined(__GNUC__)
  446. # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  447. # pragma GCC diagnostic push
  448. # endif
  449. # pragma GCC diagnostic ignored "-Wunused-function"
  450. # pragma GCC diagnostic ignored "-Wunused-parameter"
  451. #elif defined(_MSC_VER)
  452. # pragma warning(push)
  453. # pragma warning(disable:4800) /* 'int': forcing value to 'true' or 'false' */
  454. #endif
  455. /*==============================================================================
  456. * Version
  457. *============================================================================*/
  458. /** The major version of yyjson. */
  459. #define YYJSON_VERSION_MAJOR 0
  460. /** The minor version of yyjson. */
  461. #define YYJSON_VERSION_MINOR 7
  462. /** The patch version of yyjson. */
  463. #define YYJSON_VERSION_PATCH 0
  464. /** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */
  465. #define YYJSON_VERSION_HEX 0x000700
  466. /** The version string of yyjson. */
  467. #define YYJSON_VERSION_STRING "0.7.0"
  468. /** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */
  469. yyjson_api uint32_t yyjson_version(void);
  470. /*==============================================================================
  471. * JSON Types
  472. *============================================================================*/
  473. /** Type of a JSON value (3 bit). */
  474. typedef uint8_t yyjson_type;
  475. /** No type, invalid. */
  476. #define YYJSON_TYPE_NONE ((uint8_t)0) /* _____000 */
  477. /** Raw string type, no subtype. */
  478. #define YYJSON_TYPE_RAW ((uint8_t)1) /* _____001 */
  479. /** Null type: `null` literal, no subtype. */
  480. #define YYJSON_TYPE_NULL ((uint8_t)2) /* _____010 */
  481. /** Boolean type, subtype: TRUE, FALSE. */
  482. #define YYJSON_TYPE_BOOL ((uint8_t)3) /* _____011 */
  483. /** Number type, subtype: UINT, SINT, REAL. */
  484. #define YYJSON_TYPE_NUM ((uint8_t)4) /* _____100 */
  485. /** String type, subtype: NONE, NOESC. */
  486. #define YYJSON_TYPE_STR ((uint8_t)5) /* _____101 */
  487. /** Array type, no subtype. */
  488. #define YYJSON_TYPE_ARR ((uint8_t)6) /* _____110 */
  489. /** Object type, no subtype. */
  490. #define YYJSON_TYPE_OBJ ((uint8_t)7) /* _____111 */
  491. /** Subtype of a JSON value (2 bit). */
  492. typedef uint8_t yyjson_subtype;
  493. /** No subtype. */
  494. #define YYJSON_SUBTYPE_NONE ((uint8_t)(0 << 3)) /* ___00___ */
  495. /** False subtype: `false` literal. */
  496. #define YYJSON_SUBTYPE_FALSE ((uint8_t)(0 << 3)) /* ___00___ */
  497. /** True subtype: `true` literal. */
  498. #define YYJSON_SUBTYPE_TRUE ((uint8_t)(1 << 3)) /* ___01___ */
  499. /** Unsigned integer subtype: `uint64_t`. */
  500. #define YYJSON_SUBTYPE_UINT ((uint8_t)(0 << 3)) /* ___00___ */
  501. /** Signed integer subtype: `int64_t`. */
  502. #define YYJSON_SUBTYPE_SINT ((uint8_t)(1 << 3)) /* ___01___ */
  503. /** Real number subtype: `double`. */
  504. #define YYJSON_SUBTYPE_REAL ((uint8_t)(2 << 3)) /* ___10___ */
  505. /** String that do not need to be escaped for writing (internal use). */
  506. #define YYJSON_SUBTYPE_NOESC ((uint8_t)(1 << 3)) /* ___01___ */
  507. /** The mask used to extract the type of a JSON value. */
  508. #define YYJSON_TYPE_MASK ((uint8_t)0x07) /* _____111 */
  509. /** The number of bits used by the type. */
  510. #define YYJSON_TYPE_BIT ((uint8_t)3)
  511. /** The mask used to extract the subtype of a JSON value. */
  512. #define YYJSON_SUBTYPE_MASK ((uint8_t)0x18) /* ___11___ */
  513. /** The number of bits used by the subtype. */
  514. #define YYJSON_SUBTYPE_BIT ((uint8_t)2)
  515. /** The mask used to extract the reserved bits of a JSON value. */
  516. #define YYJSON_RESERVED_MASK ((uint8_t)0xE0) /* 111_____ */
  517. /** The number of reserved bits. */
  518. #define YYJSON_RESERVED_BIT ((uint8_t)3)
  519. /** The mask used to extract the tag of a JSON value. */
  520. #define YYJSON_TAG_MASK ((uint8_t)0xFF) /* 11111111 */
  521. /** The number of bits used by the tag. */
  522. #define YYJSON_TAG_BIT ((uint8_t)8)
  523. /** Padding size for JSON reader. */
  524. #define YYJSON_PADDING_SIZE 4
  525. /*==============================================================================
  526. * Allocator
  527. *============================================================================*/
  528. /**
  529. A memory allocator.
  530. Typically you don't need to use it, unless you want to customize your own
  531. memory allocator.
  532. */
  533. typedef struct yyjson_alc {
  534. /** Same as libc's malloc(size), should not be NULL. */
  535. void *(*malloc)(void *ctx, size_t size);
  536. /** Same as libc's realloc(ptr, size), should not be NULL. */
  537. void *(*realloc)(void *ctx, void *ptr, size_t old_size, size_t size);
  538. /** Same as libc's free(ptr), should not be NULL. */
  539. void (*free)(void *ctx, void *ptr);
  540. /** A context for malloc/realloc/free, can be NULL. */
  541. void *ctx;
  542. } yyjson_alc;
  543. /**
  544. A pool allocator uses fixed length pre-allocated memory.
  545. This allocator may be used to avoid malloc/realloc calls. The pre-allocated
  546. memory should be held by the caller. The maximum amount of memory required to
  547. read a JSON can be calculated using the `yyjson_read_max_memory_usage()`
  548. function, but the amount of memory required to write a JSON cannot be directly
  549. calculated.
  550. This is not a general-purpose allocator. If used to read multiple JSON
  551. documents and only some of them are released, it may cause memory
  552. fragmentation, leading to performance degradation and memory waste. Therefore,
  553. it is recommended to use this allocator only for reading or writing a single
  554. JSON document.
  555. @param alc The allocator to be initialized.
  556. If this parameter is NULL, the function will fail and return false.
  557. If `buf` or `size` is invalid, this will be set to an empty allocator.
  558. @param buf The buffer memory for this allocator.
  559. If this parameter is NULL, the function will fail and return false.
  560. @param size The size of `buf`, in bytes.
  561. If this parameter is less than 8 words (32/64 bytes on 32/64-bit OS), the
  562. function will fail and return false.
  563. @return true if the `alc` has been successfully initialized.
  564. @par Example
  565. @code
  566. // parse JSON with stack memory
  567. char buf[1024];
  568. yyjson_alc alc;
  569. yyjson_alc_pool_init(&alc, buf, 1024);
  570. const char *json = "{\"name\":\"Helvetica\",\"size\":16}"
  571. yyjson_doc *doc = yyjson_read_opts(json, strlen(json), 0, &alc, NULL);
  572. // the memory of `doc` is on the stack
  573. @endcode
  574. */
  575. yyjson_api bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, size_t size);
  576. /*==============================================================================
  577. * JSON Structure
  578. *============================================================================*/
  579. /**
  580. An immutable document for reading JSON.
  581. This document holds memory for all its JSON values and strings. When it is no
  582. longer used, the user should call `yyjson_doc_free()` to free its memory.
  583. */
  584. typedef struct yyjson_doc yyjson_doc;
  585. /**
  586. An immutable value for reading JSON.
  587. A JSON Value has the same lifetime as its document. The memory is held by its
  588. document and and cannot be freed alone.
  589. */
  590. typedef struct yyjson_val yyjson_val;
  591. /**
  592. A mutable document for building JSON.
  593. This document holds memory for all its JSON values and strings. When it is no
  594. longer used, the user should call `yyjson_mut_doc_free()` to free its memory.
  595. */
  596. typedef struct yyjson_mut_doc yyjson_mut_doc;
  597. /**
  598. A mutable value for building JSON.
  599. A JSON Value has the same lifetime as its document. The memory is held by its
  600. document and and cannot be freed alone.
  601. */
  602. typedef struct yyjson_mut_val yyjson_mut_val;
  603. /*==============================================================================
  604. * JSON Reader API
  605. *============================================================================*/
  606. /** Run-time options for JSON reader. */
  607. typedef uint32_t yyjson_read_flag;
  608. /** Default option (RFC 8259 compliant):
  609. - Read positive integer as uint64_t.
  610. - Read negative integer as int64_t.
  611. - Read floating-point number as double with round-to-nearest mode.
  612. - Read integer which cannot fit in uint64_t or int64_t as double.
  613. - Report error if double number is infinity.
  614. - Report error if string contains invalid UTF-8 character or BOM.
  615. - Report error on trailing commas, comments, inf and nan literals. */
  616. static const yyjson_read_flag YYJSON_READ_NOFLAG = 0 << 0;
  617. /** Read the input data in-situ.
  618. This option allows the reader to modify and use input data to store string
  619. values, which can increase reading speed slightly.
  620. The caller should hold the input data before free the document.
  621. The input data must be padded by at least `YYJSON_PADDING_SIZE` bytes.
  622. For example: `[1,2]` should be `[1,2]\0\0\0\0`, input length should be 5. */
  623. static const yyjson_read_flag YYJSON_READ_INSITU = 1 << 0;
  624. /** Stop when done instead of issuing an error if there's additional content
  625. after a JSON document. This option may be used to parse small pieces of JSON
  626. in larger data, such as `NDJSON`. */
  627. static const yyjson_read_flag YYJSON_READ_STOP_WHEN_DONE = 1 << 1;
  628. /** Allow single trailing comma at the end of an object or array,
  629. such as `[1,2,3,]`, `{"a":1,"b":2,}` (non-standard). */
  630. static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS = 1 << 2;
  631. /** Allow C-style single line and multiple line comments (non-standard). */
  632. static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS = 1 << 3;
  633. /** Allow inf/nan number and literal, case-insensitive,
  634. such as 1e999, NaN, inf, -Infinity (non-standard). */
  635. static const yyjson_read_flag YYJSON_READ_ALLOW_INF_AND_NAN = 1 << 4;
  636. /** Read all numbers as raw strings (value with `YYJSON_TYPE_RAW` type),
  637. inf/nan literal is also read as raw with `ALLOW_INF_AND_NAN` flag. */
  638. static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW = 1 << 5;
  639. /** Allow reading invalid unicode when parsing string values (non-standard).
  640. Invalid characters will be allowed to appear in the string values, but
  641. invalid escape sequences will still be reported as errors.
  642. This flag does not affect the performance of correctly encoded strings.
  643. @warning Strings in JSON values may contain incorrect encoding when this
  644. option is used, you need to handle these strings carefully to avoid security
  645. risks. */
  646. static const yyjson_read_flag YYJSON_READ_ALLOW_INVALID_UNICODE = 1 << 6;
  647. /** Read big numbers as raw strings. These big numbers include integers that
  648. cannot be represented by `int64_t` and `uint64_t`, and floating-point
  649. numbers that cannot be represented by finite `double`.
  650. The flag will be overridden by `YYJSON_READ_NUMBER_AS_RAW` flag. */
  651. static const yyjson_read_flag YYJSON_READ_BIGNUM_AS_RAW = 1 << 7;
  652. /** Result code for JSON reader. */
  653. typedef uint32_t yyjson_read_code;
  654. /** Success, no error. */
  655. static const yyjson_read_code YYJSON_READ_SUCCESS = 0;
  656. /** Invalid parameter, such as NULL input string or 0 input length. */
  657. static const yyjson_read_code YYJSON_READ_ERROR_INVALID_PARAMETER = 1;
  658. /** Memory allocation failure occurs. */
  659. static const yyjson_read_code YYJSON_READ_ERROR_MEMORY_ALLOCATION = 2;
  660. /** Input JSON string is empty. */
  661. static const yyjson_read_code YYJSON_READ_ERROR_EMPTY_CONTENT = 3;
  662. /** Unexpected content after document, such as `[123]abc`. */
  663. static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CONTENT = 4;
  664. /** Unexpected ending, such as `[123`. */
  665. static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_END = 5;
  666. /** Unexpected character inside the document, such as `[abc]`. */
  667. static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CHARACTER = 6;
  668. /** Invalid JSON structure, such as `[1,]`. */
  669. static const yyjson_read_code YYJSON_READ_ERROR_JSON_STRUCTURE = 7;
  670. /** Invalid comment, such as unclosed multi-line comment. */
  671. static const yyjson_read_code YYJSON_READ_ERROR_INVALID_COMMENT = 8;
  672. /** Invalid number, such as `123.e12`, `000`. */
  673. static const yyjson_read_code YYJSON_READ_ERROR_INVALID_NUMBER = 9;
  674. /** Invalid string, such as invalid escaped character inside a string. */
  675. static const yyjson_read_code YYJSON_READ_ERROR_INVALID_STRING = 10;
  676. /** Invalid JSON literal, such as `truu`. */
  677. static const yyjson_read_code YYJSON_READ_ERROR_LITERAL = 11;
  678. /** Failed to open a file. */
  679. static const yyjson_read_code YYJSON_READ_ERROR_FILE_OPEN = 12;
  680. /** Failed to read a file. */
  681. static const yyjson_read_code YYJSON_READ_ERROR_FILE_READ = 13;
  682. /** Error information for JSON reader. */
  683. typedef struct yyjson_read_err {
  684. /** Error code, see `yyjson_read_code` for all possible values. */
  685. yyjson_read_code code;
  686. /** Error message, constant, no need to free (NULL if success). */
  687. const char *msg;
  688. /** Error byte position for input data (0 if success). */
  689. size_t pos;
  690. } yyjson_read_err;
  691. /**
  692. Read JSON with options.
  693. This function is thread-safe when:
  694. 1. The `dat` is not modified by other threads.
  695. 2. The `alc` is thread-safe or NULL.
  696. @param dat The JSON data (UTF-8 without BOM), null-terminator is not required.
  697. If this parameter is NULL, the function will fail and return NULL.
  698. The `dat` will not be modified without the flag `YYJSON_READ_INSITU`, so you
  699. can pass a `const char *` string and case it to `char *` if you don't use
  700. the `YYJSON_READ_INSITU` flag.
  701. @param len The length of JSON data in bytes.
  702. If this parameter is 0, the function will fail and return NULL.
  703. @param flg The JSON read options.
  704. Multiple options can be combined with `|` operator. 0 means no options.
  705. @param alc The memory allocator used by JSON reader.
  706. Pass NULL to use the libc's default allocator.
  707. @param err A pointer to receive error information.
  708. Pass NULL if you don't need error information.
  709. @return A new JSON document, or NULL if an error occurs.
  710. When it's no longer needed, it should be freed with `yyjson_doc_free()`.
  711. */
  712. yyjson_api yyjson_doc *yyjson_read_opts(char *dat,
  713. size_t len,
  714. yyjson_read_flag flg,
  715. const yyjson_alc *alc,
  716. yyjson_read_err *err);
  717. /**
  718. Read a JSON file.
  719. This function is thread-safe when:
  720. 1. The file is not modified by other threads.
  721. 2. The `alc` is thread-safe or NULL.
  722. @param path The JSON file's path.
  723. If this path is NULL or invalid, the function will fail and return NULL.
  724. @param flg The JSON read options.
  725. Multiple options can be combined with `|` operator. 0 means no options.
  726. @param alc The memory allocator used by JSON reader.
  727. Pass NULL to use the libc's default allocator.
  728. @param err A pointer to receive error information.
  729. Pass NULL if you don't need error information.
  730. @return A new JSON document, or NULL if an error occurs.
  731. When it's no longer needed, it should be freed with `yyjson_doc_free()`.
  732. @warning On 32-bit operating system, files larger than 2GB may fail to read.
  733. */
  734. yyjson_api yyjson_doc *yyjson_read_file(const char *path,
  735. yyjson_read_flag flg,
  736. const yyjson_alc *alc,
  737. yyjson_read_err *err);
  738. /**
  739. Read JSON from a file pointer.
  740. @param fp The file pointer.
  741. The data will be read from the current position of the FILE to the end.
  742. If this fp is NULL or invalid, the function will fail and return NULL.
  743. @param flg The JSON read options.
  744. Multiple options can be combined with `|` operator. 0 means no options.
  745. @param alc The memory allocator used by JSON reader.
  746. Pass NULL to use the libc's default allocator.
  747. @param err A pointer to receive error information.
  748. Pass NULL if you don't need error information.
  749. @return A new JSON document, or NULL if an error occurs.
  750. When it's no longer needed, it should be freed with `yyjson_doc_free()`.
  751. @warning On 32-bit operating system, files larger than 2GB may fail to read.
  752. */
  753. yyjson_api yyjson_doc *yyjson_read_fp(FILE *fp,
  754. yyjson_read_flag flg,
  755. const yyjson_alc *alc,
  756. yyjson_read_err *err);
  757. /**
  758. Read a JSON string.
  759. This function is thread-safe.
  760. @param dat The JSON data (UTF-8 without BOM), null-terminator is not required.
  761. If this parameter is NULL, the function will fail and return NULL.
  762. @param len The length of JSON data in bytes.
  763. If this parameter is 0, the function will fail and return NULL.
  764. @param flg The JSON read options.
  765. Multiple options can be combined with `|` operator. 0 means no options.
  766. @return A new JSON document, or NULL if an error occurs.
  767. When it's no longer needed, it should be freed with `yyjson_doc_free()`.
  768. */
  769. yyjson_api_inline yyjson_doc *yyjson_read(const char *dat,
  770. size_t len,
  771. yyjson_read_flag flg) {
  772. flg &= ~YYJSON_READ_INSITU; /* const string cannot be modified */
  773. return yyjson_read_opts((char *)(void *)(size_t)(const void *)dat,
  774. len, flg, NULL, NULL);
  775. }
  776. /**
  777. Returns the size of maximum memory usage to read a JSON data.
  778. You may use this value to avoid malloc() or calloc() call inside the reader
  779. to get better performance, or read multiple JSON with one piece of memory.
  780. @param len The length of JSON data in bytes.
  781. @param flg The JSON read options.
  782. @return The maximum memory size to read this JSON, or 0 if overflow.
  783. @par Example
  784. @code
  785. // read multiple JSON with same pre-allocated memory
  786. char *dat1, *dat2, *dat3; // JSON data
  787. size_t len1, len2, len3; // JSON length
  788. size_t max_len = MAX(len1, MAX(len2, len3));
  789. yyjson_doc *doc;
  790. // use one allocator for multiple JSON
  791. size_t size = yyjson_read_max_memory_usage(max_len, 0);
  792. void *buf = malloc(size);
  793. yyjson_alc alc;
  794. yyjson_alc_pool_init(&alc, buf, size);
  795. // no more alloc() or realloc() call during reading
  796. doc = yyjson_read_opts(dat1, len1, 0, &alc, NULL);
  797. yyjson_doc_free(doc);
  798. doc = yyjson_read_opts(dat2, len2, 0, &alc, NULL);
  799. yyjson_doc_free(doc);
  800. doc = yyjson_read_opts(dat3, len3, 0, &alc, NULL);
  801. yyjson_doc_free(doc);
  802. free(buf);
  803. @endcode
  804. @see yyjson_alc_pool_init()
  805. */
  806. yyjson_api_inline size_t yyjson_read_max_memory_usage(size_t len,
  807. yyjson_read_flag flg) {
  808. /*
  809. 1. The max value count is (json_size / 2 + 1),
  810. for example: "[1,2,3,4]" size is 9, value count is 5.
  811. 2. Some broken JSON may cost more memory during reading, but fail at end,
  812. for example: "[[[[[[[[".
  813. 3. yyjson use 16 bytes per value, see struct yyjson_val.
  814. 4. yyjson use dynamic memory with a growth factor of 1.5.
  815. The max memory size is (json_size / 2 * 16 * 1.5 + padding).
  816. */
  817. size_t mul = (size_t)12 + !(flg & YYJSON_READ_INSITU);
  818. size_t pad = 256;
  819. size_t max = (size_t)(~(size_t)0);
  820. if (flg & YYJSON_READ_STOP_WHEN_DONE) len = len < 256 ? 256 : len;
  821. if (len >= (max - pad - mul) / mul) return 0;
  822. return len * mul + pad;
  823. }
  824. /**
  825. Read a JSON number.
  826. This function is thread-safe when data is not modified by other threads.
  827. @param dat The JSON data (UTF-8 without BOM), null-terminator is required.
  828. If this parameter is NULL, the function will fail and return NULL.
  829. @param val The output value where result is stored.
  830. If this parameter is NULL, the function will fail and return NULL.
  831. The value will hold either UINT or SINT or REAL number;
  832. @param flg The JSON read options.
  833. Multiple options can be combined with `|` operator. 0 means no options.
  834. Supports `YYJSON_READ_NUMBER_AS_RAW` and `YYJSON_READ_ALLOW_INF_AND_NAN`.
  835. @param alc The memory allocator used for long number.
  836. It is only used when the built-in floating point reader is disabled.
  837. Pass NULL to use the libc's default allocator.
  838. @param err A pointer to receive error information.
  839. Pass NULL if you don't need error information.
  840. @return If successful, a pointer to the character after the last character
  841. used in the conversion, NULL if an error occurs.
  842. */
  843. yyjson_api const char *yyjson_read_number(const char *dat,
  844. yyjson_val *val,
  845. yyjson_read_flag flg,
  846. const yyjson_alc *alc,
  847. yyjson_read_err *err);
  848. /**
  849. Read a JSON number.
  850. This function is thread-safe when data is not modified by other threads.
  851. @param dat The JSON data (UTF-8 without BOM), null-terminator is required.
  852. If this parameter is NULL, the function will fail and return NULL.
  853. @param val The output value where result is stored.
  854. If this parameter is NULL, the function will fail and return NULL.
  855. The value will hold either UINT or SINT or REAL number;
  856. @param flg The JSON read options.
  857. Multiple options can be combined with `|` operator. 0 means no options.
  858. Supports `YYJSON_READ_NUMBER_AS_RAW` and `YYJSON_READ_ALLOW_INF_AND_NAN`.
  859. @param alc The memory allocator used for long number.
  860. It is only used when the built-in floating point reader is disabled.
  861. Pass NULL to use the libc's default allocator.
  862. @param err A pointer to receive error information.
  863. Pass NULL if you don't need error information.
  864. @return If successful, a pointer to the character after the last character
  865. used in the conversion, NULL if an error occurs.
  866. */
  867. yyjson_api_inline const char *yyjson_mut_read_number(const char *dat,
  868. yyjson_mut_val *val,
  869. yyjson_read_flag flg,
  870. const yyjson_alc *alc,
  871. yyjson_read_err *err) {
  872. return yyjson_read_number(dat, (yyjson_val *)val, flg, alc, err);
  873. }
  874. /*==============================================================================
  875. * JSON Writer API
  876. *============================================================================*/
  877. /** Run-time options for JSON writer. */
  878. typedef uint32_t yyjson_write_flag;
  879. /** Default option:
  880. - Write JSON minify.
  881. - Report error on inf or nan number.
  882. - Report error on invalid UTF-8 string.
  883. - Do not escape unicode or slash. */
  884. static const yyjson_write_flag YYJSON_WRITE_NOFLAG = 0 << 0;
  885. /** Write JSON pretty with 4 space indent. */
  886. static const yyjson_write_flag YYJSON_WRITE_PRETTY = 1 << 0;
  887. /** Escape unicode as `uXXXX`, make the output ASCII only. */
  888. static const yyjson_write_flag YYJSON_WRITE_ESCAPE_UNICODE = 1 << 1;
  889. /** Escape '/' as '\/'. */
  890. static const yyjson_write_flag YYJSON_WRITE_ESCAPE_SLASHES = 1 << 2;
  891. /** Write inf and nan number as 'Infinity' and 'NaN' literal (non-standard). */
  892. static const yyjson_write_flag YYJSON_WRITE_ALLOW_INF_AND_NAN = 1 << 3;
  893. /** Write inf and nan number as null literal.
  894. This flag will override `YYJSON_WRITE_ALLOW_INF_AND_NAN` flag. */
  895. static const yyjson_write_flag YYJSON_WRITE_INF_AND_NAN_AS_NULL = 1 << 4;
  896. /** Allow invalid unicode when encoding string values (non-standard).
  897. Invalid characters in string value will be copied byte by byte.
  898. If `YYJSON_WRITE_ESCAPE_UNICODE` flag is also set, invalid character will be
  899. escaped as `U+FFFD` (replacement character).
  900. This flag does not affect the performance of correctly encoded strings. */
  901. static const yyjson_write_flag YYJSON_WRITE_ALLOW_INVALID_UNICODE = 1 << 5;
  902. /** Write JSON pretty with 2 space indent.
  903. This flag will override `YYJSON_WRITE_PRETTY` flag. */
  904. static const yyjson_write_flag YYJSON_WRITE_PRETTY_TWO_SPACES = 1 << 6;
  905. /** Result code for JSON writer */
  906. typedef uint32_t yyjson_write_code;
  907. /** Success, no error. */
  908. static const yyjson_write_code YYJSON_WRITE_SUCCESS = 0;
  909. /** Invalid parameter, such as NULL document. */
  910. static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_PARAMETER = 1;
  911. /** Memory allocation failure occurs. */
  912. static const yyjson_write_code YYJSON_WRITE_ERROR_MEMORY_ALLOCATION = 2;
  913. /** Invalid value type in JSON document. */
  914. static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_VALUE_TYPE = 3;
  915. /** NaN or Infinity number occurs. */
  916. static const yyjson_write_code YYJSON_WRITE_ERROR_NAN_OR_INF = 4;
  917. /** Failed to open a file. */
  918. static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_OPEN = 5;
  919. /** Failed to write a file. */
  920. static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_WRITE = 6;
  921. /** Invalid unicode in string. */
  922. static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_STRING = 7;
  923. /** Error information for JSON writer. */
  924. typedef struct yyjson_write_err {
  925. /** Error code, see `yyjson_write_code` for all possible values. */
  926. yyjson_write_code code;
  927. /** Error message, constant, no need to free (NULL if success). */
  928. const char *msg;
  929. } yyjson_write_err;
  930. /*==============================================================================
  931. * JSON Document Writer API
  932. *============================================================================*/
  933. /**
  934. Write a document to JSON string with options.
  935. This function is thread-safe when:
  936. The `alc` is thread-safe or NULL.
  937. @param doc The JSON document.
  938. If this doc is NULL or has no root, the function will fail and return false.
  939. @param flg The JSON write options.
  940. Multiple options can be combined with `|` operator. 0 means no options.
  941. @param alc The memory allocator used by JSON writer.
  942. Pass NULL to use the libc's default allocator.
  943. @param len A pointer to receive output length in bytes (not including the
  944. null-terminator). Pass NULL if you don't need length information.
  945. @param err A pointer to receive error information.
  946. Pass NULL if you don't need error information.
  947. @return A new JSON string, or NULL if an error occurs.
  948. This string is encoded as UTF-8 with a null-terminator.
  949. When it's no longer needed, it should be freed with free() or alc->free().
  950. */
  951. yyjson_api char *yyjson_write_opts(const yyjson_doc *doc,
  952. yyjson_write_flag flg,
  953. const yyjson_alc *alc,
  954. size_t *len,
  955. yyjson_write_err *err);
  956. /**
  957. Write a document to JSON file with options.
  958. This function is thread-safe when:
  959. 1. The file is not accessed by other threads.
  960. 2. The `alc` is thread-safe or NULL.
  961. @param path The JSON file's path.
  962. If this path is NULL or invalid, the function will fail and return false.
  963. If this file is not empty, the content will be discarded.
  964. @param doc The JSON document.
  965. If this doc is NULL or has no root, the function will fail and return false.
  966. @param flg The JSON write options.
  967. Multiple options can be combined with `|` operator. 0 means no options.
  968. @param alc The memory allocator used by JSON writer.
  969. Pass NULL to use the libc's default allocator.
  970. @param err A pointer to receive error information.
  971. Pass NULL if you don't need error information.
  972. @return true if successful, false if an error occurs.
  973. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  974. */
  975. yyjson_api bool yyjson_write_file(const char *path,
  976. const yyjson_doc *doc,
  977. yyjson_write_flag flg,
  978. const yyjson_alc *alc,
  979. yyjson_write_err *err);
  980. /**
  981. Write a document to file pointer with options.
  982. @param fp The file pointer.
  983. The data will be written to the current position of the file.
  984. If this fp is NULL or invalid, the function will fail and return false.
  985. @param doc The JSON document.
  986. If this doc is NULL or has no root, the function will fail and return false.
  987. @param flg The JSON write options.
  988. Multiple options can be combined with `|` operator. 0 means no options.
  989. @param alc The memory allocator used by JSON writer.
  990. Pass NULL to use the libc's default allocator.
  991. @param err A pointer to receive error information.
  992. Pass NULL if you don't need error information.
  993. @return true if successful, false if an error occurs.
  994. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  995. */
  996. yyjson_api bool yyjson_write_fp(FILE *fp,
  997. const yyjson_doc *doc,
  998. yyjson_write_flag flg,
  999. const yyjson_alc *alc,
  1000. yyjson_write_err *err);
  1001. /**
  1002. Write a document to JSON string.
  1003. This function is thread-safe.
  1004. @param doc The JSON document.
  1005. If this doc is NULL or has no root, the function will fail and return false.
  1006. @param flg The JSON write options.
  1007. Multiple options can be combined with `|` operator. 0 means no options.
  1008. @param len A pointer to receive output length in bytes (not including the
  1009. null-terminator). Pass NULL if you don't need length information.
  1010. @return A new JSON string, or NULL if an error occurs.
  1011. This string is encoded as UTF-8 with a null-terminator.
  1012. When it's no longer needed, it should be freed with free().
  1013. */
  1014. yyjson_api_inline char *yyjson_write(const yyjson_doc *doc,
  1015. yyjson_write_flag flg,
  1016. size_t *len) {
  1017. return yyjson_write_opts(doc, flg, NULL, len, NULL);
  1018. }
  1019. /**
  1020. Write a document to JSON string with options.
  1021. This function is thread-safe when:
  1022. 1. The `doc` is not modified by other threads.
  1023. 2. The `alc` is thread-safe or NULL.
  1024. @param doc The mutable JSON document.
  1025. If this doc is NULL or has no root, the function will fail and return false.
  1026. @param flg The JSON write options.
  1027. Multiple options can be combined with `|` operator. 0 means no options.
  1028. @param alc The memory allocator used by JSON writer.
  1029. Pass NULL to use the libc's default allocator.
  1030. @param len A pointer to receive output length in bytes (not including the
  1031. null-terminator). Pass NULL if you don't need length information.
  1032. @param err A pointer to receive error information.
  1033. Pass NULL if you don't need error information.
  1034. @return A new JSON string, or NULL if an error occurs.
  1035. This string is encoded as UTF-8 with a null-terminator.
  1036. When it's no longer needed, it should be freed with free() or alc->free().
  1037. */
  1038. yyjson_api char *yyjson_mut_write_opts(const yyjson_mut_doc *doc,
  1039. yyjson_write_flag flg,
  1040. const yyjson_alc *alc,
  1041. size_t *len,
  1042. yyjson_write_err *err);
  1043. /**
  1044. Write a document to JSON file with options.
  1045. This function is thread-safe when:
  1046. 1. The file is not accessed by other threads.
  1047. 2. The `doc` is not modified by other threads.
  1048. 3. The `alc` is thread-safe or NULL.
  1049. @param path The JSON file's path.
  1050. If this path is NULL or invalid, the function will fail and return false.
  1051. If this file is not empty, the content will be discarded.
  1052. @param doc The mutable JSON document.
  1053. If this doc is NULL or has no root, the function will fail and return false.
  1054. @param flg The JSON write options.
  1055. Multiple options can be combined with `|` operator. 0 means no options.
  1056. @param alc The memory allocator used by JSON writer.
  1057. Pass NULL to use the libc's default allocator.
  1058. @param err A pointer to receive error information.
  1059. Pass NULL if you don't need error information.
  1060. @return true if successful, false if an error occurs.
  1061. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1062. */
  1063. yyjson_api bool yyjson_mut_write_file(const char *path,
  1064. const yyjson_mut_doc *doc,
  1065. yyjson_write_flag flg,
  1066. const yyjson_alc *alc,
  1067. yyjson_write_err *err);
  1068. /**
  1069. Write a document to file pointer with options.
  1070. @param fp The file pointer.
  1071. The data will be written to the current position of the file.
  1072. If this fp is NULL or invalid, the function will fail and return false.
  1073. @param doc The mutable JSON document.
  1074. If this doc is NULL or has no root, the function will fail and return false.
  1075. @param flg The JSON write options.
  1076. Multiple options can be combined with `|` operator. 0 means no options.
  1077. @param alc The memory allocator used by JSON writer.
  1078. Pass NULL to use the libc's default allocator.
  1079. @param err A pointer to receive error information.
  1080. Pass NULL if you don't need error information.
  1081. @return true if successful, false if an error occurs.
  1082. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1083. */
  1084. yyjson_api bool yyjson_mut_write_fp(FILE *fp,
  1085. const yyjson_mut_doc *doc,
  1086. yyjson_write_flag flg,
  1087. const yyjson_alc *alc,
  1088. yyjson_write_err *err);
  1089. /**
  1090. Write a document to JSON string.
  1091. This function is thread-safe when:
  1092. The `doc` is not modified by other threads.
  1093. @param doc The JSON document.
  1094. If this doc is NULL or has no root, the function will fail and return false.
  1095. @param flg The JSON write options.
  1096. Multiple options can be combined with `|` operator. 0 means no options.
  1097. @param len A pointer to receive output length in bytes (not including the
  1098. null-terminator). Pass NULL if you don't need length information.
  1099. @return A new JSON string, or NULL if an error occurs.
  1100. This string is encoded as UTF-8 with a null-terminator.
  1101. When it's no longer needed, it should be freed with free().
  1102. */
  1103. yyjson_api_inline char *yyjson_mut_write(const yyjson_mut_doc *doc,
  1104. yyjson_write_flag flg,
  1105. size_t *len) {
  1106. return yyjson_mut_write_opts(doc, flg, NULL, len, NULL);
  1107. }
  1108. /*==============================================================================
  1109. * JSON Value Writer API
  1110. *============================================================================*/
  1111. /**
  1112. Write a value to JSON string with options.
  1113. This function is thread-safe when:
  1114. The `alc` is thread-safe or NULL.
  1115. @param val The JSON root value.
  1116. If this parameter is NULL, the function will fail and return NULL.
  1117. @param flg The JSON write options.
  1118. Multiple options can be combined with `|` operator. 0 means no options.
  1119. @param alc The memory allocator used by JSON writer.
  1120. Pass NULL to use the libc's default allocator.
  1121. @param len A pointer to receive output length in bytes (not including the
  1122. null-terminator). Pass NULL if you don't need length information.
  1123. @param err A pointer to receive error information.
  1124. Pass NULL if you don't need error information.
  1125. @return A new JSON string, or NULL if an error occurs.
  1126. This string is encoded as UTF-8 with a null-terminator.
  1127. When it's no longer needed, it should be freed with free() or alc->free().
  1128. */
  1129. yyjson_api char *yyjson_val_write_opts(const yyjson_val *val,
  1130. yyjson_write_flag flg,
  1131. const yyjson_alc *alc,
  1132. size_t *len,
  1133. yyjson_write_err *err);
  1134. /**
  1135. Write a value to JSON file with options.
  1136. This function is thread-safe when:
  1137. 1. The file is not accessed by other threads.
  1138. 2. The `alc` is thread-safe or NULL.
  1139. @param path The JSON file's path.
  1140. If this path is NULL or invalid, the function will fail and return false.
  1141. If this file is not empty, the content will be discarded.
  1142. @param val The JSON root value.
  1143. If this parameter is NULL, the function will fail and return NULL.
  1144. @param flg The JSON write options.
  1145. Multiple options can be combined with `|` operator. 0 means no options.
  1146. @param alc The memory allocator used by JSON writer.
  1147. Pass NULL to use the libc's default allocator.
  1148. @param err A pointer to receive error information.
  1149. Pass NULL if you don't need error information.
  1150. @return true if successful, false if an error occurs.
  1151. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1152. */
  1153. yyjson_api bool yyjson_val_write_file(const char *path,
  1154. const yyjson_val *val,
  1155. yyjson_write_flag flg,
  1156. const yyjson_alc *alc,
  1157. yyjson_write_err *err);
  1158. /**
  1159. Write a value to file pointer with options.
  1160. @param fp The file pointer.
  1161. The data will be written to the current position of the file.
  1162. If this path is NULL or invalid, the function will fail and return false.
  1163. @param val The JSON root value.
  1164. If this parameter is NULL, the function will fail and return NULL.
  1165. @param flg The JSON write options.
  1166. Multiple options can be combined with `|` operator. 0 means no options.
  1167. @param alc The memory allocator used by JSON writer.
  1168. Pass NULL to use the libc's default allocator.
  1169. @param err A pointer to receive error information.
  1170. Pass NULL if you don't need error information.
  1171. @return true if successful, false if an error occurs.
  1172. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1173. */
  1174. yyjson_api bool yyjson_val_write_fp(FILE *fp,
  1175. const yyjson_val *val,
  1176. yyjson_write_flag flg,
  1177. const yyjson_alc *alc,
  1178. yyjson_write_err *err);
  1179. /**
  1180. Write a value to JSON string.
  1181. This function is thread-safe.
  1182. @param val The JSON root value.
  1183. If this parameter is NULL, the function will fail and return NULL.
  1184. @param flg The JSON write options.
  1185. Multiple options can be combined with `|` operator. 0 means no options.
  1186. @param len A pointer to receive output length in bytes (not including the
  1187. null-terminator). Pass NULL if you don't need length information.
  1188. @return A new JSON string, or NULL if an error occurs.
  1189. This string is encoded as UTF-8 with a null-terminator.
  1190. When it's no longer needed, it should be freed with free().
  1191. */
  1192. yyjson_api_inline char *yyjson_val_write(const yyjson_val *val,
  1193. yyjson_write_flag flg,
  1194. size_t *len) {
  1195. return yyjson_val_write_opts(val, flg, NULL, len, NULL);
  1196. }
  1197. /**
  1198. Write a value to JSON string with options.
  1199. This function is thread-safe when:
  1200. 1. The `val` is not modified by other threads.
  1201. 2. The `alc` is thread-safe or NULL.
  1202. @param val The mutable JSON root value.
  1203. If this parameter is NULL, the function will fail and return NULL.
  1204. @param flg The JSON write options.
  1205. Multiple options can be combined with `|` operator. 0 means no options.
  1206. @param alc The memory allocator used by JSON writer.
  1207. Pass NULL to use the libc's default allocator.
  1208. @param len A pointer to receive output length in bytes (not including the
  1209. null-terminator). Pass NULL if you don't need length information.
  1210. @param err A pointer to receive error information.
  1211. Pass NULL if you don't need error information.
  1212. @return A new JSON string, or NULL if an error occurs.
  1213. This string is encoded as UTF-8 with a null-terminator.
  1214. When it's no longer needed, it should be freed with free() or alc->free().
  1215. */
  1216. yyjson_api char *yyjson_mut_val_write_opts(const yyjson_mut_val *val,
  1217. yyjson_write_flag flg,
  1218. const yyjson_alc *alc,
  1219. size_t *len,
  1220. yyjson_write_err *err);
  1221. /**
  1222. Write a value to JSON file with options.
  1223. This function is thread-safe when:
  1224. 1. The file is not accessed by other threads.
  1225. 2. The `val` is not modified by other threads.
  1226. 3. The `alc` is thread-safe or NULL.
  1227. @param path The JSON file's path.
  1228. If this path is NULL or invalid, the function will fail and return false.
  1229. If this file is not empty, the content will be discarded.
  1230. @param val The mutable JSON root value.
  1231. If this parameter is NULL, the function will fail and return NULL.
  1232. @param flg The JSON write options.
  1233. Multiple options can be combined with `|` operator. 0 means no options.
  1234. @param alc The memory allocator used by JSON writer.
  1235. Pass NULL to use the libc's default allocator.
  1236. @param err A pointer to receive error information.
  1237. Pass NULL if you don't need error information.
  1238. @return true if successful, false if an error occurs.
  1239. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1240. */
  1241. yyjson_api bool yyjson_mut_val_write_file(const char *path,
  1242. const yyjson_mut_val *val,
  1243. yyjson_write_flag flg,
  1244. const yyjson_alc *alc,
  1245. yyjson_write_err *err);
  1246. /**
  1247. Write a value to JSON file with options.
  1248. @param fp The file pointer.
  1249. The data will be written to the current position of the file.
  1250. If this path is NULL or invalid, the function will fail and return false.
  1251. @param val The mutable JSON root value.
  1252. If this parameter is NULL, the function will fail and return NULL.
  1253. @param flg The JSON write options.
  1254. Multiple options can be combined with `|` operator. 0 means no options.
  1255. @param alc The memory allocator used by JSON writer.
  1256. Pass NULL to use the libc's default allocator.
  1257. @param err A pointer to receive error information.
  1258. Pass NULL if you don't need error information.
  1259. @return true if successful, false if an error occurs.
  1260. @warning On 32-bit operating system, files larger than 2GB may fail to write.
  1261. */
  1262. yyjson_api bool yyjson_mut_val_write_fp(FILE *fp,
  1263. const yyjson_mut_val *val,
  1264. yyjson_write_flag flg,
  1265. const yyjson_alc *alc,
  1266. yyjson_write_err *err);
  1267. /**
  1268. Write a value to JSON string.
  1269. This function is thread-safe when:
  1270. The `val` is not modified by other threads.
  1271. @param val The JSON root value.
  1272. If this parameter is NULL, the function will fail and return NULL.
  1273. @param flg The JSON write options.
  1274. Multiple options can be combined with `|` operator. 0 means no options.
  1275. @param len A pointer to receive output length in bytes (not including the
  1276. null-terminator). Pass NULL if you don't need length information.
  1277. @return A new JSON string, or NULL if an error occurs.
  1278. This string is encoded as UTF-8 with a null-terminator.
  1279. When it's no longer needed, it should be freed with free().
  1280. */
  1281. yyjson_api_inline char *yyjson_mut_val_write(const yyjson_mut_val *val,
  1282. yyjson_write_flag flg,
  1283. size_t *len) {
  1284. return yyjson_mut_val_write_opts(val, flg, NULL, len, NULL);
  1285. }
  1286. /*==============================================================================
  1287. * JSON Document API
  1288. *============================================================================*/
  1289. /** Returns the root value of this JSON document.
  1290. Returns NULL if `doc` is NULL. */
  1291. yyjson_api_inline yyjson_val *yyjson_doc_get_root(yyjson_doc *doc);
  1292. /** Returns read size of input JSON data.
  1293. Returns 0 if `doc` is NULL.
  1294. For example: the read size of `[1,2,3]` is 7 bytes. */
  1295. yyjson_api_inline size_t yyjson_doc_get_read_size(yyjson_doc *doc);
  1296. /** Returns total value count in this JSON document.
  1297. Returns 0 if `doc` is NULL.
  1298. For example: the value count of `[1,2,3]` is 4. */
  1299. yyjson_api_inline size_t yyjson_doc_get_val_count(yyjson_doc *doc);
  1300. /** Release the JSON document and free the memory.
  1301. After calling this function, the `doc` and all values from the `doc` are no
  1302. longer available. This function will do nothing if the `doc` is NULL. */
  1303. yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc);
  1304. /*==============================================================================
  1305. * JSON Value Type API
  1306. *============================================================================*/
  1307. /** Returns whether the JSON value is raw.
  1308. Returns false if `val` is NULL. */
  1309. yyjson_api_inline bool yyjson_is_raw(yyjson_val *val);
  1310. /** Returns whether the JSON value is `null`.
  1311. Returns false if `val` is NULL. */
  1312. yyjson_api_inline bool yyjson_is_null(yyjson_val *val);
  1313. /** Returns whether the JSON value is `true`.
  1314. Returns false if `val` is NULL. */
  1315. yyjson_api_inline bool yyjson_is_true(yyjson_val *val);
  1316. /** Returns whether the JSON value is `false`.
  1317. Returns false if `val` is NULL. */
  1318. yyjson_api_inline bool yyjson_is_false(yyjson_val *val);
  1319. /** Returns whether the JSON value is bool (true/false).
  1320. Returns false if `val` is NULL. */
  1321. yyjson_api_inline bool yyjson_is_bool(yyjson_val *val);
  1322. /** Returns whether the JSON value is unsigned integer (uint64_t).
  1323. Returns false if `val` is NULL. */
  1324. yyjson_api_inline bool yyjson_is_uint(yyjson_val *val);
  1325. /** Returns whether the JSON value is signed integer (int64_t).
  1326. Returns false if `val` is NULL. */
  1327. yyjson_api_inline bool yyjson_is_sint(yyjson_val *val);
  1328. /** Returns whether the JSON value is integer (uint64_t/int64_t).
  1329. Returns false if `val` is NULL. */
  1330. yyjson_api_inline bool yyjson_is_int(yyjson_val *val);
  1331. /** Returns whether the JSON value is real number (double).
  1332. Returns false if `val` is NULL. */
  1333. yyjson_api_inline bool yyjson_is_real(yyjson_val *val);
  1334. /** Returns whether the JSON value is number (uint64_t/int64_t/double).
  1335. Returns false if `val` is NULL. */
  1336. yyjson_api_inline bool yyjson_is_num(yyjson_val *val);
  1337. /** Returns whether the JSON value is string.
  1338. Returns false if `val` is NULL. */
  1339. yyjson_api_inline bool yyjson_is_str(yyjson_val *val);
  1340. /** Returns whether the JSON value is array.
  1341. Returns false if `val` is NULL. */
  1342. yyjson_api_inline bool yyjson_is_arr(yyjson_val *val);
  1343. /** Returns whether the JSON value is object.
  1344. Returns false if `val` is NULL. */
  1345. yyjson_api_inline bool yyjson_is_obj(yyjson_val *val);
  1346. /** Returns whether the JSON value is container (array/object).
  1347. Returns false if `val` is NULL. */
  1348. yyjson_api_inline bool yyjson_is_ctn(yyjson_val *val);
  1349. /*==============================================================================
  1350. * JSON Value Content API
  1351. *============================================================================*/
  1352. /** Returns the JSON value's type.
  1353. Returns YYJSON_TYPE_NONE if `val` is NULL. */
  1354. yyjson_api_inline yyjson_type yyjson_get_type(yyjson_val *val);
  1355. /** Returns the JSON value's subtype.
  1356. Returns YYJSON_SUBTYPE_NONE if `val` is NULL. */
  1357. yyjson_api_inline yyjson_subtype yyjson_get_subtype(yyjson_val *val);
  1358. /** Returns the JSON value's tag.
  1359. Returns 0 if `val` is NULL. */
  1360. yyjson_api_inline uint8_t yyjson_get_tag(yyjson_val *val);
  1361. /** Returns the JSON value's type description.
  1362. The return value should be one of these strings: "raw", "null", "string",
  1363. "array", "object", "true", "false", "uint", "sint", "real", "unknown". */
  1364. yyjson_api_inline const char *yyjson_get_type_desc(yyjson_val *val);
  1365. /** Returns the content if the value is raw.
  1366. Returns NULL if `val` is NULL or type is not raw. */
  1367. yyjson_api_inline const char *yyjson_get_raw(yyjson_val *val);
  1368. /** Returns the content if the value is bool.
  1369. Returns NULL if `val` is NULL or type is not bool. */
  1370. yyjson_api_inline bool yyjson_get_bool(yyjson_val *val);
  1371. /** Returns the content and cast to uint64_t.
  1372. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1373. yyjson_api_inline uint64_t yyjson_get_uint(yyjson_val *val);
  1374. /** Returns the content and cast to int64_t.
  1375. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1376. yyjson_api_inline int64_t yyjson_get_sint(yyjson_val *val);
  1377. /** Returns the content and cast to int.
  1378. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1379. yyjson_api_inline int yyjson_get_int(yyjson_val *val);
  1380. /** Returns the content if the value is real number, or 0.0 on error.
  1381. Returns 0.0 if `val` is NULL or type is not real(double). */
  1382. yyjson_api_inline double yyjson_get_real(yyjson_val *val);
  1383. /** Returns the content and typecast to `double` if the value is number.
  1384. Returns 0.0 if `val` is NULL or type is not number(uint/sint/real). */
  1385. yyjson_api_inline double yyjson_get_num(yyjson_val *val);
  1386. /** Returns the content if the value is string.
  1387. Returns NULL if `val` is NULL or type is not string. */
  1388. yyjson_api_inline const char *yyjson_get_str(yyjson_val *val);
  1389. /** Returns the content length (string length, array size, object size.
  1390. Returns 0 if `val` is NULL or type is not string/array/object. */
  1391. yyjson_api_inline size_t yyjson_get_len(yyjson_val *val);
  1392. /** Returns whether the JSON value is equals to a string.
  1393. Returns false if input is NULL or type is not string. */
  1394. yyjson_api_inline bool yyjson_equals_str(yyjson_val *val, const char *str);
  1395. /** Returns whether the JSON value is equals to a string.
  1396. The `str` should be a UTF-8 string, null-terminator is not required.
  1397. Returns false if input is NULL or type is not string. */
  1398. yyjson_api_inline bool yyjson_equals_strn(yyjson_val *val, const char *str,
  1399. size_t len);
  1400. /** Returns whether two JSON values are equal (deep compare).
  1401. Returns false if input is NULL.
  1402. @note the result may be inaccurate if object has duplicate keys.
  1403. @warning This function is recursive and may cause a stack overflow
  1404. if the object level is too deep. */
  1405. yyjson_api_inline bool yyjson_equals(yyjson_val *lhs, yyjson_val *rhs);
  1406. /** Set the value to raw.
  1407. Returns false if input is NULL or `val` is object or array.
  1408. @warning This will modify the `immutable` value, use with caution. */
  1409. yyjson_api_inline bool yyjson_set_raw(yyjson_val *val,
  1410. const char *raw, size_t len);
  1411. /** Set the value to null.
  1412. Returns false if input is NULL or `val` is object or array.
  1413. @warning This will modify the `immutable` value, use with caution. */
  1414. yyjson_api_inline bool yyjson_set_null(yyjson_val *val);
  1415. /** Set the value to bool.
  1416. Returns false if input is NULL or `val` is object or array.
  1417. @warning This will modify the `immutable` value, use with caution. */
  1418. yyjson_api_inline bool yyjson_set_bool(yyjson_val *val, bool num);
  1419. /** Set the value to uint.
  1420. Returns false if input is NULL or `val` is object or array.
  1421. @warning This will modify the `immutable` value, use with caution. */
  1422. yyjson_api_inline bool yyjson_set_uint(yyjson_val *val, uint64_t num);
  1423. /** Set the value to sint.
  1424. Returns false if input is NULL or `val` is object or array.
  1425. @warning This will modify the `immutable` value, use with caution. */
  1426. yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num);
  1427. /** Set the value to int.
  1428. Returns false if input is NULL or `val` is object or array.
  1429. @warning This will modify the `immutable` value, use with caution. */
  1430. yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int num);
  1431. /** Set the value to real.
  1432. Returns false if input is NULL or `val` is object or array.
  1433. @warning This will modify the `immutable` value, use with caution. */
  1434. yyjson_api_inline bool yyjson_set_real(yyjson_val *val, double num);
  1435. /** Set the value to string (null-terminated).
  1436. Returns false if input is NULL or `val` is object or array.
  1437. @warning This will modify the `immutable` value, use with caution. */
  1438. yyjson_api_inline bool yyjson_set_str(yyjson_val *val, const char *str);
  1439. /** Set the value to string (with length).
  1440. Returns false if input is NULL or `val` is object or array.
  1441. @warning This will modify the `immutable` value, use with caution. */
  1442. yyjson_api_inline bool yyjson_set_strn(yyjson_val *val,
  1443. const char *str, size_t len);
  1444. /*==============================================================================
  1445. * JSON Array API
  1446. *============================================================================*/
  1447. /** Returns the number of elements in this array.
  1448. Returns 0 if `arr` is NULL or type is not array. */
  1449. yyjson_api_inline size_t yyjson_arr_size(yyjson_val *arr);
  1450. /** Returns the element at the specified position in this array.
  1451. Returns NULL if array is NULL/empty or the index is out of bounds.
  1452. @warning This function takes a linear search time if array is not flat.
  1453. For example: `[1,{},3]` is flat, `[1,[2],3]` is not flat. */
  1454. yyjson_api_inline yyjson_val *yyjson_arr_get(yyjson_val *arr, size_t idx);
  1455. /** Returns the first element of this array.
  1456. Returns NULL if `arr` is NULL/empty or type is not array. */
  1457. yyjson_api_inline yyjson_val *yyjson_arr_get_first(yyjson_val *arr);
  1458. /** Returns the last element of this array.
  1459. Returns NULL if `arr` is NULL/empty or type is not array.
  1460. @warning This function takes a linear search time if array is not flat.
  1461. For example: `[1,{},3]` is flat, `[1,[2],3]` is not flat.*/
  1462. yyjson_api_inline yyjson_val *yyjson_arr_get_last(yyjson_val *arr);
  1463. /*==============================================================================
  1464. * JSON Array Iterator API
  1465. *============================================================================*/
  1466. /**
  1467. A JSON array iterator.
  1468. @par Example
  1469. @code
  1470. yyjson_val *val;
  1471. yyjson_arr_iter iter = yyjson_arr_iter_with(arr);
  1472. while ((val = yyjson_arr_iter_next(&iter))) {
  1473. your_func(val);
  1474. }
  1475. @endcode
  1476. */
  1477. typedef struct yyjson_arr_iter {
  1478. size_t idx; /**< next value's index */
  1479. size_t max; /**< maximum index (arr.size) */
  1480. yyjson_val *cur; /**< next value */
  1481. } yyjson_arr_iter;
  1482. /**
  1483. Initialize an iterator for this array.
  1484. @param arr The array to be iterated over.
  1485. If this parameter is NULL or not an array, `iter` will be set to empty.
  1486. @param iter The iterator to be initialized.
  1487. If this parameter is NULL, the function will fail and return false.
  1488. @return true if the `iter` has been successfully initialized.
  1489. @note The iterator does not need to be destroyed.
  1490. */
  1491. yyjson_api_inline bool yyjson_arr_iter_init(yyjson_val *arr,
  1492. yyjson_arr_iter *iter);
  1493. /**
  1494. Create an iterator with an array , same as `yyjson_arr_iter_init()`.
  1495. @param arr The array to be iterated over.
  1496. If this parameter is NULL or not an array, an empty iterator will returned.
  1497. @return A new iterator for the array.
  1498. @note The iterator does not need to be destroyed.
  1499. */
  1500. yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(yyjson_val *arr);
  1501. /**
  1502. Returns whether the iteration has more elements.
  1503. If `iter` is NULL, this function will return false.
  1504. */
  1505. yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter *iter);
  1506. /**
  1507. Returns the next element in the iteration, or NULL on end.
  1508. If `iter` is NULL, this function will return NULL.
  1509. */
  1510. yyjson_api_inline yyjson_val *yyjson_arr_iter_next(yyjson_arr_iter *iter);
  1511. /**
  1512. Macro for iterating over an array.
  1513. It works like iterator, but with a more intuitive API.
  1514. @par Example
  1515. @code
  1516. size_t idx, max;
  1517. yyjson_val *val;
  1518. yyjson_arr_foreach(arr, idx, max, val) {
  1519. your_func(idx, val);
  1520. }
  1521. @endcode
  1522. */
  1523. #define yyjson_arr_foreach(arr, idx, max, val) \
  1524. for ((idx) = 0, \
  1525. (max) = yyjson_arr_size(arr), \
  1526. (val) = yyjson_arr_get_first(arr); \
  1527. (idx) < (max); \
  1528. (idx)++, \
  1529. (val) = unsafe_yyjson_get_next(val))
  1530. /*==============================================================================
  1531. * JSON Object API
  1532. *============================================================================*/
  1533. /** Returns the number of key-value pairs in this object.
  1534. Returns 0 if `obj` is NULL or type is not object. */
  1535. yyjson_api_inline size_t yyjson_obj_size(yyjson_val *obj);
  1536. /** Returns the value to which the specified key is mapped.
  1537. Returns NULL if this object contains no mapping for the key.
  1538. Returns NULL if `obj/key` is NULL, or type is not object.
  1539. The `key` should be a null-terminated UTF-8 string.
  1540. @warning This function takes a linear search time. */
  1541. yyjson_api_inline yyjson_val *yyjson_obj_get(yyjson_val *obj, const char *key);
  1542. /** Returns the value to which the specified key is mapped.
  1543. Returns NULL if this object contains no mapping for the key.
  1544. Returns NULL if `obj/key` is NULL, or type is not object.
  1545. The `key` should be a UTF-8 string, null-terminator is not required.
  1546. The `key_len` should be the length of the key, in bytes.
  1547. @warning This function takes a linear search time. */
  1548. yyjson_api_inline yyjson_val *yyjson_obj_getn(yyjson_val *obj, const char *key,
  1549. size_t key_len);
  1550. /*==============================================================================
  1551. * JSON Object Iterator API
  1552. *============================================================================*/
  1553. /**
  1554. A JSON object iterator.
  1555. @par Example
  1556. @code
  1557. yyjson_val *key, *val;
  1558. yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
  1559. while ((key = yyjson_obj_iter_next(&iter))) {
  1560. val = yyjson_obj_iter_get_val(key);
  1561. your_func(key, val);
  1562. }
  1563. @endcode
  1564. If the ordering of the keys is known at compile-time, you can use this method
  1565. to speed up value lookups:
  1566. @code
  1567. // {"k1":1, "k2": 3, "k3": 3}
  1568. yyjson_val *key, *val;
  1569. yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
  1570. yyjson_val *v1 = yyjson_obj_iter_get(&iter, "k1");
  1571. yyjson_val *v3 = yyjson_obj_iter_get(&iter, "k3");
  1572. @endcode
  1573. @see yyjson_obj_iter_get() and yyjson_obj_iter_getn()
  1574. */
  1575. typedef struct yyjson_obj_iter {
  1576. size_t idx; /**< next key's index */
  1577. size_t max; /**< maximum key index (obj.size) */
  1578. yyjson_val *cur; /**< next key */
  1579. yyjson_val *obj; /**< the object being iterated */
  1580. } yyjson_obj_iter;
  1581. /**
  1582. Initialize an iterator for this object.
  1583. @param obj The object to be iterated over.
  1584. If this parameter is NULL or not an object, `iter` will be set to empty.
  1585. @param iter The iterator to be initialized.
  1586. If this parameter is NULL, the function will fail and return false.
  1587. @return true if the `iter` has been successfully initialized.
  1588. @note The iterator does not need to be destroyed.
  1589. */
  1590. yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val *obj,
  1591. yyjson_obj_iter *iter);
  1592. /**
  1593. Create an iterator with an object, same as `yyjson_obj_iter_init()`.
  1594. @param obj The object to be iterated over.
  1595. If this parameter is NULL or not an object, an empty iterator will returned.
  1596. @return A new iterator for the object.
  1597. @note The iterator does not need to be destroyed.
  1598. */
  1599. yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(yyjson_val *obj);
  1600. /**
  1601. Returns whether the iteration has more elements.
  1602. If `iter` is NULL, this function will return false.
  1603. */
  1604. yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter *iter);
  1605. /**
  1606. Returns the next key in the iteration, or NULL on end.
  1607. If `iter` is NULL, this function will return NULL.
  1608. */
  1609. yyjson_api_inline yyjson_val *yyjson_obj_iter_next(yyjson_obj_iter *iter);
  1610. /**
  1611. Returns the value for key inside the iteration.
  1612. If `iter` is NULL, this function will return NULL.
  1613. */
  1614. yyjson_api_inline yyjson_val *yyjson_obj_iter_get_val(yyjson_val *key);
  1615. /**
  1616. Iterates to a specified key and returns the value.
  1617. This function does the same thing as `yyjson_obj_get()`, but is much faster
  1618. if the ordering of the keys is known at compile-time and you are using the same
  1619. order to look up the values. If the key exists in this object, then the
  1620. iterator will stop at the next key, otherwise the iterator will not change and
  1621. NULL is returned.
  1622. @param iter The object iterator, should not be NULL.
  1623. @param key The key, should be a UTF-8 string with null-terminator.
  1624. @return The value to which the specified key is mapped.
  1625. NULL if this object contains no mapping for the key or input is invalid.
  1626. @warning This function takes a linear search time if the key is not nearby.
  1627. */
  1628. yyjson_api_inline yyjson_val *yyjson_obj_iter_get(yyjson_obj_iter *iter,
  1629. const char *key);
  1630. /**
  1631. Iterates to a specified key and returns the value.
  1632. This function does the same thing as `yyjson_obj_getn()`, but is much faster
  1633. if the ordering of the keys is known at compile-time and you are using the same
  1634. order to look up the values. If the key exists in this object, then the
  1635. iterator will stop at the next key, otherwise the iterator will not change and
  1636. NULL is returned.
  1637. @param iter The object iterator, should not be NULL.
  1638. @param key The key, should be a UTF-8 string, null-terminator is not required.
  1639. @param key_len The the length of `key`, in bytes.
  1640. @return The value to which the specified key is mapped.
  1641. NULL if this object contains no mapping for the key or input is invalid.
  1642. @warning This function takes a linear search time if the key is not nearby.
  1643. */
  1644. yyjson_api_inline yyjson_val *yyjson_obj_iter_getn(yyjson_obj_iter *iter,
  1645. const char *key,
  1646. size_t key_len);
  1647. /**
  1648. Macro for iterating over an object.
  1649. It works like iterator, but with a more intuitive API.
  1650. @par Example
  1651. @code
  1652. size_t idx, max;
  1653. yyjson_val *key, *val;
  1654. yyjson_obj_foreach(obj, idx, max, key, val) {
  1655. your_func(key, val);
  1656. }
  1657. @endcode
  1658. */
  1659. #define yyjson_obj_foreach(obj, idx, max, key, val) \
  1660. for ((idx) = 0, \
  1661. (max) = yyjson_obj_size(obj), \
  1662. (key) = (obj) ? unsafe_yyjson_get_first(obj) : NULL, \
  1663. (val) = (key) + 1; \
  1664. (idx) < (max); \
  1665. (idx)++, \
  1666. (key) = unsafe_yyjson_get_next(val), \
  1667. (val) = (key) + 1)
  1668. /*==============================================================================
  1669. * Mutable JSON Document API
  1670. *============================================================================*/
  1671. /** Returns the root value of this JSON document.
  1672. Returns NULL if `doc` is NULL. */
  1673. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_root(yyjson_mut_doc *doc);
  1674. /** Sets the root value of this JSON document.
  1675. Pass NULL to clear root value of the document. */
  1676. yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc,
  1677. yyjson_mut_val *root);
  1678. /**
  1679. Set the string pool size for a mutable document.
  1680. This function does not allocate memory immediately, but uses the size when
  1681. the next memory allocation is needed.
  1682. If the caller knows the approximate bytes of strings that the document needs to
  1683. store (e.g. copy string with `yyjson_mut_strcpy` function), setting a larger
  1684. size can avoid multiple memory allocations and improve performance.
  1685. @param doc The mutable document.
  1686. @param len The desired string pool size in bytes (total string length).
  1687. @return true if successful, false if size is 0 or overflow.
  1688. */
  1689. yyjson_api bool yyjson_mut_doc_set_str_pool_size(yyjson_mut_doc *doc,
  1690. size_t len);
  1691. /**
  1692. Set the value pool size for a mutable document.
  1693. This function does not allocate memory immediately, but uses the size when
  1694. the next memory allocation is needed.
  1695. If the caller knows the approximate number of values that the document needs to
  1696. store (e.g. create new value with `yyjson_mut_xxx` functions), setting a larger
  1697. size can avoid multiple memory allocations and improve performance.
  1698. @param doc The mutable document.
  1699. @param count The desired value pool size (number of `yyjson_mut_val`).
  1700. @return true if successful, false if size is 0 or overflow.
  1701. */
  1702. yyjson_api bool yyjson_mut_doc_set_val_pool_size(yyjson_mut_doc *doc,
  1703. size_t count);
  1704. /** Release the JSON document and free the memory.
  1705. After calling this function, the `doc` and all values from the `doc` are no
  1706. longer available. This function will do nothing if the `doc` is NULL. */
  1707. yyjson_api void yyjson_mut_doc_free(yyjson_mut_doc *doc);
  1708. /** Creates and returns a new mutable JSON document, returns NULL on error.
  1709. If allocator is NULL, the default allocator will be used. */
  1710. yyjson_api yyjson_mut_doc *yyjson_mut_doc_new(const yyjson_alc *alc);
  1711. /** Copies and returns a new mutable document from input, returns NULL on error.
  1712. This makes a `deep-copy` on the immutable document.
  1713. If allocator is NULL, the default allocator will be used.
  1714. @note `imut_doc` -> `mut_doc`. */
  1715. yyjson_api yyjson_mut_doc *yyjson_doc_mut_copy(yyjson_doc *doc,
  1716. const yyjson_alc *alc);
  1717. /** Copies and returns a new mutable document from input, returns NULL on error.
  1718. This makes a `deep-copy` on the mutable document.
  1719. If allocator is NULL, the default allocator will be used.
  1720. @note `mut_doc` -> `mut_doc`. */
  1721. yyjson_api yyjson_mut_doc *yyjson_mut_doc_mut_copy(yyjson_mut_doc *doc,
  1722. const yyjson_alc *alc);
  1723. /** Copies and returns a new mutable value from input, returns NULL on error.
  1724. This makes a `deep-copy` on the immutable value.
  1725. The memory was managed by mutable document.
  1726. @note `imut_val` -> `mut_val`. */
  1727. yyjson_api yyjson_mut_val *yyjson_val_mut_copy(yyjson_mut_doc *doc,
  1728. yyjson_val *val);
  1729. /** Copies and returns a new mutable value from input, returns NULL on error.
  1730. This makes a `deep-copy` on the mutable value.
  1731. The memory was managed by mutable document.
  1732. @note `mut_val` -> `mut_val`.
  1733. @warning This function is recursive and may cause a stack overflow
  1734. if the object level is too deep. */
  1735. yyjson_api yyjson_mut_val *yyjson_mut_val_mut_copy(yyjson_mut_doc *doc,
  1736. yyjson_mut_val *val);
  1737. /** Copies and returns a new immutable document from input,
  1738. returns NULL on error. This makes a `deep-copy` on the mutable document.
  1739. The returned document should be freed with `yyjson_doc_free()`.
  1740. @note `mut_doc` -> `imut_doc`.
  1741. @warning This function is recursive and may cause a stack overflow
  1742. if the object level is too deep. */
  1743. yyjson_api yyjson_doc *yyjson_mut_doc_imut_copy(yyjson_mut_doc *doc,
  1744. const yyjson_alc *alc);
  1745. /** Copies and returns a new immutable document from input,
  1746. returns NULL on error. This makes a `deep-copy` on the mutable value.
  1747. The returned document should be freed with `yyjson_doc_free()`.
  1748. @note `mut_val` -> `imut_doc`.
  1749. @warning This function is recursive and may cause a stack overflow
  1750. if the object level is too deep. */
  1751. yyjson_api yyjson_doc *yyjson_mut_val_imut_copy(yyjson_mut_val *val,
  1752. const yyjson_alc *alc);
  1753. /*==============================================================================
  1754. * Mutable JSON Value Type API
  1755. *============================================================================*/
  1756. /** Returns whether the JSON value is raw.
  1757. Returns false if `val` is NULL. */
  1758. yyjson_api_inline bool yyjson_mut_is_raw(yyjson_mut_val *val);
  1759. /** Returns whether the JSON value is `null`.
  1760. Returns false if `val` is NULL. */
  1761. yyjson_api_inline bool yyjson_mut_is_null(yyjson_mut_val *val);
  1762. /** Returns whether the JSON value is `true`.
  1763. Returns false if `val` is NULL. */
  1764. yyjson_api_inline bool yyjson_mut_is_true(yyjson_mut_val *val);
  1765. /** Returns whether the JSON value is `false`.
  1766. Returns false if `val` is NULL. */
  1767. yyjson_api_inline bool yyjson_mut_is_false(yyjson_mut_val *val);
  1768. /** Returns whether the JSON value is bool (true/false).
  1769. Returns false if `val` is NULL. */
  1770. yyjson_api_inline bool yyjson_mut_is_bool(yyjson_mut_val *val);
  1771. /** Returns whether the JSON value is unsigned integer (uint64_t).
  1772. Returns false if `val` is NULL. */
  1773. yyjson_api_inline bool yyjson_mut_is_uint(yyjson_mut_val *val);
  1774. /** Returns whether the JSON value is signed integer (int64_t).
  1775. Returns false if `val` is NULL. */
  1776. yyjson_api_inline bool yyjson_mut_is_sint(yyjson_mut_val *val);
  1777. /** Returns whether the JSON value is integer (uint64_t/int64_t).
  1778. Returns false if `val` is NULL. */
  1779. yyjson_api_inline bool yyjson_mut_is_int(yyjson_mut_val *val);
  1780. /** Returns whether the JSON value is real number (double).
  1781. Returns false if `val` is NULL. */
  1782. yyjson_api_inline bool yyjson_mut_is_real(yyjson_mut_val *val);
  1783. /** Returns whether the JSON value is number (uint/sint/real).
  1784. Returns false if `val` is NULL. */
  1785. yyjson_api_inline bool yyjson_mut_is_num(yyjson_mut_val *val);
  1786. /** Returns whether the JSON value is string.
  1787. Returns false if `val` is NULL. */
  1788. yyjson_api_inline bool yyjson_mut_is_str(yyjson_mut_val *val);
  1789. /** Returns whether the JSON value is array.
  1790. Returns false if `val` is NULL. */
  1791. yyjson_api_inline bool yyjson_mut_is_arr(yyjson_mut_val *val);
  1792. /** Returns whether the JSON value is object.
  1793. Returns false if `val` is NULL. */
  1794. yyjson_api_inline bool yyjson_mut_is_obj(yyjson_mut_val *val);
  1795. /** Returns whether the JSON value is container (array/object).
  1796. Returns false if `val` is NULL. */
  1797. yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val *val);
  1798. /*==============================================================================
  1799. * Mutable JSON Value Content API
  1800. *============================================================================*/
  1801. /** Returns the JSON value's type.
  1802. Returns `YYJSON_TYPE_NONE` if `val` is NULL. */
  1803. yyjson_api_inline yyjson_type yyjson_mut_get_type(yyjson_mut_val *val);
  1804. /** Returns the JSON value's subtype.
  1805. Returns `YYJSON_SUBTYPE_NONE` if `val` is NULL. */
  1806. yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(yyjson_mut_val *val);
  1807. /** Returns the JSON value's tag.
  1808. Returns 0 if `val` is NULL. */
  1809. yyjson_api_inline uint8_t yyjson_mut_get_tag(yyjson_mut_val *val);
  1810. /** Returns the JSON value's type description.
  1811. The return value should be one of these strings: "raw", "null", "string",
  1812. "array", "object", "true", "false", "uint", "sint", "real", "unknown". */
  1813. yyjson_api_inline const char *yyjson_mut_get_type_desc(yyjson_mut_val *val);
  1814. /** Returns the content if the value is raw.
  1815. Returns NULL if `val` is NULL or type is not raw. */
  1816. yyjson_api_inline const char *yyjson_mut_get_raw(yyjson_mut_val *val);
  1817. /** Returns the content if the value is bool.
  1818. Returns NULL if `val` is NULL or type is not bool. */
  1819. yyjson_api_inline bool yyjson_mut_get_bool(yyjson_mut_val *val);
  1820. /** Returns the content and cast to uint64_t.
  1821. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1822. yyjson_api_inline uint64_t yyjson_mut_get_uint(yyjson_mut_val *val);
  1823. /** Returns the content and cast to int64_t.
  1824. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1825. yyjson_api_inline int64_t yyjson_mut_get_sint(yyjson_mut_val *val);
  1826. /** Returns the content and cast to int.
  1827. Returns 0 if `val` is NULL or type is not integer(sint/uint). */
  1828. yyjson_api_inline int yyjson_mut_get_int(yyjson_mut_val *val);
  1829. /** Returns the content if the value is real number.
  1830. Returns 0.0 if `val` is NULL or type is not real(double). */
  1831. yyjson_api_inline double yyjson_mut_get_real(yyjson_mut_val *val);
  1832. /** Returns the content and typecast to `double` if the value is number.
  1833. Returns 0.0 if `val` is NULL or type is not number(uint/sint/real). */
  1834. yyjson_api_inline double yyjson_mut_get_num(yyjson_mut_val *val);
  1835. /** Returns the content if the value is string.
  1836. Returns NULL if `val` is NULL or type is not string. */
  1837. yyjson_api_inline const char *yyjson_mut_get_str(yyjson_mut_val *val);
  1838. /** Returns the content length (string length, array size, object size.
  1839. Returns 0 if `val` is NULL or type is not string/array/object. */
  1840. yyjson_api_inline size_t yyjson_mut_get_len(yyjson_mut_val *val);
  1841. /** Returns whether the JSON value is equals to a string.
  1842. The `str` should be a null-terminated UTF-8 string.
  1843. Returns false if input is NULL or type is not string. */
  1844. yyjson_api_inline bool yyjson_mut_equals_str(yyjson_mut_val *val,
  1845. const char *str);
  1846. /** Returns whether the JSON value is equals to a string.
  1847. The `str` should be a UTF-8 string, null-terminator is not required.
  1848. Returns false if input is NULL or type is not string. */
  1849. yyjson_api_inline bool yyjson_mut_equals_strn(yyjson_mut_val *val,
  1850. const char *str, size_t len);
  1851. /** Returns whether two JSON values are equal (deep compare).
  1852. Returns false if input is NULL.
  1853. @note the result may be inaccurate if object has duplicate keys.
  1854. @warning This function is recursive and may cause a stack overflow
  1855. if the object level is too deep. */
  1856. yyjson_api_inline bool yyjson_mut_equals(yyjson_mut_val *lhs,
  1857. yyjson_mut_val *rhs);
  1858. /** Set the value to raw.
  1859. Returns false if input is NULL.
  1860. @warning This function should not be used on an existing object or array. */
  1861. yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val *val,
  1862. const char *raw, size_t len);
  1863. /** Set the value to null.
  1864. Returns false if input is NULL.
  1865. @warning This function should not be used on an existing object or array. */
  1866. yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val *val);
  1867. /** Set the value to bool.
  1868. Returns false if input is NULL.
  1869. @warning This function should not be used on an existing object or array. */
  1870. yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val *val, bool num);
  1871. /** Set the value to uint.
  1872. Returns false if input is NULL.
  1873. @warning This function should not be used on an existing object or array. */
  1874. yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val *val, uint64_t num);
  1875. /** Set the value to sint.
  1876. Returns false if input is NULL.
  1877. @warning This function should not be used on an existing object or array. */
  1878. yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num);
  1879. /** Set the value to int.
  1880. Returns false if input is NULL.
  1881. @warning This function should not be used on an existing object or array. */
  1882. yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int num);
  1883. /** Set the value to real.
  1884. Returns false if input is NULL.
  1885. @warning This function should not be used on an existing object or array. */
  1886. yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val *val, double num);
  1887. /** Set the value to string (null-terminated).
  1888. Returns false if input is NULL.
  1889. @warning This function should not be used on an existing object or array. */
  1890. yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val *val, const char *str);
  1891. /** Set the value to string (with length).
  1892. Returns false if input is NULL.
  1893. @warning This function should not be used on an existing object or array. */
  1894. yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val *val,
  1895. const char *str, size_t len);
  1896. /** Set the value to array.
  1897. Returns false if input is NULL.
  1898. @warning This function should not be used on an existing object or array. */
  1899. yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val *val);
  1900. /** Set the value to array.
  1901. Returns false if input is NULL.
  1902. @warning This function should not be used on an existing object or array. */
  1903. yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val);
  1904. /*==============================================================================
  1905. * Mutable JSON Value Creation API
  1906. *============================================================================*/
  1907. /** Creates and returns a raw value, returns NULL on error.
  1908. The `str` should be a null-terminated UTF-8 string.
  1909. @warning The input string is not copied, you should keep this string
  1910. unmodified for the lifetime of this JSON document. */
  1911. yyjson_api_inline yyjson_mut_val *yyjson_mut_raw(yyjson_mut_doc *doc,
  1912. const char *str);
  1913. /** Creates and returns a raw value, returns NULL on error.
  1914. The `str` should be a UTF-8 string, null-terminator is not required.
  1915. @warning The input string is not copied, you should keep this string
  1916. unmodified for the lifetime of this JSON document. */
  1917. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawn(yyjson_mut_doc *doc,
  1918. const char *str,
  1919. size_t len);
  1920. /** Creates and returns a raw value, returns NULL on error.
  1921. The `str` should be a null-terminated UTF-8 string.
  1922. The input string is copied and held by the document. */
  1923. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawcpy(yyjson_mut_doc *doc,
  1924. const char *str);
  1925. /** Creates and returns a raw value, returns NULL on error.
  1926. The `str` should be a UTF-8 string, null-terminator is not required.
  1927. The input string is copied and held by the document. */
  1928. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawncpy(yyjson_mut_doc *doc,
  1929. const char *str,
  1930. size_t len);
  1931. /** Creates and returns a null value, returns NULL on error. */
  1932. yyjson_api_inline yyjson_mut_val *yyjson_mut_null(yyjson_mut_doc *doc);
  1933. /** Creates and returns a true value, returns NULL on error. */
  1934. yyjson_api_inline yyjson_mut_val *yyjson_mut_true(yyjson_mut_doc *doc);
  1935. /** Creates and returns a false value, returns NULL on error. */
  1936. yyjson_api_inline yyjson_mut_val *yyjson_mut_false(yyjson_mut_doc *doc);
  1937. /** Creates and returns a bool value, returns NULL on error. */
  1938. yyjson_api_inline yyjson_mut_val *yyjson_mut_bool(yyjson_mut_doc *doc,
  1939. bool val);
  1940. /** Creates and returns an unsigned integer value, returns NULL on error. */
  1941. yyjson_api_inline yyjson_mut_val *yyjson_mut_uint(yyjson_mut_doc *doc,
  1942. uint64_t num);
  1943. /** Creates and returns a signed integer value, returns NULL on error. */
  1944. yyjson_api_inline yyjson_mut_val *yyjson_mut_sint(yyjson_mut_doc *doc,
  1945. int64_t num);
  1946. /** Creates and returns a signed integer value, returns NULL on error. */
  1947. yyjson_api_inline yyjson_mut_val *yyjson_mut_int(yyjson_mut_doc *doc,
  1948. int64_t num);
  1949. /** Creates and returns an real number value, returns NULL on error. */
  1950. yyjson_api_inline yyjson_mut_val *yyjson_mut_real(yyjson_mut_doc *doc,
  1951. double num);
  1952. /** Creates and returns a string value, returns NULL on error.
  1953. The `str` should be a null-terminated UTF-8 string.
  1954. @warning The input string is not copied, you should keep this string
  1955. unmodified for the lifetime of this JSON document. */
  1956. yyjson_api_inline yyjson_mut_val *yyjson_mut_str(yyjson_mut_doc *doc,
  1957. const char *str);
  1958. /** Creates and returns a string value, returns NULL on error.
  1959. The `str` should be a UTF-8 string, null-terminator is not required.
  1960. @warning The input string is not copied, you should keep this string
  1961. unmodified for the lifetime of this JSON document. */
  1962. yyjson_api_inline yyjson_mut_val *yyjson_mut_strn(yyjson_mut_doc *doc,
  1963. const char *str,
  1964. size_t len);
  1965. /** Creates and returns a string value, returns NULL on error.
  1966. The `str` should be a null-terminated UTF-8 string.
  1967. The input string is copied and held by the document. */
  1968. yyjson_api_inline yyjson_mut_val *yyjson_mut_strcpy(yyjson_mut_doc *doc,
  1969. const char *str);
  1970. /** Creates and returns a string value, returns NULL on error.
  1971. The `str` should be a UTF-8 string, null-terminator is not required.
  1972. The input string is copied and held by the document. */
  1973. yyjson_api_inline yyjson_mut_val *yyjson_mut_strncpy(yyjson_mut_doc *doc,
  1974. const char *str,
  1975. size_t len);
  1976. /*==============================================================================
  1977. * Mutable JSON Array API
  1978. *============================================================================*/
  1979. /** Returns the number of elements in this array.
  1980. Returns 0 if `arr` is NULL or type is not array. */
  1981. yyjson_api_inline size_t yyjson_mut_arr_size(yyjson_mut_val *arr);
  1982. /** Returns the element at the specified position in this array.
  1983. Returns NULL if array is NULL/empty or the index is out of bounds.
  1984. @warning This function takes a linear search time. */
  1985. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get(yyjson_mut_val *arr,
  1986. size_t idx);
  1987. /** Returns the first element of this array.
  1988. Returns NULL if `arr` is NULL/empty or type is not array. */
  1989. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_first(yyjson_mut_val *arr);
  1990. /** Returns the last element of this array.
  1991. Returns NULL if `arr` is NULL/empty or type is not array. */
  1992. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_last(yyjson_mut_val *arr);
  1993. /*==============================================================================
  1994. * Mutable JSON Array Iterator API
  1995. *============================================================================*/
  1996. /**
  1997. A mutable JSON array iterator.
  1998. @warning You should not modify the array while iterating over it, but you can
  1999. use `yyjson_mut_arr_iter_remove()` to remove current value.
  2000. @par Example
  2001. @code
  2002. yyjson_mut_val *val;
  2003. yyjson_mut_arr_iter iter = yyjson_mut_arr_iter_with(arr);
  2004. while ((val = yyjson_mut_arr_iter_next(&iter))) {
  2005. your_func(val);
  2006. if (your_val_is_unused(val)) {
  2007. yyjson_mut_arr_iter_remove(&iter);
  2008. }
  2009. }
  2010. @endcode
  2011. */
  2012. typedef struct yyjson_mut_arr_iter {
  2013. size_t idx; /**< next value's index */
  2014. size_t max; /**< maximum index (arr.size) */
  2015. yyjson_mut_val *cur; /**< current value */
  2016. yyjson_mut_val *pre; /**< previous value */
  2017. yyjson_mut_val *arr; /**< the array being iterated */
  2018. } yyjson_mut_arr_iter;
  2019. /**
  2020. Initialize an iterator for this array.
  2021. @param arr The array to be iterated over.
  2022. If this parameter is NULL or not an array, `iter` will be set to empty.
  2023. @param iter The iterator to be initialized.
  2024. If this parameter is NULL, the function will fail and return false.
  2025. @return true if the `iter` has been successfully initialized.
  2026. @note The iterator does not need to be destroyed.
  2027. */
  2028. yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val *arr,
  2029. yyjson_mut_arr_iter *iter);
  2030. /**
  2031. Create an iterator with an array , same as `yyjson_mut_arr_iter_init()`.
  2032. @param arr The array to be iterated over.
  2033. If this parameter is NULL or not an array, an empty iterator will returned.
  2034. @return A new iterator for the array.
  2035. @note The iterator does not need to be destroyed.
  2036. */
  2037. yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(
  2038. yyjson_mut_val *arr);
  2039. /**
  2040. Returns whether the iteration has more elements.
  2041. If `iter` is NULL, this function will return false.
  2042. */
  2043. yyjson_api_inline bool yyjson_mut_arr_iter_has_next(
  2044. yyjson_mut_arr_iter *iter);
  2045. /**
  2046. Returns the next element in the iteration, or NULL on end.
  2047. If `iter` is NULL, this function will return NULL.
  2048. */
  2049. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_next(
  2050. yyjson_mut_arr_iter *iter);
  2051. /**
  2052. Removes and returns current element in the iteration.
  2053. If `iter` is NULL, this function will return NULL.
  2054. */
  2055. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_remove(
  2056. yyjson_mut_arr_iter *iter);
  2057. /**
  2058. Macro for iterating over an array.
  2059. It works like iterator, but with a more intuitive API.
  2060. @warning You should not modify the array while iterating over it.
  2061. @par Example
  2062. @code
  2063. size_t idx, max;
  2064. yyjson_mut_val *val;
  2065. yyjson_mut_arr_foreach(arr, idx, max, val) {
  2066. your_func(idx, val);
  2067. }
  2068. @endcode
  2069. */
  2070. #define yyjson_mut_arr_foreach(arr, idx, max, val) \
  2071. for ((idx) = 0, \
  2072. (max) = yyjson_mut_arr_size(arr), \
  2073. (val) = yyjson_mut_arr_get_first(arr); \
  2074. (idx) < (max); \
  2075. (idx)++, \
  2076. (val) = (val)->next)
  2077. /*==============================================================================
  2078. * Mutable JSON Array Creation API
  2079. *============================================================================*/
  2080. /**
  2081. Creates and returns an empty mutable array.
  2082. @param doc A mutable document, used for memory allocation only.
  2083. @return The new array. NULL if input is NULL or memory allocation failed.
  2084. */
  2085. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc);
  2086. /**
  2087. Creates and returns a new mutable array with the given boolean values.
  2088. @param doc A mutable document, used for memory allocation only.
  2089. If this parameter is NULL, the function will fail and return NULL.
  2090. @param vals A C array of boolean values.
  2091. @param count The value count. If this value is 0, an empty array will return.
  2092. @return The new array. NULL if input is invalid or memory allocation failed.
  2093. @par Example
  2094. @code
  2095. const bool vals[3] = { true, false, true };
  2096. yyjson_mut_val *arr = yyjson_mut_arr_with_bool(doc, vals, 3);
  2097. @endcode
  2098. */
  2099. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_bool(
  2100. yyjson_mut_doc *doc, const bool *vals, size_t count);
  2101. /**
  2102. Creates and returns a new mutable array with the given sint numbers.
  2103. @param doc A mutable document, used for memory allocation only.
  2104. If this parameter is NULL, the function will fail and return NULL.
  2105. @param vals A C array of sint numbers.
  2106. @param count The number count. If this value is 0, an empty array will return.
  2107. @return The new array. NULL if input is invalid or memory allocation failed.
  2108. @par Example
  2109. @code
  2110. const int64_t vals[3] = { -1, 0, 1 };
  2111. yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, vals, 3);
  2112. @endcode
  2113. */
  2114. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint(
  2115. yyjson_mut_doc *doc, const int64_t *vals, size_t count);
  2116. /**
  2117. Creates and returns a new mutable array with the given uint numbers.
  2118. @param doc A mutable document, used for memory allocation only.
  2119. If this parameter is NULL, the function will fail and return NULL.
  2120. @param vals A C array of uint numbers.
  2121. @param count The number count. If this value is 0, an empty array will return.
  2122. @return The new array. NULL if input is invalid or memory allocation failed.
  2123. @par Example
  2124. @code
  2125. const uint64_t vals[3] = { 0, 1, 0 };
  2126. yyjson_mut_val *arr = yyjson_mut_arr_with_uint(doc, vals, 3);
  2127. @endcode
  2128. */
  2129. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint(
  2130. yyjson_mut_doc *doc, const uint64_t *vals, size_t count);
  2131. /**
  2132. Creates and returns a new mutable array with the given real numbers.
  2133. @param doc A mutable document, used for memory allocation only.
  2134. If this parameter is NULL, the function will fail and return NULL.
  2135. @param vals A C array of real numbers.
  2136. @param count The number count. If this value is 0, an empty array will return.
  2137. @return The new array. NULL if input is invalid or memory allocation failed.
  2138. @par Example
  2139. @code
  2140. const double vals[3] = { 0.1, 0.2, 0.3 };
  2141. yyjson_mut_val *arr = yyjson_mut_arr_with_real(doc, vals, 3);
  2142. @endcode
  2143. */
  2144. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_real(
  2145. yyjson_mut_doc *doc, const double *vals, size_t count);
  2146. /**
  2147. Creates and returns a new mutable array with the given int8 numbers.
  2148. @param doc A mutable document, used for memory allocation only.
  2149. If this parameter is NULL, the function will fail and return NULL.
  2150. @param vals A C array of int8 numbers.
  2151. @param count The number count. If this value is 0, an empty array will return.
  2152. @return The new array. NULL if input is invalid or memory allocation failed.
  2153. @par Example
  2154. @code
  2155. const int8_t vals[3] = { -1, 0, 1 };
  2156. yyjson_mut_val *arr = yyjson_mut_arr_with_sint8(doc, vals, 3);
  2157. @endcode
  2158. */
  2159. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint8(
  2160. yyjson_mut_doc *doc, const int8_t *vals, size_t count);
  2161. /**
  2162. Creates and returns a new mutable array with the given int16 numbers.
  2163. @param doc A mutable document, used for memory allocation only.
  2164. If this parameter is NULL, the function will fail and return NULL.
  2165. @param vals A C array of int16 numbers.
  2166. @param count The number count. If this value is 0, an empty array will return.
  2167. @return The new array. NULL if input is invalid or memory allocation failed.
  2168. @par Example
  2169. @code
  2170. const int16_t vals[3] = { -1, 0, 1 };
  2171. yyjson_mut_val *arr = yyjson_mut_arr_with_sint16(doc, vals, 3);
  2172. @endcode
  2173. */
  2174. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint16(
  2175. yyjson_mut_doc *doc, const int16_t *vals, size_t count);
  2176. /**
  2177. Creates and returns a new mutable array with the given int32 numbers.
  2178. @param doc A mutable document, used for memory allocation only.
  2179. If this parameter is NULL, the function will fail and return NULL.
  2180. @param vals A C array of int32 numbers.
  2181. @param count The number count. If this value is 0, an empty array will return.
  2182. @return The new array. NULL if input is invalid or memory allocation failed.
  2183. @par Example
  2184. @code
  2185. const int32_t vals[3] = { -1, 0, 1 };
  2186. yyjson_mut_val *arr = yyjson_mut_arr_with_sint32(doc, vals, 3);
  2187. @endcode
  2188. */
  2189. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint32(
  2190. yyjson_mut_doc *doc, const int32_t *vals, size_t count);
  2191. /**
  2192. Creates and returns a new mutable array with the given int64 numbers.
  2193. @param doc A mutable document, used for memory allocation only.
  2194. If this parameter is NULL, the function will fail and return NULL.
  2195. @param vals A C array of int64 numbers.
  2196. @param count The number count. If this value is 0, an empty array will return.
  2197. @return The new array. NULL if input is invalid or memory allocation failed.
  2198. @par Example
  2199. @code
  2200. const int64_t vals[3] = { -1, 0, 1 };
  2201. yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, vals, 3);
  2202. @endcode
  2203. */
  2204. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint64(
  2205. yyjson_mut_doc *doc, const int64_t *vals, size_t count);
  2206. /**
  2207. Creates and returns a new mutable array with the given uint8 numbers.
  2208. @param doc A mutable document, used for memory allocation only.
  2209. If this parameter is NULL, the function will fail and return NULL.
  2210. @param vals A C array of uint8 numbers.
  2211. @param count The number count. If this value is 0, an empty array will return.
  2212. @return The new array. NULL if input is invalid or memory allocation failed.
  2213. @par Example
  2214. @code
  2215. const uint8_t vals[3] = { 0, 1, 0 };
  2216. yyjson_mut_val *arr = yyjson_mut_arr_with_uint8(doc, vals, 3);
  2217. @endcode
  2218. */
  2219. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint8(
  2220. yyjson_mut_doc *doc, const uint8_t *vals, size_t count);
  2221. /**
  2222. Creates and returns a new mutable array with the given uint16 numbers.
  2223. @param doc A mutable document, used for memory allocation only.
  2224. If this parameter is NULL, the function will fail and return NULL.
  2225. @param vals A C array of uint16 numbers.
  2226. @param count The number count. If this value is 0, an empty array will return.
  2227. @return The new array. NULL if input is invalid or memory allocation failed.
  2228. @par Example
  2229. @code
  2230. const uint16_t vals[3] = { 0, 1, 0 };
  2231. yyjson_mut_val *arr = yyjson_mut_arr_with_uint16(doc, vals, 3);
  2232. @endcode
  2233. */
  2234. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint16(
  2235. yyjson_mut_doc *doc, const uint16_t *vals, size_t count);
  2236. /**
  2237. Creates and returns a new mutable array with the given uint32 numbers.
  2238. @param doc A mutable document, used for memory allocation only.
  2239. If this parameter is NULL, the function will fail and return NULL.
  2240. @param vals A C array of uint32 numbers.
  2241. @param count The number count. If this value is 0, an empty array will return.
  2242. @return The new array. NULL if input is invalid or memory allocation failed.
  2243. @par Example
  2244. @code
  2245. const uint32_t vals[3] = { 0, 1, 0 };
  2246. yyjson_mut_val *arr = yyjson_mut_arr_with_uint32(doc, vals, 3);
  2247. @endcode
  2248. */
  2249. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint32(
  2250. yyjson_mut_doc *doc, const uint32_t *vals, size_t count);
  2251. /**
  2252. Creates and returns a new mutable array with the given uint64 numbers.
  2253. @param doc A mutable document, used for memory allocation only.
  2254. If this parameter is NULL, the function will fail and return NULL.
  2255. @param vals A C array of uint64 numbers.
  2256. @param count The number count. If this value is 0, an empty array will return.
  2257. @return The new array. NULL if input is invalid or memory allocation failed.
  2258. @par Example
  2259. @code
  2260. const uint64_t vals[3] = { 0, 1, 0 };
  2261. yyjson_mut_val *arr = yyjson_mut_arr_with_uint64(doc, vals, 3);
  2262. @endcode
  2263. */
  2264. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint64(
  2265. yyjson_mut_doc *doc, const uint64_t *vals, size_t count);
  2266. /**
  2267. Creates and returns a new mutable array with the given float numbers.
  2268. @param doc A mutable document, used for memory allocation only.
  2269. If this parameter is NULL, the function will fail and return NULL.
  2270. @param vals A C array of float numbers.
  2271. @param count The number count. If this value is 0, an empty array will return.
  2272. @return The new array. NULL if input is invalid or memory allocation failed.
  2273. @par Example
  2274. @code
  2275. const float vals[3] = { -1.0f, 0.0f, 1.0f };
  2276. yyjson_mut_val *arr = yyjson_mut_arr_with_float(doc, vals, 3);
  2277. @endcode
  2278. */
  2279. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_float(
  2280. yyjson_mut_doc *doc, const float *vals, size_t count);
  2281. /**
  2282. Creates and returns a new mutable array with the given double numbers.
  2283. @param doc A mutable document, used for memory allocation only.
  2284. If this parameter is NULL, the function will fail and return NULL.
  2285. @param vals A C array of double numbers.
  2286. @param count The number count. If this value is 0, an empty array will return.
  2287. @return The new array. NULL if input is invalid or memory allocation failed.
  2288. @par Example
  2289. @code
  2290. const double vals[3] = { -1.0, 0.0, 1.0 };
  2291. yyjson_mut_val *arr = yyjson_mut_arr_with_double(doc, vals, 3);
  2292. @endcode
  2293. */
  2294. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_double(
  2295. yyjson_mut_doc *doc, const double *vals, size_t count);
  2296. /**
  2297. Creates and returns a new mutable array with the given strings, these strings
  2298. will not be copied.
  2299. @param doc A mutable document, used for memory allocation only.
  2300. If this parameter is NULL, the function will fail and return NULL.
  2301. @param vals A C array of UTF-8 null-terminator strings.
  2302. If this array contains NULL, the function will fail and return NULL.
  2303. @param count The number of values in `vals`.
  2304. If this value is 0, an empty array will return.
  2305. @return The new array. NULL if input is invalid or memory allocation failed.
  2306. @warning The input strings are not copied, you should keep these strings
  2307. unmodified for the lifetime of this JSON document. If these strings will be
  2308. modified, you should use `yyjson_mut_arr_with_strcpy()` instead.
  2309. @par Example
  2310. @code
  2311. const char *vals[3] = { "a", "b", "c" };
  2312. yyjson_mut_val *arr = yyjson_mut_arr_with_str(doc, vals, 3);
  2313. @endcode
  2314. */
  2315. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_str(
  2316. yyjson_mut_doc *doc, const char **vals, size_t count);
  2317. /**
  2318. Creates and returns a new mutable array with the given strings and string
  2319. lengths, these strings will not be copied.
  2320. @param doc A mutable document, used for memory allocation only.
  2321. If this parameter is NULL, the function will fail and return NULL.
  2322. @param vals A C array of UTF-8 strings, null-terminator is not required.
  2323. If this array contains NULL, the function will fail and return NULL.
  2324. @param lens A C array of string lengths, in bytes.
  2325. @param count The number of strings in `vals`.
  2326. If this value is 0, an empty array will return.
  2327. @return The new array. NULL if input is invalid or memory allocation failed.
  2328. @warning The input strings are not copied, you should keep these strings
  2329. unmodified for the lifetime of this JSON document. If these strings will be
  2330. modified, you should use `yyjson_mut_arr_with_strncpy()` instead.
  2331. @par Example
  2332. @code
  2333. const char *vals[3] = { "a", "bb", "c" };
  2334. const size_t lens[3] = { 1, 2, 1 };
  2335. yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, vals, lens, 3);
  2336. @endcode
  2337. */
  2338. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strn(
  2339. yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count);
  2340. /**
  2341. Creates and returns a new mutable array with the given strings, these strings
  2342. will be copied.
  2343. @param doc A mutable document, used for memory allocation only.
  2344. If this parameter is NULL, the function will fail and return NULL.
  2345. @param vals A C array of UTF-8 null-terminator strings.
  2346. If this array contains NULL, the function will fail and return NULL.
  2347. @param count The number of values in `vals`.
  2348. If this value is 0, an empty array will return.
  2349. @return The new array. NULL if input is invalid or memory allocation failed.
  2350. @par Example
  2351. @code
  2352. const char *vals[3] = { "a", "b", "c" };
  2353. yyjson_mut_val *arr = yyjson_mut_arr_with_strcpy(doc, vals, 3);
  2354. @endcode
  2355. */
  2356. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strcpy(
  2357. yyjson_mut_doc *doc, const char **vals, size_t count);
  2358. /**
  2359. Creates and returns a new mutable array with the given strings and string
  2360. lengths, these strings will be copied.
  2361. @param doc A mutable document, used for memory allocation only.
  2362. If this parameter is NULL, the function will fail and return NULL.
  2363. @param vals A C array of UTF-8 strings, null-terminator is not required.
  2364. If this array contains NULL, the function will fail and return NULL.
  2365. @param lens A C array of string lengths, in bytes.
  2366. @param count The number of strings in `vals`.
  2367. If this value is 0, an empty array will return.
  2368. @return The new array. NULL if input is invalid or memory allocation failed.
  2369. @par Example
  2370. @code
  2371. const char *vals[3] = { "a", "bb", "c" };
  2372. const size_t lens[3] = { 1, 2, 1 };
  2373. yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, vals, lens, 3);
  2374. @endcode
  2375. */
  2376. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strncpy(
  2377. yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count);
  2378. /*==============================================================================
  2379. * Mutable JSON Array Modification API
  2380. *============================================================================*/
  2381. /**
  2382. Inserts a value into an array at a given index.
  2383. @param arr The array to which the value is to be inserted.
  2384. Returns false if it is NULL or not an array.
  2385. @param val The value to be inserted. Returns false if it is NULL.
  2386. @param idx The index to which to insert the new value.
  2387. Returns false if the index is out of range.
  2388. @return Whether successful.
  2389. @warning This function takes a linear search time.
  2390. */
  2391. yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val *arr,
  2392. yyjson_mut_val *val, size_t idx);
  2393. /**
  2394. Inserts a value at the end of the array.
  2395. @param arr The array to which the value is to be inserted.
  2396. Returns false if it is NULL or not an array.
  2397. @param val The value to be inserted. Returns false if it is NULL.
  2398. @return Whether successful.
  2399. */
  2400. yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val *arr,
  2401. yyjson_mut_val *val);
  2402. /**
  2403. Inserts a value at the head of the array.
  2404. @param arr The array to which the value is to be inserted.
  2405. Returns false if it is NULL or not an array.
  2406. @param val The value to be inserted. Returns false if it is NULL.
  2407. @return Whether successful.
  2408. */
  2409. yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val *arr,
  2410. yyjson_mut_val *val);
  2411. /**
  2412. Replaces a value at index and returns old value.
  2413. @param arr The array to which the value is to be replaced.
  2414. Returns false if it is NULL or not an array.
  2415. @param idx The index to which to replace the value.
  2416. Returns false if the index is out of range.
  2417. @param val The new value to replace. Returns false if it is NULL.
  2418. @return Old value, or NULL on error.
  2419. @warning This function takes a linear search time.
  2420. */
  2421. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_replace(yyjson_mut_val *arr,
  2422. size_t idx,
  2423. yyjson_mut_val *val);
  2424. /**
  2425. Removes and returns a value at index.
  2426. @param arr The array from which the value is to be removed.
  2427. Returns false if it is NULL or not an array.
  2428. @param idx The index from which to remove the value.
  2429. Returns false if the index is out of range.
  2430. @return Old value, or NULL on error.
  2431. @warning This function takes a linear search time.
  2432. */
  2433. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove(yyjson_mut_val *arr,
  2434. size_t idx);
  2435. /**
  2436. Removes and returns the first value in this array.
  2437. @param arr The array from which the value is to be removed.
  2438. Returns false if it is NULL or not an array.
  2439. @return The first value, or NULL on error.
  2440. */
  2441. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_first(
  2442. yyjson_mut_val *arr);
  2443. /**
  2444. Removes and returns the last value in this array.
  2445. @param arr The array from which the value is to be removed.
  2446. Returns false if it is NULL or not an array.
  2447. @return The last value, or NULL on error.
  2448. */
  2449. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_last(
  2450. yyjson_mut_val *arr);
  2451. /**
  2452. Removes all values within a specified range in the array.
  2453. @param arr The array from which the value is to be removed.
  2454. Returns false if it is NULL or not an array.
  2455. @param idx The start index of the range (0 is the first).
  2456. @param len The number of items in the range (can be 0).
  2457. @return Whether successful.
  2458. @warning This function takes a linear search time.
  2459. */
  2460. yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val *arr,
  2461. size_t idx, size_t len);
  2462. /**
  2463. Removes all values in this array.
  2464. @param arr The array from which all of the values are to be removed.
  2465. Returns false if it is NULL or not an array.
  2466. @return Whether successful.
  2467. */
  2468. yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val *arr);
  2469. /**
  2470. Rotates values in this array for the given number of times.
  2471. For example: `[1,2,3,4,5]` rotate 2 is `[3,4,5,1,2]`.
  2472. @param arr The array to be rotated.
  2473. @param idx Index (or times) to rotate.
  2474. @warning This function takes a linear search time.
  2475. */
  2476. yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr,
  2477. size_t idx);
  2478. /*==============================================================================
  2479. * Mutable JSON Array Modification Convenience API
  2480. *============================================================================*/
  2481. /**
  2482. Adds a value at the end of the array.
  2483. @param arr The array to which the value is to be inserted.
  2484. Returns false if it is NULL or not an array.
  2485. @param val The value to be inserted. Returns false if it is NULL.
  2486. @return Whether successful.
  2487. */
  2488. yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val *arr,
  2489. yyjson_mut_val *val);
  2490. /**
  2491. Adds a `null` value at the end of the array.
  2492. @param doc The `doc` is only used for memory allocation.
  2493. @param arr The array to which the value is to be inserted.
  2494. Returns false if it is NULL or not an array.
  2495. @return Whether successful.
  2496. */
  2497. yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc *doc,
  2498. yyjson_mut_val *arr);
  2499. /**
  2500. Adds a `true` value at the end of the array.
  2501. @param doc The `doc` is only used for memory allocation.
  2502. @param arr The array to which the value is to be inserted.
  2503. Returns false if it is NULL or not an array.
  2504. @return Whether successful.
  2505. */
  2506. yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc *doc,
  2507. yyjson_mut_val *arr);
  2508. /**
  2509. Adds a `false` value at the end of the array.
  2510. @param doc The `doc` is only used for memory allocation.
  2511. @param arr The array to which the value is to be inserted.
  2512. Returns false if it is NULL or not an array.
  2513. @return Whether successful.
  2514. */
  2515. yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc *doc,
  2516. yyjson_mut_val *arr);
  2517. /**
  2518. Adds a bool value at the end of the array.
  2519. @param doc The `doc` is only used for memory allocation.
  2520. @param arr The array to which the value is to be inserted.
  2521. Returns false if it is NULL or not an array.
  2522. @param val The bool value to be added.
  2523. @return Whether successful.
  2524. */
  2525. yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc *doc,
  2526. yyjson_mut_val *arr,
  2527. bool val);
  2528. /**
  2529. Adds an unsigned integer value at the end of the array.
  2530. @param doc The `doc` is only used for memory allocation.
  2531. @param arr The array to which the value is to be inserted.
  2532. Returns false if it is NULL or not an array.
  2533. @param num The number to be added.
  2534. @return Whether successful.
  2535. */
  2536. yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc *doc,
  2537. yyjson_mut_val *arr,
  2538. uint64_t num);
  2539. /**
  2540. Adds a signed integer value at the end of the array.
  2541. @param doc The `doc` is only used for memory allocation.
  2542. @param arr The array to which the value is to be inserted.
  2543. Returns false if it is NULL or not an array.
  2544. @param num The number to be added.
  2545. @return Whether successful.
  2546. */
  2547. yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc *doc,
  2548. yyjson_mut_val *arr,
  2549. int64_t num);
  2550. /**
  2551. Adds a integer value at the end of the array.
  2552. @param doc The `doc` is only used for memory allocation.
  2553. @param arr The array to which the value is to be inserted.
  2554. Returns false if it is NULL or not an array.
  2555. @param num The number to be added.
  2556. @return Whether successful.
  2557. */
  2558. yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc *doc,
  2559. yyjson_mut_val *arr,
  2560. int64_t num);
  2561. /**
  2562. Adds a double value at the end of the array.
  2563. @param doc The `doc` is only used for memory allocation.
  2564. @param arr The array to which the value is to be inserted.
  2565. Returns false if it is NULL or not an array.
  2566. @param num The number to be added.
  2567. @return Whether successful.
  2568. */
  2569. yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc *doc,
  2570. yyjson_mut_val *arr,
  2571. double num);
  2572. /**
  2573. Adds a string value at the end of the array (no copy).
  2574. @param doc The `doc` is only used for memory allocation.
  2575. @param arr The array to which the value is to be inserted.
  2576. Returns false if it is NULL or not an array.
  2577. @param str A null-terminated UTF-8 string.
  2578. @return Whether successful.
  2579. @warning The input string is not copied, you should keep this string unmodified
  2580. for the lifetime of this JSON document.
  2581. */
  2582. yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc *doc,
  2583. yyjson_mut_val *arr,
  2584. const char *str);
  2585. /**
  2586. Adds a string value at the end of the array (no copy).
  2587. @param doc The `doc` is only used for memory allocation.
  2588. @param arr The array to which the value is to be inserted.
  2589. Returns false if it is NULL or not an array.
  2590. @param str A UTF-8 string, null-terminator is not required.
  2591. @param len The length of the string, in bytes.
  2592. @return Whether successful.
  2593. @warning The input string is not copied, you should keep this string unmodified
  2594. for the lifetime of this JSON document.
  2595. */
  2596. yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc *doc,
  2597. yyjson_mut_val *arr,
  2598. const char *str,
  2599. size_t len);
  2600. /**
  2601. Adds a string value at the end of the array (copied).
  2602. @param doc The `doc` is only used for memory allocation.
  2603. @param arr The array to which the value is to be inserted.
  2604. Returns false if it is NULL or not an array.
  2605. @param str A null-terminated UTF-8 string.
  2606. @return Whether successful.
  2607. */
  2608. yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc *doc,
  2609. yyjson_mut_val *arr,
  2610. const char *str);
  2611. /**
  2612. Adds a string value at the end of the array (copied).
  2613. @param doc The `doc` is only used for memory allocation.
  2614. @param arr The array to which the value is to be inserted.
  2615. Returns false if it is NULL or not an array.
  2616. @param str A UTF-8 string, null-terminator is not required.
  2617. @param len The length of the string, in bytes.
  2618. @return Whether successful.
  2619. */
  2620. yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc *doc,
  2621. yyjson_mut_val *arr,
  2622. const char *str,
  2623. size_t len);
  2624. /**
  2625. Creates and adds a new array at the end of the array.
  2626. @param doc The `doc` is only used for memory allocation.
  2627. @param arr The array to which the value is to be inserted.
  2628. Returns false if it is NULL or not an array.
  2629. @return The new array, or NULL on error.
  2630. */
  2631. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_arr(yyjson_mut_doc *doc,
  2632. yyjson_mut_val *arr);
  2633. /**
  2634. Creates and adds a new object at the end of the array.
  2635. @param doc The `doc` is only used for memory allocation.
  2636. @param arr The array to which the value is to be inserted.
  2637. Returns false if it is NULL or not an array.
  2638. @return The new object, or NULL on error.
  2639. */
  2640. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_obj(yyjson_mut_doc *doc,
  2641. yyjson_mut_val *arr);
  2642. /*==============================================================================
  2643. * Mutable JSON Object API
  2644. *============================================================================*/
  2645. /** Returns the number of key-value pairs in this object.
  2646. Returns 0 if `obj` is NULL or type is not object. */
  2647. yyjson_api_inline size_t yyjson_mut_obj_size(yyjson_mut_val *obj);
  2648. /** Returns the value to which the specified key is mapped.
  2649. Returns NULL if this object contains no mapping for the key.
  2650. Returns NULL if `obj/key` is NULL, or type is not object.
  2651. The `key` should be a null-terminated UTF-8 string.
  2652. @warning This function takes a linear search time. */
  2653. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_get(yyjson_mut_val *obj,
  2654. const char *key);
  2655. /** Returns the value to which the specified key is mapped.
  2656. Returns NULL if this object contains no mapping for the key.
  2657. Returns NULL if `obj/key` is NULL, or type is not object.
  2658. The `key` should be a UTF-8 string, null-terminator is not required.
  2659. The `key_len` should be the length of the key, in bytes.
  2660. @warning This function takes a linear search time. */
  2661. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_getn(yyjson_mut_val *obj,
  2662. const char *key,
  2663. size_t key_len);
  2664. /*==============================================================================
  2665. * Mutable JSON Object Iterator API
  2666. *============================================================================*/
  2667. /**
  2668. A mutable JSON object iterator.
  2669. @warning You should not modify the object while iterating over it, but you can
  2670. use `yyjson_mut_obj_iter_remove()` to remove current value.
  2671. @par Example
  2672. @code
  2673. yyjson_mut_val *key, *val;
  2674. yyjson_mut_obj_iter iter = yyjson_mut_obj_iter_with(obj);
  2675. while ((key = yyjson_mut_obj_iter_next(&iter))) {
  2676. val = yyjson_mut_obj_iter_get_val(key);
  2677. your_func(key, val);
  2678. if (your_val_is_unused(key, val)) {
  2679. yyjson_mut_obj_iter_remove(&iter);
  2680. }
  2681. }
  2682. @endcode
  2683. If the ordering of the keys is known at compile-time, you can use this method
  2684. to speed up value lookups:
  2685. @code
  2686. // {"k1":1, "k2": 3, "k3": 3}
  2687. yyjson_mut_val *key, *val;
  2688. yyjson_mut_obj_iter iter = yyjson_mut_obj_iter_with(obj);
  2689. yyjson_mut_val *v1 = yyjson_mut_obj_iter_get(&iter, "k1");
  2690. yyjson_mut_val *v3 = yyjson_mut_obj_iter_get(&iter, "k3");
  2691. @endcode
  2692. @see `yyjson_mut_obj_iter_get()` and `yyjson_mut_obj_iter_getn()`
  2693. */
  2694. typedef struct yyjson_mut_obj_iter {
  2695. size_t idx; /**< next key's index */
  2696. size_t max; /**< maximum key index (obj.size) */
  2697. yyjson_mut_val *cur; /**< current key */
  2698. yyjson_mut_val *pre; /**< previous key */
  2699. yyjson_mut_val *obj; /**< the object being iterated */
  2700. } yyjson_mut_obj_iter;
  2701. /**
  2702. Initialize an iterator for this object.
  2703. @param obj The object to be iterated over.
  2704. If this parameter is NULL or not an array, `iter` will be set to empty.
  2705. @param iter The iterator to be initialized.
  2706. If this parameter is NULL, the function will fail and return false.
  2707. @return true if the `iter` has been successfully initialized.
  2708. @note The iterator does not need to be destroyed.
  2709. */
  2710. yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj,
  2711. yyjson_mut_obj_iter *iter);
  2712. /**
  2713. Create an iterator with an object, same as `yyjson_obj_iter_init()`.
  2714. @param obj The object to be iterated over.
  2715. If this parameter is NULL or not an object, an empty iterator will returned.
  2716. @return A new iterator for the object.
  2717. @note The iterator does not need to be destroyed.
  2718. */
  2719. yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(
  2720. yyjson_mut_val *obj);
  2721. /**
  2722. Returns whether the iteration has more elements.
  2723. If `iter` is NULL, this function will return false.
  2724. */
  2725. yyjson_api_inline bool yyjson_mut_obj_iter_has_next(
  2726. yyjson_mut_obj_iter *iter);
  2727. /**
  2728. Returns the next key in the iteration, or NULL on end.
  2729. If `iter` is NULL, this function will return NULL.
  2730. */
  2731. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_next(
  2732. yyjson_mut_obj_iter *iter);
  2733. /**
  2734. Returns the value for key inside the iteration.
  2735. If `iter` is NULL, this function will return NULL.
  2736. */
  2737. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get_val(
  2738. yyjson_mut_val *key);
  2739. /**
  2740. Removes current key-value pair in the iteration, returns the removed value.
  2741. If `iter` is NULL, this function will return NULL.
  2742. */
  2743. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_remove(
  2744. yyjson_mut_obj_iter *iter);
  2745. /**
  2746. Iterates to a specified key and returns the value.
  2747. This function does the same thing as `yyjson_mut_obj_get()`, but is much faster
  2748. if the ordering of the keys is known at compile-time and you are using the same
  2749. order to look up the values. If the key exists in this object, then the
  2750. iterator will stop at the next key, otherwise the iterator will not change and
  2751. NULL is returned.
  2752. @param iter The object iterator, should not be NULL.
  2753. @param key The key, should be a UTF-8 string with null-terminator.
  2754. @return The value to which the specified key is mapped.
  2755. NULL if this object contains no mapping for the key or input is invalid.
  2756. @warning This function takes a linear search time if the key is not nearby.
  2757. */
  2758. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get(
  2759. yyjson_mut_obj_iter *iter, const char *key);
  2760. /**
  2761. Iterates to a specified key and returns the value.
  2762. This function does the same thing as `yyjson_mut_obj_getn()` but is much faster
  2763. if the ordering of the keys is known at compile-time and you are using the same
  2764. order to look up the values. If the key exists in this object, then the
  2765. iterator will stop at the next key, otherwise the iterator will not change and
  2766. NULL is returned.
  2767. @param iter The object iterator, should not be NULL.
  2768. @param key The key, should be a UTF-8 string, null-terminator is not required.
  2769. @param key_len The the length of `key`, in bytes.
  2770. @return The value to which the specified key is mapped.
  2771. NULL if this object contains no mapping for the key or input is invalid.
  2772. @warning This function takes a linear search time if the key is not nearby.
  2773. */
  2774. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_getn(
  2775. yyjson_mut_obj_iter *iter, const char *key, size_t key_len);
  2776. /**
  2777. Macro for iterating over an object.
  2778. It works like iterator, but with a more intuitive API.
  2779. @warning You should not modify the object while iterating over it.
  2780. @par Example
  2781. @code
  2782. size_t idx, max;
  2783. yyjson_val *key, *val;
  2784. yyjson_obj_foreach(obj, idx, max, key, val) {
  2785. your_func(key, val);
  2786. }
  2787. @endcode
  2788. */
  2789. #define yyjson_mut_obj_foreach(obj, idx, max, key, val) \
  2790. for ((idx) = 0, \
  2791. (max) = yyjson_mut_obj_size(obj), \
  2792. (key) = (max) ? ((yyjson_mut_val *)(obj)->uni.ptr)->next->next : NULL, \
  2793. (val) = (key) ? (key)->next : NULL; \
  2794. (idx) < (max); \
  2795. (idx)++, \
  2796. (key) = (val)->next, \
  2797. (val) = (key)->next)
  2798. /*==============================================================================
  2799. * Mutable JSON Object Creation API
  2800. *============================================================================*/
  2801. /** Creates and returns a mutable object, returns NULL on error. */
  2802. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj(yyjson_mut_doc *doc);
  2803. /**
  2804. Creates and returns a mutable object with keys and values, returns NULL on
  2805. error. The keys and values are not copied. The strings should be a
  2806. null-terminated UTF-8 string.
  2807. @warning The input string is not copied, you should keep this string
  2808. unmodified for the lifetime of this JSON document.
  2809. @par Example
  2810. @code
  2811. const char *keys[2] = { "id", "name" };
  2812. const char *vals[2] = { "01", "Harry" };
  2813. yyjson_mut_val *obj = yyjson_mut_obj_with_str(doc, keys, vals, 2);
  2814. @endcode
  2815. */
  2816. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_str(yyjson_mut_doc *doc,
  2817. const char **keys,
  2818. const char **vals,
  2819. size_t count);
  2820. /**
  2821. Creates and returns a mutable object with key-value pairs and pair count,
  2822. returns NULL on error. The keys and values are not copied. The strings should
  2823. be a null-terminated UTF-8 string.
  2824. @warning The input string is not copied, you should keep this string
  2825. unmodified for the lifetime of this JSON document.
  2826. @par Example
  2827. @code
  2828. const char *kv_pairs[4] = { "id", "01", "name", "Harry" };
  2829. yyjson_mut_val *obj = yyjson_mut_obj_with_kv(doc, kv_pairs, 2);
  2830. @endcode
  2831. */
  2832. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_kv(yyjson_mut_doc *doc,
  2833. const char **kv_pairs,
  2834. size_t pair_count);
  2835. /*==============================================================================
  2836. * Mutable JSON Object Modification API
  2837. *============================================================================*/
  2838. /**
  2839. Adds a key-value pair at the end of the object.
  2840. This function allows duplicated key in one object.
  2841. @param obj The object to which the new key-value pair is to be added.
  2842. @param key The key, should be a string which is created by `yyjson_mut_str()`,
  2843. `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
  2844. @param val The value to add to the object.
  2845. @return Whether successful.
  2846. */
  2847. yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val *obj,
  2848. yyjson_mut_val *key,
  2849. yyjson_mut_val *val);
  2850. /**
  2851. Sets a key-value pair at the end of the object.
  2852. This function may remove all key-value pairs for the given key before add.
  2853. @param obj The object to which the new key-value pair is to be added.
  2854. @param key The key, should be a string which is created by `yyjson_mut_str()`,
  2855. `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
  2856. @param val The value to add to the object. If this value is null, the behavior
  2857. is same as `yyjson_mut_obj_remove()`.
  2858. @return Whether successful.
  2859. */
  2860. yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val *obj,
  2861. yyjson_mut_val *key,
  2862. yyjson_mut_val *val);
  2863. /**
  2864. Inserts a key-value pair to the object at the given position.
  2865. This function allows duplicated key in one object.
  2866. @param obj The object to which the new key-value pair is to be added.
  2867. @param key The key, should be a string which is created by `yyjson_mut_str()`,
  2868. `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
  2869. @param val The value to add to the object.
  2870. @param idx The index to which to insert the new pair.
  2871. @return Whether successful.
  2872. */
  2873. yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val *obj,
  2874. yyjson_mut_val *key,
  2875. yyjson_mut_val *val,
  2876. size_t idx);
  2877. /**
  2878. Removes all key-value pair from the object with given key.
  2879. @param obj The object from which the key-value pair is to be removed.
  2880. @param key The key, should be a string value.
  2881. @return The first matched value, or NULL if no matched value.
  2882. @warning This function takes a linear search time.
  2883. */
  2884. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove(yyjson_mut_val *obj,
  2885. yyjson_mut_val *key);
  2886. /**
  2887. Removes all key-value pair from the object with given key.
  2888. @param obj The object from which the key-value pair is to be removed.
  2889. @param key The key, should be a UTF-8 string with null-terminator.
  2890. @return The first matched value, or NULL if no matched value.
  2891. @warning This function takes a linear search time.
  2892. */
  2893. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_key(
  2894. yyjson_mut_val *obj, const char *key);
  2895. /**
  2896. Removes all key-value pair from the object with given key.
  2897. @param obj The object from which the key-value pair is to be removed.
  2898. @param key The key, should be a UTF-8 string, null-terminator is not required.
  2899. @param key_len The length of the key.
  2900. @return The first matched value, or NULL if no matched value.
  2901. @warning This function takes a linear search time.
  2902. */
  2903. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_keyn(
  2904. yyjson_mut_val *obj, const char *key, size_t key_len);
  2905. /**
  2906. Removes all key-value pairs in this object.
  2907. @param obj The object from which all of the values are to be removed.
  2908. @return Whether successful.
  2909. */
  2910. yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val *obj);
  2911. /**
  2912. Replaces value from the object with given key.
  2913. If the key is not exist, or the value is NULL, it will fail.
  2914. @param obj The object to which the value is to be replaced.
  2915. @param key The key, should be a string value.
  2916. @param val The value to replace into the object.
  2917. @return Whether successful.
  2918. @warning This function takes a linear search time.
  2919. */
  2920. yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val *obj,
  2921. yyjson_mut_val *key,
  2922. yyjson_mut_val *val);
  2923. /**
  2924. Rotates key-value pairs in the object for the given number of times.
  2925. For example: `{"a":1,"b":2,"c":3,"d":4}` rotate 1 is
  2926. `{"b":2,"c":3,"d":4,"a":1}`.
  2927. @param obj The object to be rotated.
  2928. @param idx Index (or times) to rotate.
  2929. @return Whether successful.
  2930. @warning This function takes a linear search time.
  2931. */
  2932. yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
  2933. size_t idx);
  2934. /*==============================================================================
  2935. * Mutable JSON Object Modification Convenience API
  2936. *============================================================================*/
  2937. /** Adds a `null` value at the end of the object.
  2938. The `key` should be a null-terminated UTF-8 string.
  2939. This function allows duplicated key in one object.
  2940. @warning The key string are not copied, you should keep the string
  2941. unmodified for the lifetime of this JSON document. */
  2942. yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc,
  2943. yyjson_mut_val *obj,
  2944. const char *key);
  2945. /** Adds a `true` value at the end of the object.
  2946. The `key` should be a null-terminated UTF-8 string.
  2947. This function allows duplicated key in one object.
  2948. @warning The key string are not copied, you should keep the string
  2949. unmodified for the lifetime of this JSON document. */
  2950. yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc,
  2951. yyjson_mut_val *obj,
  2952. const char *key);
  2953. /** Adds a `false` value at the end of the object.
  2954. The `key` should be a null-terminated UTF-8 string.
  2955. This function allows duplicated key in one object.
  2956. @warning The key string are not copied, you should keep the string
  2957. unmodified for the lifetime of this JSON document. */
  2958. yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc,
  2959. yyjson_mut_val *obj,
  2960. const char *key);
  2961. /** Adds a bool value at the end of the object.
  2962. The `key` should be a null-terminated UTF-8 string.
  2963. This function allows duplicated key in one object.
  2964. @warning The key string are not copied, you should keep the string
  2965. unmodified for the lifetime of this JSON document. */
  2966. yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
  2967. yyjson_mut_val *obj,
  2968. const char *key, bool val);
  2969. /** Adds an unsigned integer value at the end of the object.
  2970. The `key` should be a null-terminated UTF-8 string.
  2971. This function allows duplicated key in one object.
  2972. @warning The key string are not copied, you should keep the string
  2973. unmodified for the lifetime of this JSON document. */
  2974. yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc,
  2975. yyjson_mut_val *obj,
  2976. const char *key, uint64_t val);
  2977. /** Adds a signed integer value at the end of the object.
  2978. The `key` should be a null-terminated UTF-8 string.
  2979. This function allows duplicated key in one object.
  2980. @warning The key string are not copied, you should keep the string
  2981. unmodified for the lifetime of this JSON document. */
  2982. yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc,
  2983. yyjson_mut_val *obj,
  2984. const char *key, int64_t val);
  2985. /** Adds an int value at the end of the object.
  2986. The `key` should be a null-terminated UTF-8 string.
  2987. This function allows duplicated key in one object.
  2988. @warning The key string are not copied, you should keep the string
  2989. unmodified for the lifetime of this JSON document. */
  2990. yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc,
  2991. yyjson_mut_val *obj,
  2992. const char *key, int64_t val);
  2993. /** Adds a double value at the end of the object.
  2994. The `key` should be a null-terminated UTF-8 string.
  2995. This function allows duplicated key in one object.
  2996. @warning The key string are not copied, you should keep the string
  2997. unmodified for the lifetime of this JSON document. */
  2998. yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc,
  2999. yyjson_mut_val *obj,
  3000. const char *key, double val);
  3001. /** Adds a string value at the end of the object.
  3002. The `key` and `val` should be null-terminated UTF-8 strings.
  3003. This function allows duplicated key in one object.
  3004. @warning The key/value string are not copied, you should keep these strings
  3005. unmodified for the lifetime of this JSON document. */
  3006. yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc,
  3007. yyjson_mut_val *obj,
  3008. const char *key, const char *val);
  3009. /** Adds a string value at the end of the object.
  3010. The `key` should be a null-terminated UTF-8 string.
  3011. The `val` should be a UTF-8 string, null-terminator is not required.
  3012. The `len` should be the length of the `val`, in bytes.
  3013. This function allows duplicated key in one object.
  3014. @warning The key/value string are not copied, you should keep these strings
  3015. unmodified for the lifetime of this JSON document. */
  3016. yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc,
  3017. yyjson_mut_val *obj,
  3018. const char *key,
  3019. const char *val, size_t len);
  3020. /** Adds a string value at the end of the object.
  3021. The `key` and `val` should be null-terminated UTF-8 strings.
  3022. The value string is copied.
  3023. This function allows duplicated key in one object.
  3024. @warning The key string are not copied, you should keep the string
  3025. unmodified for the lifetime of this JSON document. */
  3026. yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
  3027. yyjson_mut_val *obj,
  3028. const char *key,
  3029. const char *val);
  3030. /** Adds a string value at the end of the object.
  3031. The `key` should be a null-terminated UTF-8 string.
  3032. The `val` should be a UTF-8 string, null-terminator is not required.
  3033. The `len` should be the length of the `val`, in bytes.
  3034. This function allows duplicated key in one object.
  3035. @warning The key/value string are not copied, you should keep these strings
  3036. unmodified for the lifetime of this JSON document. */
  3037. yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc,
  3038. yyjson_mut_val *obj,
  3039. const char *key,
  3040. const char *val, size_t len);
  3041. /** Adds a JSON value at the end of the object.
  3042. The `key` should be a null-terminated UTF-8 string.
  3043. This function allows duplicated key in one object.
  3044. @warning The key string are not copied, you should keep the string
  3045. unmodified for the lifetime of this JSON document. */
  3046. yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc,
  3047. yyjson_mut_val *obj,
  3048. const char *key,
  3049. yyjson_mut_val *val);
  3050. /** Removes all key-value pairs for the given key.
  3051. Returns the first value to which the specified key is mapped or NULL if this
  3052. object contains no mapping for the key.
  3053. The `key` should be a null-terminated UTF-8 string.
  3054. @warning This function takes a linear search time. */
  3055. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_str(
  3056. yyjson_mut_val *obj, const char *key);
  3057. /** Removes all key-value pairs for the given key.
  3058. Returns the first value to which the specified key is mapped or NULL if this
  3059. object contains no mapping for the key.
  3060. The `key` should be a UTF-8 string, null-terminator is not required.
  3061. The `len` should be the length of the key, in bytes.
  3062. @warning This function takes a linear search time. */
  3063. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_strn(
  3064. yyjson_mut_val *obj, const char *key, size_t len);
  3065. /** Replaces all matching keys with the new key.
  3066. Returns true if at least one key was renamed.
  3067. The `key` and `new_key` should be a null-terminated UTF-8 string.
  3068. The `new_key` is copied and held by doc.
  3069. @warning This function takes a linear search time.
  3070. If `new_key` already exists, it will cause duplicate keys.
  3071. */
  3072. yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc *doc,
  3073. yyjson_mut_val *obj,
  3074. const char *key,
  3075. const char *new_key);
  3076. /** Replaces all matching keys with the new key.
  3077. Returns true if at least one key was renamed.
  3078. The `key` and `new_key` should be a UTF-8 string,
  3079. null-terminator is not required. The `new_key` is copied and held by doc.
  3080. @warning This function takes a linear search time.
  3081. If `new_key` already exists, it will cause duplicate keys.
  3082. */
  3083. yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc,
  3084. yyjson_mut_val *obj,
  3085. const char *key,
  3086. size_t len,
  3087. const char *new_key,
  3088. size_t new_len);
  3089. /*==============================================================================
  3090. * JSON Pointer API (RFC 6901)
  3091. * https://tools.ietf.org/html/rfc6901
  3092. *============================================================================*/
  3093. /** JSON Pointer error code. */
  3094. typedef uint32_t yyjson_ptr_code;
  3095. /** No JSON pointer error. */
  3096. static const yyjson_ptr_code YYJSON_PTR_ERR_NONE = 0;
  3097. /** Invalid input parameter, such as NULL input. */
  3098. static const yyjson_ptr_code YYJSON_PTR_ERR_PARAMETER = 1;
  3099. /** JSON pointer syntax error, such as invalid escape, token no prefix. */
  3100. static const yyjson_ptr_code YYJSON_PTR_ERR_SYNTAX = 2;
  3101. /** JSON pointer resolve failed, such as index out of range, key not found. */
  3102. static const yyjson_ptr_code YYJSON_PTR_ERR_RESOLVE = 3;
  3103. /** Document's root is NULL, but it is required for the function call. */
  3104. static const yyjson_ptr_code YYJSON_PTR_ERR_NULL_ROOT = 4;
  3105. /** Cannot set root as the target is not a document. */
  3106. static const yyjson_ptr_code YYJSON_PTR_ERR_SET_ROOT = 5;
  3107. /** The memory allocation failed and a new value could not be created. */
  3108. static const yyjson_ptr_code YYJSON_PTR_ERR_MEMORY_ALLOCATION = 6;
  3109. /** Error information for JSON pointer. */
  3110. typedef struct yyjson_ptr_err {
  3111. /** Error code, see `yyjson_ptr_code` for all possible values. */
  3112. yyjson_ptr_code code;
  3113. /** Error message, constant, no need to free (NULL if no error). */
  3114. const char *msg;
  3115. /** Error byte position for input JSON pointer (0 if no error). */
  3116. size_t pos;
  3117. } yyjson_ptr_err;
  3118. /**
  3119. A context for JSON pointer operation.
  3120. This struct stores the context of JSON Pointer operation result. The struct
  3121. can be used with three helper functions: `ctx_append()`, `ctx_replace()`, and
  3122. `ctx_remove()`, which perform the corresponding operations on the container
  3123. without re-parsing the JSON Pointer.
  3124. For example:
  3125. @code
  3126. // doc before: {"a":[0,1,null]}
  3127. // ptr: "/a/2"
  3128. val = yyjson_mut_doc_ptr_getx(doc, ptr, strlen(ptr), &ctx, &err);
  3129. if (yyjson_is_null(val)) {
  3130. yyjson_ptr_ctx_remove(&ctx);
  3131. }
  3132. // doc after: {"a":[0,1]}
  3133. @endcode
  3134. */
  3135. typedef struct yyjson_ptr_ctx {
  3136. /**
  3137. The container (parent) of the target value. It can be either an array or
  3138. an object. If the target location has no value, but all its parent
  3139. containers exist, and the target location can be used to insert a new
  3140. value, then `ctn` is the parent container of the target location.
  3141. Otherwise, `ctn` is NULL.
  3142. */
  3143. yyjson_mut_val *ctn;
  3144. /**
  3145. The previous sibling of the target value. It can be either a value in an
  3146. array or a key in an object. As the container is a `circular linked list`
  3147. of elements, `pre` is the previous node of the target value. If the
  3148. operation is `add` or `set`, then `pre` is the previous node of the new
  3149. value, not the original target value. If the target value does not exist,
  3150. `pre` is NULL.
  3151. */
  3152. yyjson_mut_val *pre;
  3153. /**
  3154. The removed value if the operation is `set`, `replace` or `remove`. It can
  3155. be used to restore the original state of the document if needed.
  3156. */
  3157. yyjson_mut_val *old;
  3158. } yyjson_ptr_ctx;
  3159. /**
  3160. Get value by a JSON Pointer.
  3161. @param doc The JSON document to be queried.
  3162. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3163. @return The value referenced by the JSON pointer.
  3164. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3165. */
  3166. yyjson_api_inline yyjson_val *yyjson_doc_ptr_get(yyjson_doc *doc,
  3167. const char *ptr);
  3168. /**
  3169. Get value by a JSON Pointer.
  3170. @param doc The JSON document to be queried.
  3171. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3172. @param len The length of `ptr` in bytes.
  3173. @return The value referenced by the JSON pointer.
  3174. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3175. */
  3176. yyjson_api_inline yyjson_val *yyjson_doc_ptr_getn(yyjson_doc *doc,
  3177. const char *ptr, size_t len);
  3178. /**
  3179. Get value by a JSON Pointer.
  3180. @param doc The JSON document to be queried.
  3181. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3182. @param len The length of `ptr` in bytes.
  3183. @param err A pointer to store the error information, or NULL if not needed.
  3184. @return The value referenced by the JSON pointer.
  3185. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3186. */
  3187. yyjson_api_inline yyjson_val *yyjson_doc_ptr_getx(yyjson_doc *doc,
  3188. const char *ptr, size_t len,
  3189. yyjson_ptr_err *err);
  3190. /**
  3191. Get value by a JSON Pointer.
  3192. @param val The JSON value to be queried.
  3193. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3194. @return The value referenced by the JSON pointer.
  3195. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3196. */
  3197. yyjson_api_inline yyjson_val *yyjson_ptr_get(yyjson_val *val,
  3198. const char *ptr);
  3199. /**
  3200. Get value by a JSON Pointer.
  3201. @param val The JSON value to be queried.
  3202. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3203. @param len The length of `ptr` in bytes.
  3204. @return The value referenced by the JSON pointer.
  3205. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3206. */
  3207. yyjson_api_inline yyjson_val *yyjson_ptr_getn(yyjson_val *val,
  3208. const char *ptr, size_t len);
  3209. /**
  3210. Get value by a JSON Pointer.
  3211. @param val The JSON value to be queried.
  3212. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3213. @param len The length of `ptr` in bytes.
  3214. @param err A pointer to store the error information, or NULL if not needed.
  3215. @return The value referenced by the JSON pointer.
  3216. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3217. */
  3218. yyjson_api_inline yyjson_val *yyjson_ptr_getx(yyjson_val *val,
  3219. const char *ptr, size_t len,
  3220. yyjson_ptr_err *err);
  3221. /**
  3222. Get value by a JSON Pointer.
  3223. @param doc The JSON document to be queried.
  3224. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3225. @return The value referenced by the JSON pointer.
  3226. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3227. */
  3228. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_get(yyjson_mut_doc *doc,
  3229. const char *ptr);
  3230. /**
  3231. Get value by a JSON Pointer.
  3232. @param doc The JSON document to be queried.
  3233. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3234. @param len The length of `ptr` in bytes.
  3235. @return The value referenced by the JSON pointer.
  3236. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3237. */
  3238. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getn(yyjson_mut_doc *doc,
  3239. const char *ptr,
  3240. size_t len);
  3241. /**
  3242. Get value by a JSON Pointer.
  3243. @param doc The JSON document to be queried.
  3244. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3245. @param len The length of `ptr` in bytes.
  3246. @param ctx A pointer to store the result context, or NULL if not needed.
  3247. @param err A pointer to store the error information, or NULL if not needed.
  3248. @return The value referenced by the JSON pointer.
  3249. NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3250. */
  3251. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getx(yyjson_mut_doc *doc,
  3252. const char *ptr,
  3253. size_t len,
  3254. yyjson_ptr_ctx *ctx,
  3255. yyjson_ptr_err *err);
  3256. /**
  3257. Get value by a JSON Pointer.
  3258. @param val The JSON value to be queried.
  3259. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3260. @return The value referenced by the JSON pointer.
  3261. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3262. */
  3263. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_get(yyjson_mut_val *val,
  3264. const char *ptr);
  3265. /**
  3266. Get value by a JSON Pointer.
  3267. @param val The JSON value to be queried.
  3268. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3269. @param len The length of `ptr` in bytes.
  3270. @return The value referenced by the JSON pointer.
  3271. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3272. */
  3273. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getn(yyjson_mut_val *val,
  3274. const char *ptr,
  3275. size_t len);
  3276. /**
  3277. Get value by a JSON Pointer.
  3278. @param val The JSON value to be queried.
  3279. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3280. @param len The length of `ptr` in bytes.
  3281. @param ctx A pointer to store the result context, or NULL if not needed.
  3282. @param err A pointer to store the error information, or NULL if not needed.
  3283. @return The value referenced by the JSON pointer.
  3284. NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
  3285. */
  3286. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getx(yyjson_mut_val *val,
  3287. const char *ptr,
  3288. size_t len,
  3289. yyjson_ptr_ctx *ctx,
  3290. yyjson_ptr_err *err);
  3291. /**
  3292. Add (insert) value by a JSON pointer.
  3293. @param doc The target JSON document.
  3294. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3295. @param new_val The value to be added.
  3296. @return true if JSON pointer is valid and new value is added, false otherwise.
  3297. @note The parent nodes will be created if they do not exist.
  3298. */
  3299. yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc *doc,
  3300. const char *ptr,
  3301. yyjson_mut_val *new_val);
  3302. /**
  3303. Add (insert) value by a JSON pointer.
  3304. @param doc The target JSON document.
  3305. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3306. @param len The length of `ptr` in bytes.
  3307. @param new_val The value to be added.
  3308. @return true if JSON pointer is valid and new value is added, false otherwise.
  3309. @note The parent nodes will be created if they do not exist.
  3310. */
  3311. yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc *doc,
  3312. const char *ptr, size_t len,
  3313. yyjson_mut_val *new_val);
  3314. /**
  3315. Add (insert) value by a JSON pointer.
  3316. @param doc The target JSON document.
  3317. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3318. @param len The length of `ptr` in bytes.
  3319. @param new_val The value to be added.
  3320. @param create_parent Whether to create parent nodes if not exist.
  3321. @param ctx A pointer to store the result context, or NULL if not needed.
  3322. @param err A pointer to store the error information, or NULL if not needed.
  3323. @return true if JSON pointer is valid and new value is added, false otherwise.
  3324. */
  3325. yyjson_api_inline bool yyjson_mut_doc_ptr_addx(yyjson_mut_doc *doc,
  3326. const char *ptr, size_t len,
  3327. yyjson_mut_val *new_val,
  3328. bool create_parent,
  3329. yyjson_ptr_ctx *ctx,
  3330. yyjson_ptr_err *err);
  3331. /**
  3332. Add (insert) value by a JSON pointer.
  3333. @param val The target JSON value.
  3334. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3335. @param doc Only used to create new values when needed.
  3336. @param new_val The value to be added.
  3337. @return true if JSON pointer is valid and new value is added, false otherwise.
  3338. @note The parent nodes will be created if they do not exist.
  3339. */
  3340. yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val *val,
  3341. const char *ptr,
  3342. yyjson_mut_val *new_val,
  3343. yyjson_mut_doc *doc);
  3344. /**
  3345. Add (insert) value by a JSON pointer.
  3346. @param val The target JSON value.
  3347. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3348. @param len The length of `ptr` in bytes.
  3349. @param doc Only used to create new values when needed.
  3350. @param new_val The value to be added.
  3351. @return true if JSON pointer is valid and new value is added, false otherwise.
  3352. @note The parent nodes will be created if they do not exist.
  3353. */
  3354. yyjson_api_inline bool yyjson_mut_ptr_addn(yyjson_mut_val *val,
  3355. const char *ptr, size_t len,
  3356. yyjson_mut_val *new_val,
  3357. yyjson_mut_doc *doc);
  3358. /**
  3359. Add (insert) value by a JSON pointer.
  3360. @param val The target JSON value.
  3361. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3362. @param len The length of `ptr` in bytes.
  3363. @param doc Only used to create new values when needed.
  3364. @param new_val The value to be added.
  3365. @param create_parent Whether to create parent nodes if not exist.
  3366. @param ctx A pointer to store the result context, or NULL if not needed.
  3367. @param err A pointer to store the error information, or NULL if not needed.
  3368. @return true if JSON pointer is valid and new value is added, false otherwise.
  3369. */
  3370. yyjson_api_inline bool yyjson_mut_ptr_addx(yyjson_mut_val *val,
  3371. const char *ptr, size_t len,
  3372. yyjson_mut_val *new_val,
  3373. yyjson_mut_doc *doc,
  3374. bool create_parent,
  3375. yyjson_ptr_ctx *ctx,
  3376. yyjson_ptr_err *err);
  3377. /**
  3378. Set value by a JSON pointer.
  3379. @param doc The target JSON document.
  3380. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3381. @param new_val The value to be set, pass NULL to remove.
  3382. @return true if JSON pointer is valid and new value is set, false otherwise.
  3383. @note The parent nodes will be created if they do not exist.
  3384. If the target value already exists, it will be replaced by the new value.
  3385. */
  3386. yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc *doc,
  3387. const char *ptr,
  3388. yyjson_mut_val *new_val);
  3389. /**
  3390. Set value by a JSON pointer.
  3391. @param doc The target JSON document.
  3392. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3393. @param len The length of `ptr` in bytes.
  3394. @param new_val The value to be set, pass NULL to remove.
  3395. @return true if JSON pointer is valid and new value is set, false otherwise.
  3396. @note The parent nodes will be created if they do not exist.
  3397. If the target value already exists, it will be replaced by the new value.
  3398. */
  3399. yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc *doc,
  3400. const char *ptr, size_t len,
  3401. yyjson_mut_val *new_val);
  3402. /**
  3403. Set value by a JSON pointer.
  3404. @param doc The target JSON document.
  3405. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3406. @param len The length of `ptr` in bytes.
  3407. @param new_val The value to be set, pass NULL to remove.
  3408. @param create_parent Whether to create parent nodes if not exist.
  3409. @param ctx A pointer to store the result context, or NULL if not needed.
  3410. @param err A pointer to store the error information, or NULL if not needed.
  3411. @return true if JSON pointer is valid and new value is set, false otherwise.
  3412. @note If the target value already exists, it will be replaced by the new value.
  3413. */
  3414. yyjson_api_inline bool yyjson_mut_doc_ptr_setx(yyjson_mut_doc *doc,
  3415. const char *ptr, size_t len,
  3416. yyjson_mut_val *new_val,
  3417. bool create_parent,
  3418. yyjson_ptr_ctx *ctx,
  3419. yyjson_ptr_err *err);
  3420. /**
  3421. Set value by a JSON pointer.
  3422. @param val The target JSON value.
  3423. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3424. @param new_val The value to be set, pass NULL to remove.
  3425. @param doc Only used to create new values when needed.
  3426. @return true if JSON pointer is valid and new value is set, false otherwise.
  3427. @note The parent nodes will be created if they do not exist.
  3428. If the target value already exists, it will be replaced by the new value.
  3429. */
  3430. yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val *val,
  3431. const char *ptr,
  3432. yyjson_mut_val *new_val,
  3433. yyjson_mut_doc *doc);
  3434. /**
  3435. Set value by a JSON pointer.
  3436. @param val The target JSON value.
  3437. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3438. @param len The length of `ptr` in bytes.
  3439. @param new_val The value to be set, pass NULL to remove.
  3440. @param doc Only used to create new values when needed.
  3441. @return true if JSON pointer is valid and new value is set, false otherwise.
  3442. @note The parent nodes will be created if they do not exist.
  3443. If the target value already exists, it will be replaced by the new value.
  3444. */
  3445. yyjson_api_inline bool yyjson_mut_ptr_setn(yyjson_mut_val *val,
  3446. const char *ptr, size_t len,
  3447. yyjson_mut_val *new_val,
  3448. yyjson_mut_doc *doc);
  3449. /**
  3450. Set value by a JSON pointer.
  3451. @param val The target JSON value.
  3452. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3453. @param len The length of `ptr` in bytes.
  3454. @param new_val The value to be set, pass NULL to remove.
  3455. @param doc Only used to create new values when needed.
  3456. @param create_parent Whether to create parent nodes if not exist.
  3457. @param ctx A pointer to store the result context, or NULL if not needed.
  3458. @param err A pointer to store the error information, or NULL if not needed.
  3459. @return true if JSON pointer is valid and new value is set, false otherwise.
  3460. @note If the target value already exists, it will be replaced by the new value.
  3461. */
  3462. yyjson_api_inline bool yyjson_mut_ptr_setx(yyjson_mut_val *val,
  3463. const char *ptr, size_t len,
  3464. yyjson_mut_val *new_val,
  3465. yyjson_mut_doc *doc,
  3466. bool create_parent,
  3467. yyjson_ptr_ctx *ctx,
  3468. yyjson_ptr_err *err);
  3469. /**
  3470. Replace value by a JSON pointer.
  3471. @param doc The target JSON document.
  3472. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3473. @param new_val The new value to replace the old one.
  3474. @return The old value that was replaced, or NULL if not found.
  3475. */
  3476. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replace(
  3477. yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val);
  3478. /**
  3479. Replace value by a JSON pointer.
  3480. @param doc The target JSON document.
  3481. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3482. @param len The length of `ptr` in bytes.
  3483. @param new_val The new value to replace the old one.
  3484. @return The old value that was replaced, or NULL if not found.
  3485. */
  3486. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacen(
  3487. yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val);
  3488. /**
  3489. Replace value by a JSON pointer.
  3490. @param doc The target JSON document.
  3491. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3492. @param len The length of `ptr` in bytes.
  3493. @param new_val The new value to replace the old one.
  3494. @param ctx A pointer to store the result context, or NULL if not needed.
  3495. @param err A pointer to store the error information, or NULL if not needed.
  3496. @return The old value that was replaced, or NULL if not found.
  3497. */
  3498. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacex(
  3499. yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val,
  3500. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
  3501. /**
  3502. Replace value by a JSON pointer.
  3503. @param val The target JSON value.
  3504. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3505. @param new_val The new value to replace the old one.
  3506. @return The old value that was replaced, or NULL if not found.
  3507. */
  3508. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replace(
  3509. yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val);
  3510. /**
  3511. Replace value by a JSON pointer.
  3512. @param val The target JSON value.
  3513. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3514. @param len The length of `ptr` in bytes.
  3515. @param new_val The new value to replace the old one.
  3516. @return The old value that was replaced, or NULL if not found.
  3517. */
  3518. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacen(
  3519. yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val);
  3520. /**
  3521. Replace value by a JSON pointer.
  3522. @param val The target JSON value.
  3523. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3524. @param len The length of `ptr` in bytes.
  3525. @param new_val The new value to replace the old one.
  3526. @param ctx A pointer to store the result context, or NULL if not needed.
  3527. @param err A pointer to store the error information, or NULL if not needed.
  3528. @return The old value that was replaced, or NULL if not found.
  3529. */
  3530. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacex(
  3531. yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
  3532. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
  3533. /**
  3534. Remove value by a JSON pointer.
  3535. @param doc The target JSON document.
  3536. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3537. @return The removed value, or NULL on error.
  3538. */
  3539. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_remove(
  3540. yyjson_mut_doc *doc, const char *ptr);
  3541. /**
  3542. Remove value by a JSON pointer.
  3543. @param doc The target JSON document.
  3544. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3545. @param len The length of `ptr` in bytes.
  3546. @return The removed value, or NULL on error.
  3547. */
  3548. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removen(
  3549. yyjson_mut_doc *doc, const char *ptr, size_t len);
  3550. /**
  3551. Remove value by a JSON pointer.
  3552. @param doc The target JSON document.
  3553. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3554. @param len The length of `ptr` in bytes.
  3555. @param ctx A pointer to store the result context, or NULL if not needed.
  3556. @param err A pointer to store the error information, or NULL if not needed.
  3557. @return The removed value, or NULL on error.
  3558. */
  3559. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removex(
  3560. yyjson_mut_doc *doc, const char *ptr, size_t len,
  3561. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
  3562. /**
  3563. Remove value by a JSON pointer.
  3564. @param val The target JSON value.
  3565. @param ptr The JSON pointer string (UTF-8 with null-terminator).
  3566. @return The removed value, or NULL on error.
  3567. */
  3568. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_remove(yyjson_mut_val *val,
  3569. const char *ptr);
  3570. /**
  3571. Remove value by a JSON pointer.
  3572. @param val The target JSON value.
  3573. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3574. @param len The length of `ptr` in bytes.
  3575. @return The removed value, or NULL on error.
  3576. */
  3577. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removen(yyjson_mut_val *val,
  3578. const char *ptr,
  3579. size_t len);
  3580. /**
  3581. Remove value by a JSON pointer.
  3582. @param val The target JSON value.
  3583. @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
  3584. @param len The length of `ptr` in bytes.
  3585. @param ctx A pointer to store the result context, or NULL if not needed.
  3586. @param err A pointer to store the error information, or NULL if not needed.
  3587. @return The removed value, or NULL on error.
  3588. */
  3589. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removex(yyjson_mut_val *val,
  3590. const char *ptr,
  3591. size_t len,
  3592. yyjson_ptr_ctx *ctx,
  3593. yyjson_ptr_err *err);
  3594. /**
  3595. Append value by JSON pointer context.
  3596. @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
  3597. @param key New key if `ctx->ctn` is object, or NULL if `ctx->ctn` is array.
  3598. @param val New value to be added.
  3599. @return true on success or false on fail.
  3600. */
  3601. yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx *ctx,
  3602. yyjson_mut_val *key,
  3603. yyjson_mut_val *val);
  3604. /**
  3605. Replace value by JSON pointer context.
  3606. @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
  3607. @param val New value to be replaced.
  3608. @return true on success or false on fail.
  3609. @note If success, the old value will be returned via `ctx->old`.
  3610. */
  3611. yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx *ctx,
  3612. yyjson_mut_val *val);
  3613. /**
  3614. Remove value by JSON pointer context.
  3615. @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
  3616. @return true on success or false on fail.
  3617. @note If success, the old value will be returned via `ctx->old`.
  3618. */
  3619. yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx);
  3620. /*==============================================================================
  3621. * JSON Patch API (RFC 6902)
  3622. * https://tools.ietf.org/html/rfc6902
  3623. *============================================================================*/
  3624. /** Result code for JSON patch. */
  3625. typedef uint32_t yyjson_patch_code;
  3626. /** Success, no error. */
  3627. static const yyjson_patch_code YYJSON_PATCH_SUCCESS = 0;
  3628. /** Invalid parameter, such as NULL input or non-array patch. */
  3629. static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_PARAMETER = 1;
  3630. /** Memory allocation failure occurs. */
  3631. static const yyjson_patch_code YYJSON_PATCH_ERROR_MEMORY_ALLOCATION = 2;
  3632. /** JSON patch operation is not object type. */
  3633. static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_OPERATION = 3;
  3634. /** JSON patch operation is missing a required key. */
  3635. static const yyjson_patch_code YYJSON_PATCH_ERROR_MISSING_KEY = 4;
  3636. /** JSON patch operation member is invalid. */
  3637. static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_MEMBER = 5;
  3638. /** JSON patch operation `test` not equal. */
  3639. static const yyjson_patch_code YYJSON_PATCH_ERROR_EQUAL = 6;
  3640. /** JSON patch operation failed on JSON pointer. */
  3641. static const yyjson_patch_code YYJSON_PATCH_ERROR_POINTER = 7;
  3642. /** Error information for JSON patch. */
  3643. typedef struct yyjson_patch_err {
  3644. /** Error code, see `yyjson_patch_code` for all possible values. */
  3645. yyjson_patch_code code;
  3646. /** Index of the error operation (0 if no error). */
  3647. size_t idx;
  3648. /** Error message, constant, no need to free (NULL if no error). */
  3649. const char *msg;
  3650. /** JSON pointer error if `code == YYJSON_PATCH_ERROR_POINTER`. */
  3651. yyjson_ptr_err ptr;
  3652. } yyjson_patch_err;
  3653. /**
  3654. Creates and returns a patched JSON value (RFC 6902).
  3655. The memory of the returned value is allocated by the `doc`.
  3656. The `err` is used to receive error information, pass NULL if not needed.
  3657. Returns NULL if the patch could not be applied.
  3658. */
  3659. yyjson_api yyjson_mut_val *yyjson_patch(yyjson_mut_doc *doc,
  3660. yyjson_val *orig,
  3661. yyjson_val *patch,
  3662. yyjson_patch_err *err);
  3663. /**
  3664. Creates and returns a patched JSON value (RFC 6902).
  3665. The memory of the returned value is allocated by the `doc`.
  3666. The `err` is used to receive error information, pass NULL if not needed.
  3667. Returns NULL if the patch could not be applied.
  3668. */
  3669. yyjson_api yyjson_mut_val *yyjson_mut_patch(yyjson_mut_doc *doc,
  3670. yyjson_mut_val *orig,
  3671. yyjson_mut_val *patch,
  3672. yyjson_patch_err *err);
  3673. /*==============================================================================
  3674. * JSON Merge-Patch API (RFC 7386)
  3675. * https://tools.ietf.org/html/rfc7386
  3676. *============================================================================*/
  3677. /**
  3678. Creates and returns a merge-patched JSON value (RFC 7386).
  3679. The memory of the returned value is allocated by the `doc`.
  3680. Returns NULL if the patch could not be applied.
  3681. @warning This function is recursive and may cause a stack overflow if the
  3682. object level is too deep.
  3683. */
  3684. yyjson_api yyjson_mut_val *yyjson_merge_patch(yyjson_mut_doc *doc,
  3685. yyjson_val *orig,
  3686. yyjson_val *patch);
  3687. /**
  3688. Creates and returns a merge-patched JSON value (RFC 7386).
  3689. The memory of the returned value is allocated by the `doc`.
  3690. Returns NULL if the patch could not be applied.
  3691. @warning This function is recursive and may cause a stack overflow if the
  3692. object level is too deep.
  3693. */
  3694. yyjson_api yyjson_mut_val *yyjson_mut_merge_patch(yyjson_mut_doc *doc,
  3695. yyjson_mut_val *orig,
  3696. yyjson_mut_val *patch);
  3697. /*==============================================================================
  3698. * JSON Structure (Implementation)
  3699. *============================================================================*/
  3700. /** Payload of a JSON value (8 bytes). */
  3701. typedef union yyjson_val_uni {
  3702. uint64_t u64;
  3703. int64_t i64;
  3704. double f64;
  3705. const char *str;
  3706. void *ptr;
  3707. size_t ofs;
  3708. } yyjson_val_uni;
  3709. /**
  3710. Immutable JSON value, 16 bytes.
  3711. */
  3712. struct yyjson_val {
  3713. uint64_t tag; /**< type, subtype and length */
  3714. yyjson_val_uni uni; /**< payload */
  3715. };
  3716. struct yyjson_doc {
  3717. /** Root value of the document (nonnull). */
  3718. yyjson_val *root;
  3719. /** Allocator used by document (nonnull). */
  3720. yyjson_alc alc;
  3721. /** The total number of bytes read when parsing JSON (nonzero). */
  3722. size_t dat_read;
  3723. /** The total number of value read when parsing JSON (nonzero). */
  3724. size_t val_read;
  3725. /** The string pool used by JSON values (nullable). */
  3726. char *str_pool;
  3727. };
  3728. /*==============================================================================
  3729. * Unsafe JSON Value API (Implementation)
  3730. *============================================================================*/
  3731. /*
  3732. Whether the string does not need to be escaped for serialization.
  3733. This function is used to optimize the writing speed of small constant strings.
  3734. This function works only if the compiler can evaluate it at compile time.
  3735. Clang supports it since v8.0,
  3736. earlier versions do not support constant_p(strlen) and return false.
  3737. GCC supports it since at least v4.4,
  3738. earlier versions may compile it as run-time instructions.
  3739. ICC supports it since at least v16,
  3740. earlier versions are uncertain.
  3741. @param str The C string.
  3742. @param len The returnd value from strlen(str).
  3743. */
  3744. yyjson_api_inline bool unsafe_yyjson_is_str_noesc(const char *str, size_t len) {
  3745. #if YYJSON_HAS_CONSTANT_P && \
  3746. (!YYJSON_IS_REAL_GCC || yyjson_gcc_available(4, 4, 0))
  3747. if (yyjson_constant_p(len) && len <= 32) {
  3748. /*
  3749. Same as the following loop:
  3750. for (size_t i = 0; i < len; i++) {
  3751. char c = str[i];
  3752. if (c < ' ' || c > '~' || c == '"' || c == '\\') return false;
  3753. }
  3754. GCC evaluates it at compile time only if the string length is within 17
  3755. and -O3 (which turns on the -fpeel-loops flag) is used.
  3756. So the loop is unrolled for GCC.
  3757. */
  3758. # define yyjson_repeat32_incr(x) \
  3759. x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) \
  3760. x(8) x(9) x(10) x(11) x(12) x(13) x(14) x(15) \
  3761. x(16) x(17) x(18) x(19) x(20) x(21) x(22) x(23) \
  3762. x(24) x(25) x(26) x(27) x(28) x(29) x(30) x(31)
  3763. # define yyjson_check_char_noesc(i) \
  3764. if (i < len) { \
  3765. char c = str[i]; \
  3766. if (c < ' ' || c > '~' || c == '"' || c == '\\') return false; }
  3767. yyjson_repeat32_incr(yyjson_check_char_noesc)
  3768. # undef yyjson_repeat32_incr
  3769. # undef yyjson_check_char_noesc
  3770. return true;
  3771. }
  3772. #else
  3773. (void)str;
  3774. (void)len;
  3775. #endif
  3776. return false;
  3777. }
  3778. yyjson_api_inline yyjson_type unsafe_yyjson_get_type(void *val) {
  3779. uint8_t tag = (uint8_t)((yyjson_val *)val)->tag;
  3780. return (yyjson_type)(tag & YYJSON_TYPE_MASK);
  3781. }
  3782. yyjson_api_inline yyjson_subtype unsafe_yyjson_get_subtype(void *val) {
  3783. uint8_t tag = (uint8_t)((yyjson_val *)val)->tag;
  3784. return (yyjson_subtype)(tag & YYJSON_SUBTYPE_MASK);
  3785. }
  3786. yyjson_api_inline uint8_t unsafe_yyjson_get_tag(void *val) {
  3787. uint8_t tag = (uint8_t)((yyjson_val *)val)->tag;
  3788. return (uint8_t)(tag & YYJSON_TAG_MASK);
  3789. }
  3790. yyjson_api_inline bool unsafe_yyjson_is_raw(void *val) {
  3791. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_RAW;
  3792. }
  3793. yyjson_api_inline bool unsafe_yyjson_is_null(void *val) {
  3794. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NULL;
  3795. }
  3796. yyjson_api_inline bool unsafe_yyjson_is_bool(void *val) {
  3797. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_BOOL;
  3798. }
  3799. yyjson_api_inline bool unsafe_yyjson_is_num(void *val) {
  3800. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NUM;
  3801. }
  3802. yyjson_api_inline bool unsafe_yyjson_is_str(void *val) {
  3803. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_STR;
  3804. }
  3805. yyjson_api_inline bool unsafe_yyjson_is_arr(void *val) {
  3806. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_ARR;
  3807. }
  3808. yyjson_api_inline bool unsafe_yyjson_is_obj(void *val) {
  3809. return unsafe_yyjson_get_type(val) == YYJSON_TYPE_OBJ;
  3810. }
  3811. yyjson_api_inline bool unsafe_yyjson_is_ctn(void *val) {
  3812. uint8_t mask = YYJSON_TYPE_ARR & YYJSON_TYPE_OBJ;
  3813. return (unsafe_yyjson_get_tag(val) & mask) == mask;
  3814. }
  3815. yyjson_api_inline bool unsafe_yyjson_is_uint(void *val) {
  3816. const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  3817. return unsafe_yyjson_get_tag(val) == patt;
  3818. }
  3819. yyjson_api_inline bool unsafe_yyjson_is_sint(void *val) {
  3820. const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  3821. return unsafe_yyjson_get_tag(val) == patt;
  3822. }
  3823. yyjson_api_inline bool unsafe_yyjson_is_int(void *val) {
  3824. const uint8_t mask = YYJSON_TAG_MASK & (~YYJSON_SUBTYPE_SINT);
  3825. const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  3826. return (unsafe_yyjson_get_tag(val) & mask) == patt;
  3827. }
  3828. yyjson_api_inline bool unsafe_yyjson_is_real(void *val) {
  3829. const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
  3830. return unsafe_yyjson_get_tag(val) == patt;
  3831. }
  3832. yyjson_api_inline bool unsafe_yyjson_is_true(void *val) {
  3833. const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
  3834. return unsafe_yyjson_get_tag(val) == patt;
  3835. }
  3836. yyjson_api_inline bool unsafe_yyjson_is_false(void *val) {
  3837. const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
  3838. return unsafe_yyjson_get_tag(val) == patt;
  3839. }
  3840. yyjson_api_inline bool unsafe_yyjson_arr_is_flat(yyjson_val *val) {
  3841. size_t ofs = val->uni.ofs;
  3842. size_t len = (size_t)(val->tag >> YYJSON_TAG_BIT);
  3843. return len * sizeof(yyjson_val) + sizeof(yyjson_val) == ofs;
  3844. }
  3845. yyjson_api_inline const char *unsafe_yyjson_get_raw(void *val) {
  3846. return ((yyjson_val *)val)->uni.str;
  3847. }
  3848. yyjson_api_inline bool unsafe_yyjson_get_bool(void *val) {
  3849. uint8_t tag = unsafe_yyjson_get_tag(val);
  3850. return (bool)((tag & YYJSON_SUBTYPE_MASK) >> YYJSON_TYPE_BIT);
  3851. }
  3852. yyjson_api_inline uint64_t unsafe_yyjson_get_uint(void *val) {
  3853. return ((yyjson_val *)val)->uni.u64;
  3854. }
  3855. yyjson_api_inline int64_t unsafe_yyjson_get_sint(void *val) {
  3856. return ((yyjson_val *)val)->uni.i64;
  3857. }
  3858. yyjson_api_inline int unsafe_yyjson_get_int(void *val) {
  3859. return (int)((yyjson_val *)val)->uni.i64;
  3860. }
  3861. yyjson_api_inline double unsafe_yyjson_get_real(void *val) {
  3862. return ((yyjson_val *)val)->uni.f64;
  3863. }
  3864. yyjson_api_inline double unsafe_yyjson_get_num(void *val) {
  3865. uint8_t tag = unsafe_yyjson_get_tag(val);
  3866. if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL)) {
  3867. return ((yyjson_val *)val)->uni.f64;
  3868. } else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT)) {
  3869. return (double)((yyjson_val *)val)->uni.i64;
  3870. } else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT)) {
  3871. #if YYJSON_U64_TO_F64_NO_IMPL
  3872. uint64_t msb = ((uint64_t)1) << 63;
  3873. uint64_t num = ((yyjson_val *)val)->uni.u64;
  3874. if ((num & msb) == 0) {
  3875. return (double)(int64_t)num;
  3876. } else {
  3877. return ((double)(int64_t)((num >> 1) | (num & 1))) * (double)2.0;
  3878. }
  3879. #else
  3880. return (double)((yyjson_val *)val)->uni.u64;
  3881. #endif
  3882. }
  3883. return 0.0;
  3884. }
  3885. yyjson_api_inline const char *unsafe_yyjson_get_str(void *val) {
  3886. return ((yyjson_val *)val)->uni.str;
  3887. }
  3888. yyjson_api_inline size_t unsafe_yyjson_get_len(void *val) {
  3889. return (size_t)(((yyjson_val *)val)->tag >> YYJSON_TAG_BIT);
  3890. }
  3891. yyjson_api_inline yyjson_val *unsafe_yyjson_get_first(yyjson_val *ctn) {
  3892. return ctn + 1;
  3893. }
  3894. yyjson_api_inline yyjson_val *unsafe_yyjson_get_next(yyjson_val *val) {
  3895. bool is_ctn = unsafe_yyjson_is_ctn(val);
  3896. size_t ctn_ofs = val->uni.ofs;
  3897. size_t ofs = (is_ctn ? ctn_ofs : sizeof(yyjson_val));
  3898. return (yyjson_val *)(void *)((uint8_t *)val + ofs);
  3899. }
  3900. yyjson_api_inline bool unsafe_yyjson_equals_strn(void *val, const char *str,
  3901. size_t len) {
  3902. return unsafe_yyjson_get_len(val) == len &&
  3903. memcmp(((yyjson_val *)val)->uni.str, str, len) == 0;
  3904. }
  3905. yyjson_api_inline bool unsafe_yyjson_equals_str(void *val, const char *str) {
  3906. return unsafe_yyjson_equals_strn(val, str, strlen(str));
  3907. }
  3908. yyjson_api_inline void unsafe_yyjson_set_type(void *val, yyjson_type type,
  3909. yyjson_subtype subtype) {
  3910. uint8_t tag = (type | subtype);
  3911. uint64_t new_tag = ((yyjson_val *)val)->tag;
  3912. new_tag = (new_tag & (~(uint64_t)YYJSON_TAG_MASK)) | (uint64_t)tag;
  3913. ((yyjson_val *)val)->tag = new_tag;
  3914. }
  3915. yyjson_api_inline void unsafe_yyjson_set_len(void *val, size_t len) {
  3916. uint64_t tag = ((yyjson_val *)val)->tag & YYJSON_TAG_MASK;
  3917. tag |= (uint64_t)len << YYJSON_TAG_BIT;
  3918. ((yyjson_val *)val)->tag = tag;
  3919. }
  3920. yyjson_api_inline void unsafe_yyjson_inc_len(void *val) {
  3921. uint64_t tag = ((yyjson_val *)val)->tag;
  3922. tag += (uint64_t)(1 << YYJSON_TAG_BIT);
  3923. ((yyjson_val *)val)->tag = tag;
  3924. }
  3925. yyjson_api_inline void unsafe_yyjson_set_raw(void *val, const char *raw,
  3926. size_t len) {
  3927. unsafe_yyjson_set_type(val, YYJSON_TYPE_RAW, YYJSON_SUBTYPE_NONE);
  3928. unsafe_yyjson_set_len(val, len);
  3929. ((yyjson_val *)val)->uni.str = raw;
  3930. }
  3931. yyjson_api_inline void unsafe_yyjson_set_null(void *val) {
  3932. unsafe_yyjson_set_type(val, YYJSON_TYPE_NULL, YYJSON_SUBTYPE_NONE);
  3933. unsafe_yyjson_set_len(val, 0);
  3934. }
  3935. yyjson_api_inline void unsafe_yyjson_set_bool(void *val, bool num) {
  3936. yyjson_subtype subtype = num ? YYJSON_SUBTYPE_TRUE : YYJSON_SUBTYPE_FALSE;
  3937. unsafe_yyjson_set_type(val, YYJSON_TYPE_BOOL, subtype);
  3938. unsafe_yyjson_set_len(val, 0);
  3939. }
  3940. yyjson_api_inline void unsafe_yyjson_set_uint(void *val, uint64_t num) {
  3941. unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_UINT);
  3942. unsafe_yyjson_set_len(val, 0);
  3943. ((yyjson_val *)val)->uni.u64 = num;
  3944. }
  3945. yyjson_api_inline void unsafe_yyjson_set_sint(void *val, int64_t num) {
  3946. unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_SINT);
  3947. unsafe_yyjson_set_len(val, 0);
  3948. ((yyjson_val *)val)->uni.i64 = num;
  3949. }
  3950. yyjson_api_inline void unsafe_yyjson_set_real(void *val, double num) {
  3951. unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_REAL);
  3952. unsafe_yyjson_set_len(val, 0);
  3953. ((yyjson_val *)val)->uni.f64 = num;
  3954. }
  3955. yyjson_api_inline void unsafe_yyjson_set_str(void *val, const char *str) {
  3956. size_t len = strlen(str);
  3957. bool noesc = unsafe_yyjson_is_str_noesc(str, len);
  3958. yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
  3959. unsafe_yyjson_set_type(val, YYJSON_TYPE_STR, sub);
  3960. unsafe_yyjson_set_len(val, len);
  3961. ((yyjson_val *)val)->uni.str = str;
  3962. }
  3963. yyjson_api_inline void unsafe_yyjson_set_strn(void *val, const char *str,
  3964. size_t len) {
  3965. unsafe_yyjson_set_type(val, YYJSON_TYPE_STR, YYJSON_SUBTYPE_NONE);
  3966. unsafe_yyjson_set_len(val, len);
  3967. ((yyjson_val *)val)->uni.str = str;
  3968. }
  3969. yyjson_api_inline void unsafe_yyjson_set_arr(void *val, size_t size) {
  3970. unsafe_yyjson_set_type(val, YYJSON_TYPE_ARR, YYJSON_SUBTYPE_NONE);
  3971. unsafe_yyjson_set_len(val, size);
  3972. }
  3973. yyjson_api_inline void unsafe_yyjson_set_obj(void *val, size_t size) {
  3974. unsafe_yyjson_set_type(val, YYJSON_TYPE_OBJ, YYJSON_SUBTYPE_NONE);
  3975. unsafe_yyjson_set_len(val, size);
  3976. }
  3977. /*==============================================================================
  3978. * JSON Document API (Implementation)
  3979. *============================================================================*/
  3980. yyjson_api_inline yyjson_val *yyjson_doc_get_root(yyjson_doc *doc) {
  3981. return doc ? doc->root : NULL;
  3982. }
  3983. yyjson_api_inline size_t yyjson_doc_get_read_size(yyjson_doc *doc) {
  3984. return doc ? doc->dat_read : 0;
  3985. }
  3986. yyjson_api_inline size_t yyjson_doc_get_val_count(yyjson_doc *doc) {
  3987. return doc ? doc->val_read : 0;
  3988. }
  3989. yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc) {
  3990. if (doc) {
  3991. yyjson_alc alc = doc->alc;
  3992. if (doc->str_pool) alc.free(alc.ctx, doc->str_pool);
  3993. alc.free(alc.ctx, doc);
  3994. }
  3995. }
  3996. /*==============================================================================
  3997. * JSON Value Type API (Implementation)
  3998. *============================================================================*/
  3999. yyjson_api_inline bool yyjson_is_raw(yyjson_val *val) {
  4000. return val ? unsafe_yyjson_is_raw(val) : false;
  4001. }
  4002. yyjson_api_inline bool yyjson_is_null(yyjson_val *val) {
  4003. return val ? unsafe_yyjson_is_null(val) : false;
  4004. }
  4005. yyjson_api_inline bool yyjson_is_true(yyjson_val *val) {
  4006. return val ? unsafe_yyjson_is_true(val) : false;
  4007. }
  4008. yyjson_api_inline bool yyjson_is_false(yyjson_val *val) {
  4009. return val ? unsafe_yyjson_is_false(val) : false;
  4010. }
  4011. yyjson_api_inline bool yyjson_is_bool(yyjson_val *val) {
  4012. return val ? unsafe_yyjson_is_bool(val) : false;
  4013. }
  4014. yyjson_api_inline bool yyjson_is_uint(yyjson_val *val) {
  4015. return val ? unsafe_yyjson_is_uint(val) : false;
  4016. }
  4017. yyjson_api_inline bool yyjson_is_sint(yyjson_val *val) {
  4018. return val ? unsafe_yyjson_is_sint(val) : false;
  4019. }
  4020. yyjson_api_inline bool yyjson_is_int(yyjson_val *val) {
  4021. return val ? unsafe_yyjson_is_int(val) : false;
  4022. }
  4023. yyjson_api_inline bool yyjson_is_real(yyjson_val *val) {
  4024. return val ? unsafe_yyjson_is_real(val) : false;
  4025. }
  4026. yyjson_api_inline bool yyjson_is_num(yyjson_val *val) {
  4027. return val ? unsafe_yyjson_is_num(val) : false;
  4028. }
  4029. yyjson_api_inline bool yyjson_is_str(yyjson_val *val) {
  4030. return val ? unsafe_yyjson_is_str(val) : false;
  4031. }
  4032. yyjson_api_inline bool yyjson_is_arr(yyjson_val *val) {
  4033. return val ? unsafe_yyjson_is_arr(val) : false;
  4034. }
  4035. yyjson_api_inline bool yyjson_is_obj(yyjson_val *val) {
  4036. return val ? unsafe_yyjson_is_obj(val) : false;
  4037. }
  4038. yyjson_api_inline bool yyjson_is_ctn(yyjson_val *val) {
  4039. return val ? unsafe_yyjson_is_ctn(val) : false;
  4040. }
  4041. /*==============================================================================
  4042. * JSON Value Content API (Implementation)
  4043. *============================================================================*/
  4044. yyjson_api_inline yyjson_type yyjson_get_type(yyjson_val *val) {
  4045. return val ? unsafe_yyjson_get_type(val) : YYJSON_TYPE_NONE;
  4046. }
  4047. yyjson_api_inline yyjson_subtype yyjson_get_subtype(yyjson_val *val) {
  4048. return val ? unsafe_yyjson_get_subtype(val) : YYJSON_SUBTYPE_NONE;
  4049. }
  4050. yyjson_api_inline uint8_t yyjson_get_tag(yyjson_val *val) {
  4051. return val ? unsafe_yyjson_get_tag(val) : 0;
  4052. }
  4053. yyjson_api_inline const char *yyjson_get_type_desc(yyjson_val *val) {
  4054. switch (yyjson_get_tag(val)) {
  4055. case YYJSON_TYPE_RAW | YYJSON_SUBTYPE_NONE: return "raw";
  4056. case YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE: return "null";
  4057. case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NONE: return "string";
  4058. case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NOESC: return "string";
  4059. case YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE: return "array";
  4060. case YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE: return "object";
  4061. case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE: return "true";
  4062. case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE: return "false";
  4063. case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT: return "uint";
  4064. case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT: return "sint";
  4065. case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL: return "real";
  4066. default: return "unknown";
  4067. }
  4068. }
  4069. yyjson_api_inline const char *yyjson_get_raw(yyjson_val *val) {
  4070. return yyjson_is_raw(val) ? unsafe_yyjson_get_raw(val) : NULL;
  4071. }
  4072. yyjson_api_inline bool yyjson_get_bool(yyjson_val *val) {
  4073. return yyjson_is_bool(val) ? unsafe_yyjson_get_bool(val) : false;
  4074. }
  4075. yyjson_api_inline uint64_t yyjson_get_uint(yyjson_val *val) {
  4076. return yyjson_is_int(val) ? unsafe_yyjson_get_uint(val) : 0;
  4077. }
  4078. yyjson_api_inline int64_t yyjson_get_sint(yyjson_val *val) {
  4079. return yyjson_is_int(val) ? unsafe_yyjson_get_sint(val) : 0;
  4080. }
  4081. yyjson_api_inline int yyjson_get_int(yyjson_val *val) {
  4082. return yyjson_is_int(val) ? unsafe_yyjson_get_int(val) : 0;
  4083. }
  4084. yyjson_api_inline double yyjson_get_real(yyjson_val *val) {
  4085. return yyjson_is_real(val) ? unsafe_yyjson_get_real(val) : 0.0;
  4086. }
  4087. yyjson_api_inline double yyjson_get_num(yyjson_val *val) {
  4088. return val ? unsafe_yyjson_get_num(val) : 0.0;
  4089. }
  4090. yyjson_api_inline const char *yyjson_get_str(yyjson_val *val) {
  4091. return yyjson_is_str(val) ? unsafe_yyjson_get_str(val) : NULL;
  4092. }
  4093. yyjson_api_inline size_t yyjson_get_len(yyjson_val *val) {
  4094. return val ? unsafe_yyjson_get_len(val) : 0;
  4095. }
  4096. yyjson_api_inline bool yyjson_equals_str(yyjson_val *val, const char *str) {
  4097. if (yyjson_likely(val && str)) {
  4098. return unsafe_yyjson_is_str(val) &&
  4099. unsafe_yyjson_equals_str(val, str);
  4100. }
  4101. return false;
  4102. }
  4103. yyjson_api_inline bool yyjson_equals_strn(yyjson_val *val, const char *str,
  4104. size_t len) {
  4105. if (yyjson_likely(val && str)) {
  4106. return unsafe_yyjson_is_str(val) &&
  4107. unsafe_yyjson_equals_strn(val, str, len);
  4108. }
  4109. return false;
  4110. }
  4111. yyjson_api bool unsafe_yyjson_equals(yyjson_val *lhs, yyjson_val *rhs);
  4112. yyjson_api_inline bool yyjson_equals(yyjson_val *lhs, yyjson_val *rhs) {
  4113. if (yyjson_unlikely(!lhs || !rhs)) return false;
  4114. return unsafe_yyjson_equals(lhs, rhs);
  4115. }
  4116. yyjson_api_inline bool yyjson_set_raw(yyjson_val *val,
  4117. const char *raw, size_t len) {
  4118. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4119. unsafe_yyjson_set_raw(val, raw, len);
  4120. return true;
  4121. }
  4122. yyjson_api_inline bool yyjson_set_null(yyjson_val *val) {
  4123. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4124. unsafe_yyjson_set_null(val);
  4125. return true;
  4126. }
  4127. yyjson_api_inline bool yyjson_set_bool(yyjson_val *val, bool num) {
  4128. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4129. unsafe_yyjson_set_bool(val, num);
  4130. return true;
  4131. }
  4132. yyjson_api_inline bool yyjson_set_uint(yyjson_val *val, uint64_t num) {
  4133. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4134. unsafe_yyjson_set_uint(val, num);
  4135. return true;
  4136. }
  4137. yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num) {
  4138. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4139. unsafe_yyjson_set_sint(val, num);
  4140. return true;
  4141. }
  4142. yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int num) {
  4143. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4144. unsafe_yyjson_set_sint(val, (int64_t)num);
  4145. return true;
  4146. }
  4147. yyjson_api_inline bool yyjson_set_real(yyjson_val *val, double num) {
  4148. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4149. unsafe_yyjson_set_real(val, num);
  4150. return true;
  4151. }
  4152. yyjson_api_inline bool yyjson_set_str(yyjson_val *val, const char *str) {
  4153. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4154. if (yyjson_unlikely(!str)) return false;
  4155. unsafe_yyjson_set_str(val, str);
  4156. return true;
  4157. }
  4158. yyjson_api_inline bool yyjson_set_strn(yyjson_val *val,
  4159. const char *str, size_t len) {
  4160. if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
  4161. if (yyjson_unlikely(!str)) return false;
  4162. unsafe_yyjson_set_strn(val, str, len);
  4163. return true;
  4164. }
  4165. /*==============================================================================
  4166. * JSON Array API (Implementation)
  4167. *============================================================================*/
  4168. yyjson_api_inline size_t yyjson_arr_size(yyjson_val *arr) {
  4169. return yyjson_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
  4170. }
  4171. yyjson_api_inline yyjson_val *yyjson_arr_get(yyjson_val *arr, size_t idx) {
  4172. if (yyjson_likely(yyjson_is_arr(arr))) {
  4173. if (yyjson_likely(unsafe_yyjson_get_len(arr) > idx)) {
  4174. yyjson_val *val = unsafe_yyjson_get_first(arr);
  4175. if (unsafe_yyjson_arr_is_flat(arr)) {
  4176. return val + idx;
  4177. } else {
  4178. while (idx-- > 0) val = unsafe_yyjson_get_next(val);
  4179. return val;
  4180. }
  4181. }
  4182. }
  4183. return NULL;
  4184. }
  4185. yyjson_api_inline yyjson_val *yyjson_arr_get_first(yyjson_val *arr) {
  4186. if (yyjson_likely(yyjson_is_arr(arr))) {
  4187. if (yyjson_likely(unsafe_yyjson_get_len(arr) > 0)) {
  4188. return unsafe_yyjson_get_first(arr);
  4189. }
  4190. }
  4191. return NULL;
  4192. }
  4193. yyjson_api_inline yyjson_val *yyjson_arr_get_last(yyjson_val *arr) {
  4194. if (yyjson_likely(yyjson_is_arr(arr))) {
  4195. size_t len = unsafe_yyjson_get_len(arr);
  4196. if (yyjson_likely(len > 0)) {
  4197. yyjson_val *val = unsafe_yyjson_get_first(arr);
  4198. if (unsafe_yyjson_arr_is_flat(arr)) {
  4199. return val + (len - 1);
  4200. } else {
  4201. while (len-- > 1) val = unsafe_yyjson_get_next(val);
  4202. return val;
  4203. }
  4204. }
  4205. }
  4206. return NULL;
  4207. }
  4208. /*==============================================================================
  4209. * JSON Array Iterator API (Implementation)
  4210. *============================================================================*/
  4211. yyjson_api_inline bool yyjson_arr_iter_init(yyjson_val *arr,
  4212. yyjson_arr_iter *iter) {
  4213. if (yyjson_likely(yyjson_is_arr(arr) && iter)) {
  4214. iter->idx = 0;
  4215. iter->max = unsafe_yyjson_get_len(arr);
  4216. iter->cur = unsafe_yyjson_get_first(arr);
  4217. return true;
  4218. }
  4219. if (iter) memset(iter, 0, sizeof(yyjson_arr_iter));
  4220. return false;
  4221. }
  4222. yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(yyjson_val *arr) {
  4223. yyjson_arr_iter iter;
  4224. yyjson_arr_iter_init(arr, &iter);
  4225. return iter;
  4226. }
  4227. yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter *iter) {
  4228. return iter ? iter->idx < iter->max : false;
  4229. }
  4230. yyjson_api_inline yyjson_val *yyjson_arr_iter_next(yyjson_arr_iter *iter) {
  4231. yyjson_val *val;
  4232. if (iter && iter->idx < iter->max) {
  4233. val = iter->cur;
  4234. iter->cur = unsafe_yyjson_get_next(val);
  4235. iter->idx++;
  4236. return val;
  4237. }
  4238. return NULL;
  4239. }
  4240. /*==============================================================================
  4241. * JSON Object API (Implementation)
  4242. *============================================================================*/
  4243. yyjson_api_inline size_t yyjson_obj_size(yyjson_val *obj) {
  4244. return yyjson_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
  4245. }
  4246. yyjson_api_inline yyjson_val *yyjson_obj_get(yyjson_val *obj,
  4247. const char *key) {
  4248. return yyjson_obj_getn(obj, key, key ? strlen(key) : 0);
  4249. }
  4250. yyjson_api_inline yyjson_val *yyjson_obj_getn(yyjson_val *obj,
  4251. const char *_key,
  4252. size_t key_len) {
  4253. if (yyjson_likely(yyjson_is_obj(obj) && _key)) {
  4254. size_t len = unsafe_yyjson_get_len(obj);
  4255. yyjson_val *key = unsafe_yyjson_get_first(obj);
  4256. while (len-- > 0) {
  4257. if (unsafe_yyjson_equals_strn(key, _key, key_len)) return key + 1;
  4258. key = unsafe_yyjson_get_next(key + 1);
  4259. }
  4260. }
  4261. return NULL;
  4262. }
  4263. /*==============================================================================
  4264. * JSON Object Iterator API (Implementation)
  4265. *============================================================================*/
  4266. yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val *obj,
  4267. yyjson_obj_iter *iter) {
  4268. if (yyjson_likely(yyjson_is_obj(obj) && iter)) {
  4269. iter->idx = 0;
  4270. iter->max = unsafe_yyjson_get_len(obj);
  4271. iter->cur = unsafe_yyjson_get_first(obj);
  4272. iter->obj = obj;
  4273. return true;
  4274. }
  4275. if (iter) memset(iter, 0, sizeof(yyjson_obj_iter));
  4276. return false;
  4277. }
  4278. yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(yyjson_val *obj) {
  4279. yyjson_obj_iter iter;
  4280. yyjson_obj_iter_init(obj, &iter);
  4281. return iter;
  4282. }
  4283. yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter *iter) {
  4284. return iter ? iter->idx < iter->max : false;
  4285. }
  4286. yyjson_api_inline yyjson_val *yyjson_obj_iter_next(yyjson_obj_iter *iter) {
  4287. if (iter && iter->idx < iter->max) {
  4288. yyjson_val *key = iter->cur;
  4289. iter->idx++;
  4290. iter->cur = unsafe_yyjson_get_next(key + 1);
  4291. return key;
  4292. }
  4293. return NULL;
  4294. }
  4295. yyjson_api_inline yyjson_val *yyjson_obj_iter_get_val(yyjson_val *key) {
  4296. return key ? key + 1 : NULL;
  4297. }
  4298. yyjson_api_inline yyjson_val *yyjson_obj_iter_get(yyjson_obj_iter *iter,
  4299. const char *key) {
  4300. return yyjson_obj_iter_getn(iter, key, key ? strlen(key) : 0);
  4301. }
  4302. yyjson_api_inline yyjson_val *yyjson_obj_iter_getn(yyjson_obj_iter *iter,
  4303. const char *key,
  4304. size_t key_len) {
  4305. if (iter && key) {
  4306. size_t idx = iter->idx;
  4307. size_t max = iter->max;
  4308. yyjson_val *cur = iter->cur;
  4309. if (yyjson_unlikely(idx == max)) {
  4310. idx = 0;
  4311. cur = unsafe_yyjson_get_first(iter->obj);
  4312. }
  4313. while (idx++ < max) {
  4314. yyjson_val *next = unsafe_yyjson_get_next(cur + 1);
  4315. if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
  4316. iter->idx = idx;
  4317. iter->cur = next;
  4318. return cur + 1;
  4319. }
  4320. cur = next;
  4321. if (idx == iter->max && iter->idx < iter->max) {
  4322. idx = 0;
  4323. max = iter->idx;
  4324. cur = unsafe_yyjson_get_first(iter->obj);
  4325. }
  4326. }
  4327. }
  4328. return NULL;
  4329. }
  4330. /*==============================================================================
  4331. * Mutable JSON Structure (Implementation)
  4332. *============================================================================*/
  4333. /**
  4334. Mutable JSON value, 24 bytes.
  4335. The 'tag' and 'uni' field is same as immutable value.
  4336. The 'next' field links all elements inside the container to be a cycle.
  4337. */
  4338. struct yyjson_mut_val {
  4339. uint64_t tag; /**< type, subtype and length */
  4340. yyjson_val_uni uni; /**< payload */
  4341. yyjson_mut_val *next; /**< the next value in circular linked list */
  4342. };
  4343. /**
  4344. A memory chunk in string memory pool.
  4345. */
  4346. typedef struct yyjson_str_chunk {
  4347. struct yyjson_str_chunk *next; /* next chunk linked list */
  4348. size_t chunk_size; /* chunk size in bytes */
  4349. /* char str[]; flexible array member */
  4350. } yyjson_str_chunk;
  4351. /**
  4352. A memory pool to hold all strings in a mutable document.
  4353. */
  4354. typedef struct yyjson_str_pool {
  4355. char *cur; /* cursor inside current chunk */
  4356. char *end; /* the end of current chunk */
  4357. size_t chunk_size; /* chunk size in bytes while creating new chunk */
  4358. size_t chunk_size_max; /* maximum chunk size in bytes */
  4359. yyjson_str_chunk *chunks; /* a linked list of chunks, nullable */
  4360. } yyjson_str_pool;
  4361. /**
  4362. A memory chunk in value memory pool.
  4363. `sizeof(yyjson_val_chunk)` should not larger than `sizeof(yyjson_mut_val)`.
  4364. */
  4365. typedef struct yyjson_val_chunk {
  4366. struct yyjson_val_chunk *next; /* next chunk linked list */
  4367. size_t chunk_size; /* chunk size in bytes */
  4368. /* char pad[sizeof(yyjson_mut_val) - sizeof(yyjson_val_chunk)]; padding */
  4369. /* yyjson_mut_val vals[]; flexible array member */
  4370. } yyjson_val_chunk;
  4371. /**
  4372. A memory pool to hold all values in a mutable document.
  4373. */
  4374. typedef struct yyjson_val_pool {
  4375. yyjson_mut_val *cur; /* cursor inside current chunk */
  4376. yyjson_mut_val *end; /* the end of current chunk */
  4377. size_t chunk_size; /* chunk size in bytes while creating new chunk */
  4378. size_t chunk_size_max; /* maximum chunk size in bytes */
  4379. yyjson_val_chunk *chunks; /* a linked list of chunks, nullable */
  4380. } yyjson_val_pool;
  4381. struct yyjson_mut_doc {
  4382. yyjson_mut_val *root; /**< root value of the JSON document, nullable */
  4383. yyjson_alc alc; /**< a valid allocator, nonnull */
  4384. yyjson_str_pool str_pool; /**< string memory pool */
  4385. yyjson_val_pool val_pool; /**< value memory pool */
  4386. };
  4387. /* Ensures the capacity to at least equal to the specified byte length. */
  4388. yyjson_api bool unsafe_yyjson_str_pool_grow(yyjson_str_pool *pool,
  4389. const yyjson_alc *alc,
  4390. size_t len);
  4391. /* Ensures the capacity to at least equal to the specified value count. */
  4392. yyjson_api bool unsafe_yyjson_val_pool_grow(yyjson_val_pool *pool,
  4393. const yyjson_alc *alc,
  4394. size_t count);
  4395. /* Allocate memory for string. */
  4396. yyjson_api_inline char *unsafe_yyjson_mut_str_alc(yyjson_mut_doc *doc,
  4397. size_t len) {
  4398. char *mem;
  4399. const yyjson_alc *alc = &doc->alc;
  4400. yyjson_str_pool *pool = &doc->str_pool;
  4401. if (yyjson_unlikely((size_t)(pool->end - pool->cur) <= len)) {
  4402. if (yyjson_unlikely(!unsafe_yyjson_str_pool_grow(pool, alc, len + 1))) {
  4403. return NULL;
  4404. }
  4405. }
  4406. mem = pool->cur;
  4407. pool->cur = mem + len + 1;
  4408. return mem;
  4409. }
  4410. yyjson_api_inline char *unsafe_yyjson_mut_strncpy(yyjson_mut_doc *doc,
  4411. const char *str, size_t len) {
  4412. char *mem = unsafe_yyjson_mut_str_alc(doc, len);
  4413. if (yyjson_unlikely(!mem)) return NULL;
  4414. memcpy((void *)mem, (const void *)str, len);
  4415. mem[len] = '\0';
  4416. return mem;
  4417. }
  4418. yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_val(yyjson_mut_doc *doc,
  4419. size_t count) {
  4420. yyjson_mut_val *val;
  4421. yyjson_alc *alc = &doc->alc;
  4422. yyjson_val_pool *pool = &doc->val_pool;
  4423. if (yyjson_unlikely((size_t)(pool->end - pool->cur) < count)) {
  4424. if (yyjson_unlikely(!unsafe_yyjson_val_pool_grow(pool, alc, count))) {
  4425. return NULL;
  4426. }
  4427. }
  4428. val = pool->cur;
  4429. pool->cur += count;
  4430. return val;
  4431. }
  4432. /*==============================================================================
  4433. * Mutable JSON Document API (Implementation)
  4434. *============================================================================*/
  4435. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_root(yyjson_mut_doc *doc) {
  4436. return doc ? doc->root : NULL;
  4437. }
  4438. yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc,
  4439. yyjson_mut_val *root) {
  4440. if (doc) doc->root = root;
  4441. }
  4442. /*==============================================================================
  4443. * Mutable JSON Value Type API (Implementation)
  4444. *============================================================================*/
  4445. yyjson_api_inline bool yyjson_mut_is_raw(yyjson_mut_val *val) {
  4446. return val ? unsafe_yyjson_is_raw(val) : false;
  4447. }
  4448. yyjson_api_inline bool yyjson_mut_is_null(yyjson_mut_val *val) {
  4449. return val ? unsafe_yyjson_is_null(val) : false;
  4450. }
  4451. yyjson_api_inline bool yyjson_mut_is_true(yyjson_mut_val *val) {
  4452. return val ? unsafe_yyjson_is_true(val) : false;
  4453. }
  4454. yyjson_api_inline bool yyjson_mut_is_false(yyjson_mut_val *val) {
  4455. return val ? unsafe_yyjson_is_false(val) : false;
  4456. }
  4457. yyjson_api_inline bool yyjson_mut_is_bool(yyjson_mut_val *val) {
  4458. return val ? unsafe_yyjson_is_bool(val) : false;
  4459. }
  4460. yyjson_api_inline bool yyjson_mut_is_uint(yyjson_mut_val *val) {
  4461. return val ? unsafe_yyjson_is_uint(val) : false;
  4462. }
  4463. yyjson_api_inline bool yyjson_mut_is_sint(yyjson_mut_val *val) {
  4464. return val ? unsafe_yyjson_is_sint(val) : false;
  4465. }
  4466. yyjson_api_inline bool yyjson_mut_is_int(yyjson_mut_val *val) {
  4467. return val ? unsafe_yyjson_is_int(val) : false;
  4468. }
  4469. yyjson_api_inline bool yyjson_mut_is_real(yyjson_mut_val *val) {
  4470. return val ? unsafe_yyjson_is_real(val) : false;
  4471. }
  4472. yyjson_api_inline bool yyjson_mut_is_num(yyjson_mut_val *val) {
  4473. return val ? unsafe_yyjson_is_num(val) : false;
  4474. }
  4475. yyjson_api_inline bool yyjson_mut_is_str(yyjson_mut_val *val) {
  4476. return val ? unsafe_yyjson_is_str(val) : false;
  4477. }
  4478. yyjson_api_inline bool yyjson_mut_is_arr(yyjson_mut_val *val) {
  4479. return val ? unsafe_yyjson_is_arr(val) : false;
  4480. }
  4481. yyjson_api_inline bool yyjson_mut_is_obj(yyjson_mut_val *val) {
  4482. return val ? unsafe_yyjson_is_obj(val) : false;
  4483. }
  4484. yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val *val) {
  4485. return val ? unsafe_yyjson_is_ctn(val) : false;
  4486. }
  4487. /*==============================================================================
  4488. * Mutable JSON Value Content API (Implementation)
  4489. *============================================================================*/
  4490. yyjson_api_inline yyjson_type yyjson_mut_get_type(yyjson_mut_val *val) {
  4491. return yyjson_get_type((yyjson_val *)val);
  4492. }
  4493. yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(yyjson_mut_val *val) {
  4494. return yyjson_get_subtype((yyjson_val *)val);
  4495. }
  4496. yyjson_api_inline uint8_t yyjson_mut_get_tag(yyjson_mut_val *val) {
  4497. return yyjson_get_tag((yyjson_val *)val);
  4498. }
  4499. yyjson_api_inline const char *yyjson_mut_get_type_desc(yyjson_mut_val *val) {
  4500. return yyjson_get_type_desc((yyjson_val *)val);
  4501. }
  4502. yyjson_api_inline const char *yyjson_mut_get_raw(yyjson_mut_val *val) {
  4503. return yyjson_get_raw((yyjson_val *)val);
  4504. }
  4505. yyjson_api_inline bool yyjson_mut_get_bool(yyjson_mut_val *val) {
  4506. return yyjson_get_bool((yyjson_val *)val);
  4507. }
  4508. yyjson_api_inline uint64_t yyjson_mut_get_uint(yyjson_mut_val *val) {
  4509. return yyjson_get_uint((yyjson_val *)val);
  4510. }
  4511. yyjson_api_inline int64_t yyjson_mut_get_sint(yyjson_mut_val *val) {
  4512. return yyjson_get_sint((yyjson_val *)val);
  4513. }
  4514. yyjson_api_inline int yyjson_mut_get_int(yyjson_mut_val *val) {
  4515. return yyjson_get_int((yyjson_val *)val);
  4516. }
  4517. yyjson_api_inline double yyjson_mut_get_real(yyjson_mut_val *val) {
  4518. return yyjson_get_real((yyjson_val *)val);
  4519. }
  4520. yyjson_api_inline double yyjson_mut_get_num(yyjson_mut_val *val) {
  4521. return yyjson_get_num((yyjson_val *)val);
  4522. }
  4523. yyjson_api_inline const char *yyjson_mut_get_str(yyjson_mut_val *val) {
  4524. return yyjson_get_str((yyjson_val *)val);
  4525. }
  4526. yyjson_api_inline size_t yyjson_mut_get_len(yyjson_mut_val *val) {
  4527. return yyjson_get_len((yyjson_val *)val);
  4528. }
  4529. yyjson_api_inline bool yyjson_mut_equals_str(yyjson_mut_val *val,
  4530. const char *str) {
  4531. return yyjson_equals_str((yyjson_val *)val, str);
  4532. }
  4533. yyjson_api_inline bool yyjson_mut_equals_strn(yyjson_mut_val *val,
  4534. const char *str, size_t len) {
  4535. return yyjson_equals_strn((yyjson_val *)val, str, len);
  4536. }
  4537. yyjson_api bool unsafe_yyjson_mut_equals(yyjson_mut_val *lhs,
  4538. yyjson_mut_val *rhs);
  4539. yyjson_api_inline bool yyjson_mut_equals(yyjson_mut_val *lhs,
  4540. yyjson_mut_val *rhs) {
  4541. if (yyjson_unlikely(!lhs || !rhs)) return false;
  4542. return unsafe_yyjson_mut_equals(lhs, rhs);
  4543. }
  4544. yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val *val,
  4545. const char *raw, size_t len) {
  4546. if (yyjson_unlikely(!val || !raw)) return false;
  4547. unsafe_yyjson_set_raw(val, raw, len);
  4548. return true;
  4549. }
  4550. yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val *val) {
  4551. if (yyjson_unlikely(!val)) return false;
  4552. unsafe_yyjson_set_null(val);
  4553. return true;
  4554. }
  4555. yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val *val, bool num) {
  4556. if (yyjson_unlikely(!val)) return false;
  4557. unsafe_yyjson_set_bool(val, num);
  4558. return true;
  4559. }
  4560. yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val *val, uint64_t num) {
  4561. if (yyjson_unlikely(!val)) return false;
  4562. unsafe_yyjson_set_uint(val, num);
  4563. return true;
  4564. }
  4565. yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num) {
  4566. if (yyjson_unlikely(!val)) return false;
  4567. unsafe_yyjson_set_sint(val, num);
  4568. return true;
  4569. }
  4570. yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int num) {
  4571. if (yyjson_unlikely(!val)) return false;
  4572. unsafe_yyjson_set_sint(val, (int64_t)num);
  4573. return true;
  4574. }
  4575. yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val *val, double num) {
  4576. if (yyjson_unlikely(!val)) return false;
  4577. unsafe_yyjson_set_real(val, num);
  4578. return true;
  4579. }
  4580. yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val *val,
  4581. const char *str) {
  4582. if (yyjson_unlikely(!val || !str)) return false;
  4583. unsafe_yyjson_set_str(val, str);
  4584. return true;
  4585. }
  4586. yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val *val,
  4587. const char *str, size_t len) {
  4588. if (yyjson_unlikely(!val || !str)) return false;
  4589. unsafe_yyjson_set_strn(val, str, len);
  4590. return true;
  4591. }
  4592. yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val *val) {
  4593. if (yyjson_unlikely(!val)) return false;
  4594. unsafe_yyjson_set_arr(val, 0);
  4595. return true;
  4596. }
  4597. yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val) {
  4598. if (yyjson_unlikely(!val)) return false;
  4599. unsafe_yyjson_set_obj(val, 0);
  4600. return true;
  4601. }
  4602. /*==============================================================================
  4603. * Mutable JSON Value Creation API (Implementation)
  4604. *============================================================================*/
  4605. yyjson_api_inline yyjson_mut_val *yyjson_mut_raw(yyjson_mut_doc *doc,
  4606. const char *str) {
  4607. if (yyjson_likely(str)) return yyjson_mut_rawn(doc, str, strlen(str));
  4608. return NULL;
  4609. }
  4610. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawn(yyjson_mut_doc *doc,
  4611. const char *str,
  4612. size_t len) {
  4613. if (yyjson_likely(doc && str)) {
  4614. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4615. if (yyjson_likely(val)) {
  4616. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_RAW;
  4617. val->uni.str = str;
  4618. return val;
  4619. }
  4620. }
  4621. return NULL;
  4622. }
  4623. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawcpy(yyjson_mut_doc *doc,
  4624. const char *str) {
  4625. if (yyjson_likely(str)) return yyjson_mut_rawncpy(doc, str, strlen(str));
  4626. return NULL;
  4627. }
  4628. yyjson_api_inline yyjson_mut_val *yyjson_mut_rawncpy(yyjson_mut_doc *doc,
  4629. const char *str,
  4630. size_t len) {
  4631. if (yyjson_likely(doc && str)) {
  4632. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4633. char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
  4634. if (yyjson_likely(val && new_str)) {
  4635. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_RAW;
  4636. val->uni.str = new_str;
  4637. return val;
  4638. }
  4639. }
  4640. return NULL;
  4641. }
  4642. yyjson_api_inline yyjson_mut_val *yyjson_mut_null(yyjson_mut_doc *doc) {
  4643. if (yyjson_likely(doc)) {
  4644. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4645. if (yyjson_likely(val)) {
  4646. val->tag = YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE;
  4647. return val;
  4648. }
  4649. }
  4650. return NULL;
  4651. }
  4652. yyjson_api_inline yyjson_mut_val *yyjson_mut_true(yyjson_mut_doc *doc) {
  4653. if (yyjson_likely(doc)) {
  4654. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4655. if (yyjson_likely(val)) {
  4656. val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
  4657. return val;
  4658. }
  4659. }
  4660. return NULL;
  4661. }
  4662. yyjson_api_inline yyjson_mut_val *yyjson_mut_false(yyjson_mut_doc *doc) {
  4663. if (yyjson_likely(doc)) {
  4664. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4665. if (yyjson_likely(val)) {
  4666. val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
  4667. return val;
  4668. }
  4669. }
  4670. return NULL;
  4671. }
  4672. yyjson_api_inline yyjson_mut_val *yyjson_mut_bool(yyjson_mut_doc *doc,
  4673. bool _val) {
  4674. if (yyjson_likely(doc)) {
  4675. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4676. if (yyjson_likely(val)) {
  4677. val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3);
  4678. return val;
  4679. }
  4680. }
  4681. return NULL;
  4682. }
  4683. yyjson_api_inline yyjson_mut_val *yyjson_mut_uint(yyjson_mut_doc *doc,
  4684. uint64_t num) {
  4685. if (yyjson_likely(doc)) {
  4686. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4687. if (yyjson_likely(val)) {
  4688. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  4689. val->uni.u64 = num;
  4690. return val;
  4691. }
  4692. }
  4693. return NULL;
  4694. }
  4695. yyjson_api_inline yyjson_mut_val *yyjson_mut_sint(yyjson_mut_doc *doc,
  4696. int64_t num) {
  4697. if (yyjson_likely(doc)) {
  4698. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4699. if (yyjson_likely(val)) {
  4700. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  4701. val->uni.i64 = num;
  4702. return val;
  4703. }
  4704. }
  4705. return NULL;
  4706. }
  4707. yyjson_api_inline yyjson_mut_val *yyjson_mut_int(yyjson_mut_doc *doc,
  4708. int64_t num) {
  4709. return yyjson_mut_sint(doc, num);
  4710. }
  4711. yyjson_api_inline yyjson_mut_val *yyjson_mut_real(yyjson_mut_doc *doc,
  4712. double num) {
  4713. if (yyjson_likely(doc)) {
  4714. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4715. if (yyjson_likely(val)) {
  4716. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
  4717. val->uni.f64 = num;
  4718. return val;
  4719. }
  4720. }
  4721. return NULL;
  4722. }
  4723. yyjson_api_inline yyjson_mut_val *yyjson_mut_str(yyjson_mut_doc *doc,
  4724. const char *str) {
  4725. if (yyjson_likely(doc && str)) {
  4726. size_t len = strlen(str);
  4727. bool noesc = unsafe_yyjson_is_str_noesc(str, len);
  4728. yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
  4729. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4730. if (yyjson_likely(val)) {
  4731. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) |
  4732. (uint64_t)(YYJSON_TYPE_STR | sub);
  4733. val->uni.str = str;
  4734. return val;
  4735. }
  4736. }
  4737. return NULL;
  4738. }
  4739. yyjson_api_inline yyjson_mut_val *yyjson_mut_strn(yyjson_mut_doc *doc,
  4740. const char *str,
  4741. size_t len) {
  4742. if (yyjson_likely(doc && str)) {
  4743. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4744. if (yyjson_likely(val)) {
  4745. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  4746. val->uni.str = str;
  4747. return val;
  4748. }
  4749. }
  4750. return NULL;
  4751. }
  4752. yyjson_api_inline yyjson_mut_val *yyjson_mut_strcpy(yyjson_mut_doc *doc,
  4753. const char *str) {
  4754. if (yyjson_likely(doc && str)) {
  4755. size_t len = strlen(str);
  4756. bool noesc = unsafe_yyjson_is_str_noesc(str, len);
  4757. yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
  4758. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4759. char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
  4760. if (yyjson_likely(val && new_str)) {
  4761. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) |
  4762. (uint64_t)(YYJSON_TYPE_STR | sub);
  4763. val->uni.str = new_str;
  4764. return val;
  4765. }
  4766. }
  4767. return NULL;
  4768. }
  4769. yyjson_api_inline yyjson_mut_val *yyjson_mut_strncpy(yyjson_mut_doc *doc,
  4770. const char *str,
  4771. size_t len) {
  4772. if (yyjson_likely(doc && str)) {
  4773. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4774. char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
  4775. if (yyjson_likely(val && new_str)) {
  4776. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  4777. val->uni.str = new_str;
  4778. return val;
  4779. }
  4780. }
  4781. return NULL;
  4782. }
  4783. /*==============================================================================
  4784. * Mutable JSON Array API (Implementation)
  4785. *============================================================================*/
  4786. yyjson_api_inline size_t yyjson_mut_arr_size(yyjson_mut_val *arr) {
  4787. return yyjson_mut_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
  4788. }
  4789. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get(yyjson_mut_val *arr,
  4790. size_t idx) {
  4791. if (yyjson_likely(idx < yyjson_mut_arr_size(arr))) {
  4792. yyjson_mut_val *val = (yyjson_mut_val *)arr->uni.ptr;
  4793. while (idx-- > 0) val = val->next;
  4794. return val->next;
  4795. }
  4796. return NULL;
  4797. }
  4798. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_first(
  4799. yyjson_mut_val *arr) {
  4800. if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
  4801. return ((yyjson_mut_val *)arr->uni.ptr)->next;
  4802. }
  4803. return NULL;
  4804. }
  4805. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_last(
  4806. yyjson_mut_val *arr) {
  4807. if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
  4808. return ((yyjson_mut_val *)arr->uni.ptr);
  4809. }
  4810. return NULL;
  4811. }
  4812. /*==============================================================================
  4813. * Mutable JSON Array Iterator API (Implementation)
  4814. *============================================================================*/
  4815. yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val *arr,
  4816. yyjson_mut_arr_iter *iter) {
  4817. if (yyjson_likely(yyjson_mut_is_arr(arr) && iter)) {
  4818. iter->idx = 0;
  4819. iter->max = unsafe_yyjson_get_len(arr);
  4820. iter->cur = iter->max ? (yyjson_mut_val *)arr->uni.ptr : NULL;
  4821. iter->pre = NULL;
  4822. iter->arr = arr;
  4823. return true;
  4824. }
  4825. if (iter) memset(iter, 0, sizeof(yyjson_mut_arr_iter));
  4826. return false;
  4827. }
  4828. yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(
  4829. yyjson_mut_val *arr) {
  4830. yyjson_mut_arr_iter iter;
  4831. yyjson_mut_arr_iter_init(arr, &iter);
  4832. return iter;
  4833. }
  4834. yyjson_api_inline bool yyjson_mut_arr_iter_has_next(yyjson_mut_arr_iter *iter) {
  4835. return iter ? iter->idx < iter->max : false;
  4836. }
  4837. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_next(
  4838. yyjson_mut_arr_iter *iter) {
  4839. if (iter && iter->idx < iter->max) {
  4840. yyjson_mut_val *val = iter->cur;
  4841. iter->pre = val;
  4842. iter->cur = val->next;
  4843. iter->idx++;
  4844. return iter->cur;
  4845. }
  4846. return NULL;
  4847. }
  4848. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_remove(
  4849. yyjson_mut_arr_iter *iter) {
  4850. if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
  4851. yyjson_mut_val *prev = iter->pre;
  4852. yyjson_mut_val *cur = iter->cur;
  4853. yyjson_mut_val *next = cur->next;
  4854. if (yyjson_unlikely(iter->idx == iter->max)) iter->arr->uni.ptr = prev;
  4855. iter->idx--;
  4856. iter->max--;
  4857. unsafe_yyjson_set_len(iter->arr, iter->max);
  4858. prev->next = next;
  4859. iter->cur = next;
  4860. return cur;
  4861. }
  4862. return NULL;
  4863. }
  4864. /*==============================================================================
  4865. * Mutable JSON Array Creation API (Implementation)
  4866. *============================================================================*/
  4867. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc) {
  4868. if (yyjson_likely(doc)) {
  4869. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  4870. if (yyjson_likely(val)) {
  4871. val->tag = YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE;
  4872. return val;
  4873. }
  4874. }
  4875. return NULL;
  4876. }
  4877. #define yyjson_mut_arr_with_func(func) \
  4878. if (yyjson_likely(doc && ((0 < count && count < \
  4879. (~(size_t)0) / sizeof(yyjson_mut_val) && vals) || count == 0))) { \
  4880. yyjson_mut_val *arr = unsafe_yyjson_mut_val(doc, 1 + count); \
  4881. if (yyjson_likely(arr)) { \
  4882. arr->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_ARR; \
  4883. if (count > 0) { \
  4884. size_t i; \
  4885. for (i = 0; i < count; i++) { \
  4886. yyjson_mut_val *val = arr + i + 1; \
  4887. func \
  4888. val->next = val + 1; \
  4889. } \
  4890. arr[count].next = arr + 1; \
  4891. arr->uni.ptr = arr + count; \
  4892. } \
  4893. return arr; \
  4894. } \
  4895. } \
  4896. return NULL
  4897. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_bool(
  4898. yyjson_mut_doc *doc, const bool *vals, size_t count) {
  4899. yyjson_mut_arr_with_func({
  4900. val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)vals[i] << 3);
  4901. });
  4902. }
  4903. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint(
  4904. yyjson_mut_doc *doc, const int64_t *vals, size_t count) {
  4905. return yyjson_mut_arr_with_sint64(doc, vals, count);
  4906. }
  4907. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint(
  4908. yyjson_mut_doc *doc, const uint64_t *vals, size_t count) {
  4909. return yyjson_mut_arr_with_uint64(doc, vals, count);
  4910. }
  4911. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_real(
  4912. yyjson_mut_doc *doc, const double *vals, size_t count) {
  4913. return yyjson_mut_arr_with_double(doc, vals, count);
  4914. }
  4915. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint8(
  4916. yyjson_mut_doc *doc, const int8_t *vals, size_t count) {
  4917. yyjson_mut_arr_with_func({
  4918. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  4919. val->uni.i64 = (int64_t)vals[i];
  4920. });
  4921. }
  4922. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint16(
  4923. yyjson_mut_doc *doc, const int16_t *vals, size_t count) {
  4924. yyjson_mut_arr_with_func({
  4925. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  4926. val->uni.i64 = vals[i];
  4927. });
  4928. }
  4929. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint32(
  4930. yyjson_mut_doc *doc, const int32_t *vals, size_t count) {
  4931. yyjson_mut_arr_with_func({
  4932. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  4933. val->uni.i64 = vals[i];
  4934. });
  4935. }
  4936. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint64(
  4937. yyjson_mut_doc *doc, const int64_t *vals, size_t count) {
  4938. yyjson_mut_arr_with_func({
  4939. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  4940. val->uni.i64 = vals[i];
  4941. });
  4942. }
  4943. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint8(
  4944. yyjson_mut_doc *doc, const uint8_t *vals, size_t count) {
  4945. yyjson_mut_arr_with_func({
  4946. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  4947. val->uni.u64 = vals[i];
  4948. });
  4949. }
  4950. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint16(
  4951. yyjson_mut_doc *doc, const uint16_t *vals, size_t count) {
  4952. yyjson_mut_arr_with_func({
  4953. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  4954. val->uni.u64 = vals[i];
  4955. });
  4956. }
  4957. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint32(
  4958. yyjson_mut_doc *doc, const uint32_t *vals, size_t count) {
  4959. yyjson_mut_arr_with_func({
  4960. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  4961. val->uni.u64 = vals[i];
  4962. });
  4963. }
  4964. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint64(
  4965. yyjson_mut_doc *doc, const uint64_t *vals, size_t count) {
  4966. yyjson_mut_arr_with_func({
  4967. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  4968. val->uni.u64 = vals[i];
  4969. });
  4970. }
  4971. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_float(
  4972. yyjson_mut_doc *doc, const float *vals, size_t count) {
  4973. yyjson_mut_arr_with_func({
  4974. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
  4975. val->uni.f64 = (double)vals[i];
  4976. });
  4977. }
  4978. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_double(
  4979. yyjson_mut_doc *doc, const double *vals, size_t count) {
  4980. yyjson_mut_arr_with_func({
  4981. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
  4982. val->uni.f64 = vals[i];
  4983. });
  4984. }
  4985. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_str(
  4986. yyjson_mut_doc *doc, const char **vals, size_t count) {
  4987. yyjson_mut_arr_with_func({
  4988. uint64_t len = (uint64_t)strlen(vals[i]);
  4989. val->tag = (len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  4990. val->uni.str = vals[i];
  4991. if (yyjson_unlikely(!val->uni.str)) return NULL;
  4992. });
  4993. }
  4994. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strn(
  4995. yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count) {
  4996. if (yyjson_unlikely(count > 0 && !lens)) return NULL;
  4997. yyjson_mut_arr_with_func({
  4998. val->tag = ((uint64_t)lens[i] << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  4999. val->uni.str = vals[i];
  5000. if (yyjson_unlikely(!val->uni.str)) return NULL;
  5001. });
  5002. }
  5003. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strcpy(
  5004. yyjson_mut_doc *doc, const char **vals, size_t count) {
  5005. size_t len;
  5006. const char *str;
  5007. yyjson_mut_arr_with_func({
  5008. str = vals[i];
  5009. if (!str) return NULL;
  5010. len = strlen(str);
  5011. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5012. val->uni.str = unsafe_yyjson_mut_strncpy(doc, str, len);
  5013. if (yyjson_unlikely(!val->uni.str)) return NULL;
  5014. });
  5015. }
  5016. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strncpy(
  5017. yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count) {
  5018. size_t len;
  5019. const char *str;
  5020. if (yyjson_unlikely(count > 0 && !lens)) return NULL;
  5021. yyjson_mut_arr_with_func({
  5022. str = vals[i];
  5023. len = lens[i];
  5024. val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5025. val->uni.str = unsafe_yyjson_mut_strncpy(doc, str, len);
  5026. if (yyjson_unlikely(!val->uni.str)) return NULL;
  5027. });
  5028. }
  5029. #undef yyjson_mut_arr_with_func
  5030. /*==============================================================================
  5031. * Mutable JSON Array Modification API (Implementation)
  5032. *============================================================================*/
  5033. yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val *arr,
  5034. yyjson_mut_val *val, size_t idx) {
  5035. if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
  5036. size_t len = unsafe_yyjson_get_len(arr);
  5037. if (yyjson_likely(idx <= len)) {
  5038. unsafe_yyjson_set_len(arr, len + 1);
  5039. if (len == 0) {
  5040. val->next = val;
  5041. arr->uni.ptr = val;
  5042. } else {
  5043. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5044. yyjson_mut_val *next = prev->next;
  5045. if (idx == len) {
  5046. prev->next = val;
  5047. val->next = next;
  5048. arr->uni.ptr = val;
  5049. } else {
  5050. while (idx-- > 0) {
  5051. prev = next;
  5052. next = next->next;
  5053. }
  5054. prev->next = val;
  5055. val->next = next;
  5056. }
  5057. }
  5058. return true;
  5059. }
  5060. }
  5061. return false;
  5062. }
  5063. yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val *arr,
  5064. yyjson_mut_val *val) {
  5065. if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
  5066. size_t len = unsafe_yyjson_get_len(arr);
  5067. unsafe_yyjson_set_len(arr, len + 1);
  5068. if (len == 0) {
  5069. val->next = val;
  5070. } else {
  5071. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5072. yyjson_mut_val *next = prev->next;
  5073. prev->next = val;
  5074. val->next = next;
  5075. }
  5076. arr->uni.ptr = val;
  5077. return true;
  5078. }
  5079. return false;
  5080. }
  5081. yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val *arr,
  5082. yyjson_mut_val *val) {
  5083. if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
  5084. size_t len = unsafe_yyjson_get_len(arr);
  5085. unsafe_yyjson_set_len(arr, len + 1);
  5086. if (len == 0) {
  5087. val->next = val;
  5088. arr->uni.ptr = val;
  5089. } else {
  5090. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5091. yyjson_mut_val *next = prev->next;
  5092. prev->next = val;
  5093. val->next = next;
  5094. }
  5095. return true;
  5096. }
  5097. return false;
  5098. }
  5099. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_replace(yyjson_mut_val *arr,
  5100. size_t idx,
  5101. yyjson_mut_val *val) {
  5102. if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
  5103. size_t len = unsafe_yyjson_get_len(arr);
  5104. if (yyjson_likely(idx < len)) {
  5105. if (yyjson_likely(len > 1)) {
  5106. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5107. yyjson_mut_val *next = prev->next;
  5108. while (idx-- > 0) {
  5109. prev = next;
  5110. next = next->next;
  5111. }
  5112. prev->next = val;
  5113. val->next = next->next;
  5114. if ((void *)next == arr->uni.ptr) arr->uni.ptr = val;
  5115. return next;
  5116. } else {
  5117. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5118. val->next = val;
  5119. arr->uni.ptr = val;
  5120. return prev;
  5121. }
  5122. }
  5123. }
  5124. return NULL;
  5125. }
  5126. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove(yyjson_mut_val *arr,
  5127. size_t idx) {
  5128. if (yyjson_likely(yyjson_mut_is_arr(arr))) {
  5129. size_t len = unsafe_yyjson_get_len(arr);
  5130. if (yyjson_likely(idx < len)) {
  5131. unsafe_yyjson_set_len(arr, len - 1);
  5132. if (yyjson_likely(len > 1)) {
  5133. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5134. yyjson_mut_val *next = prev->next;
  5135. while (idx-- > 0) {
  5136. prev = next;
  5137. next = next->next;
  5138. }
  5139. prev->next = next->next;
  5140. if ((void *)next == arr->uni.ptr) arr->uni.ptr = prev;
  5141. return next;
  5142. } else {
  5143. return ((yyjson_mut_val *)arr->uni.ptr);
  5144. }
  5145. }
  5146. }
  5147. return NULL;
  5148. }
  5149. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_first(
  5150. yyjson_mut_val *arr) {
  5151. if (yyjson_likely(yyjson_mut_is_arr(arr))) {
  5152. size_t len = unsafe_yyjson_get_len(arr);
  5153. if (len > 1) {
  5154. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5155. yyjson_mut_val *next = prev->next;
  5156. prev->next = next->next;
  5157. unsafe_yyjson_set_len(arr, len - 1);
  5158. return next;
  5159. } else if (len == 1) {
  5160. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5161. unsafe_yyjson_set_len(arr, 0);
  5162. return prev;
  5163. }
  5164. }
  5165. return NULL;
  5166. }
  5167. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_last(
  5168. yyjson_mut_val *arr) {
  5169. if (yyjson_likely(yyjson_mut_is_arr(arr))) {
  5170. size_t len = unsafe_yyjson_get_len(arr);
  5171. if (yyjson_likely(len > 1)) {
  5172. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5173. yyjson_mut_val *next = prev->next;
  5174. unsafe_yyjson_set_len(arr, len - 1);
  5175. while (--len > 0) prev = prev->next;
  5176. prev->next = next;
  5177. next = (yyjson_mut_val *)arr->uni.ptr;
  5178. arr->uni.ptr = prev;
  5179. return next;
  5180. } else if (len == 1) {
  5181. yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
  5182. unsafe_yyjson_set_len(arr, 0);
  5183. return prev;
  5184. }
  5185. }
  5186. return NULL;
  5187. }
  5188. yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val *arr,
  5189. size_t _idx, size_t _len) {
  5190. if (yyjson_likely(yyjson_mut_is_arr(arr))) {
  5191. yyjson_mut_val *prev, *next;
  5192. bool tail_removed;
  5193. size_t len = unsafe_yyjson_get_len(arr);
  5194. if (yyjson_unlikely(_idx + _len > len)) return false;
  5195. if (yyjson_unlikely(_len == 0)) return true;
  5196. unsafe_yyjson_set_len(arr, len - _len);
  5197. if (yyjson_unlikely(len == _len)) return true;
  5198. tail_removed = (_idx + _len == len);
  5199. prev = ((yyjson_mut_val *)arr->uni.ptr);
  5200. while (_idx-- > 0) prev = prev->next;
  5201. next = prev->next;
  5202. while (_len-- > 0) next = next->next;
  5203. prev->next = next;
  5204. if (yyjson_unlikely(tail_removed)) arr->uni.ptr = prev;
  5205. return true;
  5206. }
  5207. return false;
  5208. }
  5209. yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val *arr) {
  5210. if (yyjson_likely(yyjson_mut_is_arr(arr))) {
  5211. unsafe_yyjson_set_len(arr, 0);
  5212. return true;
  5213. }
  5214. return false;
  5215. }
  5216. yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr,
  5217. size_t idx) {
  5218. if (yyjson_likely(yyjson_mut_is_arr(arr) &&
  5219. unsafe_yyjson_get_len(arr) > idx)) {
  5220. yyjson_mut_val *val = (yyjson_mut_val *)arr->uni.ptr;
  5221. while (idx-- > 0) val = val->next;
  5222. arr->uni.ptr = (void *)val;
  5223. return true;
  5224. }
  5225. return false;
  5226. }
  5227. /*==============================================================================
  5228. * Mutable JSON Array Modification Convenience API (Implementation)
  5229. *============================================================================*/
  5230. yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val *arr,
  5231. yyjson_mut_val *val) {
  5232. return yyjson_mut_arr_append(arr, val);
  5233. }
  5234. yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc *doc,
  5235. yyjson_mut_val *arr) {
  5236. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5237. yyjson_mut_val *val = yyjson_mut_null(doc);
  5238. return yyjson_mut_arr_append(arr, val);
  5239. }
  5240. return false;
  5241. }
  5242. yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc *doc,
  5243. yyjson_mut_val *arr) {
  5244. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5245. yyjson_mut_val *val = yyjson_mut_true(doc);
  5246. return yyjson_mut_arr_append(arr, val);
  5247. }
  5248. return false;
  5249. }
  5250. yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc *doc,
  5251. yyjson_mut_val *arr) {
  5252. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5253. yyjson_mut_val *val = yyjson_mut_false(doc);
  5254. return yyjson_mut_arr_append(arr, val);
  5255. }
  5256. return false;
  5257. }
  5258. yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc *doc,
  5259. yyjson_mut_val *arr,
  5260. bool _val) {
  5261. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5262. yyjson_mut_val *val = yyjson_mut_bool(doc, _val);
  5263. return yyjson_mut_arr_append(arr, val);
  5264. }
  5265. return false;
  5266. }
  5267. yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc *doc,
  5268. yyjson_mut_val *arr,
  5269. uint64_t num) {
  5270. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5271. yyjson_mut_val *val = yyjson_mut_uint(doc, num);
  5272. return yyjson_mut_arr_append(arr, val);
  5273. }
  5274. return false;
  5275. }
  5276. yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc *doc,
  5277. yyjson_mut_val *arr,
  5278. int64_t num) {
  5279. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5280. yyjson_mut_val *val = yyjson_mut_sint(doc, num);
  5281. return yyjson_mut_arr_append(arr, val);
  5282. }
  5283. return false;
  5284. }
  5285. yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc *doc,
  5286. yyjson_mut_val *arr,
  5287. int64_t num) {
  5288. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5289. yyjson_mut_val *val = yyjson_mut_sint(doc, num);
  5290. return yyjson_mut_arr_append(arr, val);
  5291. }
  5292. return false;
  5293. }
  5294. yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc *doc,
  5295. yyjson_mut_val *arr,
  5296. double num) {
  5297. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5298. yyjson_mut_val *val = yyjson_mut_real(doc, num);
  5299. return yyjson_mut_arr_append(arr, val);
  5300. }
  5301. return false;
  5302. }
  5303. yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc *doc,
  5304. yyjson_mut_val *arr,
  5305. const char *str) {
  5306. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5307. yyjson_mut_val *val = yyjson_mut_str(doc, str);
  5308. return yyjson_mut_arr_append(arr, val);
  5309. }
  5310. return false;
  5311. }
  5312. yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc *doc,
  5313. yyjson_mut_val *arr,
  5314. const char *str, size_t len) {
  5315. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5316. yyjson_mut_val *val = yyjson_mut_strn(doc, str, len);
  5317. return yyjson_mut_arr_append(arr, val);
  5318. }
  5319. return false;
  5320. }
  5321. yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc *doc,
  5322. yyjson_mut_val *arr,
  5323. const char *str) {
  5324. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5325. yyjson_mut_val *val = yyjson_mut_strcpy(doc, str);
  5326. return yyjson_mut_arr_append(arr, val);
  5327. }
  5328. return false;
  5329. }
  5330. yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc *doc,
  5331. yyjson_mut_val *arr,
  5332. const char *str, size_t len) {
  5333. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5334. yyjson_mut_val *val = yyjson_mut_strncpy(doc, str, len);
  5335. return yyjson_mut_arr_append(arr, val);
  5336. }
  5337. return false;
  5338. }
  5339. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_arr(yyjson_mut_doc *doc,
  5340. yyjson_mut_val *arr) {
  5341. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5342. yyjson_mut_val *val = yyjson_mut_arr(doc);
  5343. return yyjson_mut_arr_append(arr, val) ? val : NULL;
  5344. }
  5345. return NULL;
  5346. }
  5347. yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_obj(yyjson_mut_doc *doc,
  5348. yyjson_mut_val *arr) {
  5349. if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
  5350. yyjson_mut_val *val = yyjson_mut_obj(doc);
  5351. return yyjson_mut_arr_append(arr, val) ? val : NULL;
  5352. }
  5353. return NULL;
  5354. }
  5355. /*==============================================================================
  5356. * Mutable JSON Object API (Implementation)
  5357. *============================================================================*/
  5358. yyjson_api_inline size_t yyjson_mut_obj_size(yyjson_mut_val *obj) {
  5359. return yyjson_mut_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
  5360. }
  5361. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_get(yyjson_mut_val *obj,
  5362. const char *key) {
  5363. return yyjson_mut_obj_getn(obj, key, key ? strlen(key) : 0);
  5364. }
  5365. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_getn(yyjson_mut_val *obj,
  5366. const char *_key,
  5367. size_t key_len) {
  5368. size_t len = yyjson_mut_obj_size(obj);
  5369. if (yyjson_likely(len && _key)) {
  5370. yyjson_mut_val *key = ((yyjson_mut_val *)obj->uni.ptr)->next->next;
  5371. while (len-- > 0) {
  5372. if (unsafe_yyjson_equals_strn(key, _key, key_len)) return key->next;
  5373. key = key->next->next;
  5374. }
  5375. }
  5376. return NULL;
  5377. }
  5378. /*==============================================================================
  5379. * Mutable JSON Object Iterator API (Implementation)
  5380. *============================================================================*/
  5381. yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj,
  5382. yyjson_mut_obj_iter *iter) {
  5383. if (yyjson_likely(yyjson_mut_is_obj(obj) && iter)) {
  5384. iter->idx = 0;
  5385. iter->max = unsafe_yyjson_get_len(obj);
  5386. iter->cur = iter->max ? (yyjson_mut_val *)obj->uni.ptr : NULL;
  5387. iter->pre = NULL;
  5388. iter->obj = obj;
  5389. return true;
  5390. }
  5391. if (iter) memset(iter, 0, sizeof(yyjson_mut_obj_iter));
  5392. return false;
  5393. }
  5394. yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(
  5395. yyjson_mut_val *obj) {
  5396. yyjson_mut_obj_iter iter;
  5397. yyjson_mut_obj_iter_init(obj, &iter);
  5398. return iter;
  5399. }
  5400. yyjson_api_inline bool yyjson_mut_obj_iter_has_next(yyjson_mut_obj_iter *iter) {
  5401. return iter ? iter->idx < iter->max : false;
  5402. }
  5403. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_next(
  5404. yyjson_mut_obj_iter *iter) {
  5405. if (iter && iter->idx < iter->max) {
  5406. yyjson_mut_val *key = iter->cur;
  5407. iter->pre = key;
  5408. iter->cur = key->next->next;
  5409. iter->idx++;
  5410. return iter->cur;
  5411. }
  5412. return NULL;
  5413. }
  5414. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get_val(
  5415. yyjson_mut_val *key) {
  5416. return key ? key->next : NULL;
  5417. }
  5418. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_remove(
  5419. yyjson_mut_obj_iter *iter) {
  5420. if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
  5421. yyjson_mut_val *prev = iter->pre;
  5422. yyjson_mut_val *cur = iter->cur;
  5423. yyjson_mut_val *next = cur->next->next;
  5424. if (yyjson_unlikely(iter->idx == iter->max)) iter->obj->uni.ptr = prev;
  5425. iter->idx--;
  5426. iter->max--;
  5427. unsafe_yyjson_set_len(iter->obj, iter->max);
  5428. prev->next->next = next;
  5429. iter->cur = prev;
  5430. return cur->next;
  5431. }
  5432. return NULL;
  5433. }
  5434. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get(
  5435. yyjson_mut_obj_iter *iter, const char *key) {
  5436. return yyjson_mut_obj_iter_getn(iter, key, key ? strlen(key) : 0);
  5437. }
  5438. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_getn(
  5439. yyjson_mut_obj_iter *iter, const char *key, size_t key_len) {
  5440. if (iter && key) {
  5441. size_t idx = 0;
  5442. size_t max = iter->max;
  5443. yyjson_mut_val *pre, *cur = iter->cur;
  5444. while (idx++ < max) {
  5445. pre = cur;
  5446. cur = cur->next->next;
  5447. if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
  5448. iter->idx += idx;
  5449. if (iter->idx > max) iter->idx -= max + 1;
  5450. iter->pre = pre;
  5451. iter->cur = cur;
  5452. return cur->next;
  5453. }
  5454. }
  5455. }
  5456. return NULL;
  5457. }
  5458. /*==============================================================================
  5459. * Mutable JSON Object Creation API (Implementation)
  5460. *============================================================================*/
  5461. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj(yyjson_mut_doc *doc) {
  5462. if (yyjson_likely(doc)) {
  5463. yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
  5464. if (yyjson_likely(val)) {
  5465. val->tag = YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE;
  5466. return val;
  5467. }
  5468. }
  5469. return NULL;
  5470. }
  5471. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_str(yyjson_mut_doc *doc,
  5472. const char **keys,
  5473. const char **vals,
  5474. size_t count) {
  5475. if (yyjson_likely(doc && ((count > 0 && keys && vals) || (count == 0)))) {
  5476. yyjson_mut_val *obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
  5477. if (yyjson_likely(obj)) {
  5478. obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
  5479. if (count > 0) {
  5480. size_t i;
  5481. for (i = 0; i < count; i++) {
  5482. yyjson_mut_val *key = obj + (i * 2 + 1);
  5483. yyjson_mut_val *val = obj + (i * 2 + 2);
  5484. uint64_t key_len = (uint64_t)strlen(keys[i]);
  5485. uint64_t val_len = (uint64_t)strlen(vals[i]);
  5486. key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5487. val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5488. key->uni.str = keys[i];
  5489. val->uni.str = vals[i];
  5490. key->next = val;
  5491. val->next = val + 1;
  5492. }
  5493. obj[count * 2].next = obj + 1;
  5494. obj->uni.ptr = obj + (count * 2 - 1);
  5495. }
  5496. return obj;
  5497. }
  5498. }
  5499. return NULL;
  5500. }
  5501. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_kv(yyjson_mut_doc *doc,
  5502. const char **pairs,
  5503. size_t count) {
  5504. if (yyjson_likely(doc && ((count > 0 && pairs) || (count == 0)))) {
  5505. yyjson_mut_val *obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
  5506. if (yyjson_likely(obj)) {
  5507. obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
  5508. if (count > 0) {
  5509. size_t i;
  5510. for (i = 0; i < count; i++) {
  5511. yyjson_mut_val *key = obj + (i * 2 + 1);
  5512. yyjson_mut_val *val = obj + (i * 2 + 2);
  5513. const char *key_str = pairs[i * 2 + 0];
  5514. const char *val_str = pairs[i * 2 + 1];
  5515. uint64_t key_len = (uint64_t)strlen(key_str);
  5516. uint64_t val_len = (uint64_t)strlen(val_str);
  5517. key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5518. val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5519. key->uni.str = key_str;
  5520. val->uni.str = val_str;
  5521. key->next = val;
  5522. val->next = val + 1;
  5523. }
  5524. obj[count * 2].next = obj + 1;
  5525. obj->uni.ptr = obj + (count * 2 - 1);
  5526. }
  5527. return obj;
  5528. }
  5529. }
  5530. return NULL;
  5531. }
  5532. /*==============================================================================
  5533. * Mutable JSON Object Modification API (Implementation)
  5534. *============================================================================*/
  5535. yyjson_api_inline void unsafe_yyjson_mut_obj_add(yyjson_mut_val *obj,
  5536. yyjson_mut_val *key,
  5537. yyjson_mut_val *val,
  5538. size_t len) {
  5539. if (yyjson_likely(len)) {
  5540. yyjson_mut_val *prev_val = ((yyjson_mut_val *)obj->uni.ptr)->next;
  5541. yyjson_mut_val *next_key = prev_val->next;
  5542. prev_val->next = key;
  5543. val->next = next_key;
  5544. } else {
  5545. val->next = key;
  5546. }
  5547. key->next = val;
  5548. obj->uni.ptr = (void *)key;
  5549. unsafe_yyjson_set_len(obj, len + 1);
  5550. }
  5551. yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_obj_remove(
  5552. yyjson_mut_val *obj, const char *key, size_t key_len) {
  5553. size_t obj_len = unsafe_yyjson_get_len(obj);
  5554. if (obj_len) {
  5555. yyjson_mut_val *pre_key = (yyjson_mut_val *)obj->uni.ptr;
  5556. yyjson_mut_val *cur_key = pre_key->next->next;
  5557. yyjson_mut_val *removed_item = NULL;
  5558. size_t i;
  5559. for (i = 0; i < obj_len; i++) {
  5560. if (unsafe_yyjson_equals_strn(cur_key, key, key_len)) {
  5561. if (!removed_item) removed_item = cur_key->next;
  5562. cur_key = cur_key->next->next;
  5563. pre_key->next->next = cur_key;
  5564. if (i + 1 == obj_len) obj->uni.ptr = pre_key;
  5565. i--;
  5566. obj_len--;
  5567. } else {
  5568. pre_key = cur_key;
  5569. cur_key = cur_key->next->next;
  5570. }
  5571. }
  5572. unsafe_yyjson_set_len(obj, obj_len);
  5573. return removed_item;
  5574. } else {
  5575. return NULL;
  5576. }
  5577. }
  5578. yyjson_api_inline bool unsafe_yyjson_mut_obj_replace(yyjson_mut_val *obj,
  5579. yyjson_mut_val *key,
  5580. yyjson_mut_val *val) {
  5581. size_t key_len = unsafe_yyjson_get_len(key);
  5582. size_t obj_len = unsafe_yyjson_get_len(obj);
  5583. if (obj_len) {
  5584. yyjson_mut_val *pre_key = (yyjson_mut_val *)obj->uni.ptr;
  5585. yyjson_mut_val *cur_key = pre_key->next->next;
  5586. size_t i;
  5587. for (i = 0; i < obj_len; i++) {
  5588. if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
  5589. cur_key->next->tag = val->tag;
  5590. cur_key->next->uni.u64 = val->uni.u64;
  5591. return true;
  5592. } else {
  5593. cur_key = cur_key->next->next;
  5594. }
  5595. }
  5596. }
  5597. return false;
  5598. }
  5599. yyjson_api_inline void unsafe_yyjson_mut_obj_rotate(yyjson_mut_val *obj,
  5600. size_t idx) {
  5601. yyjson_mut_val *key = (yyjson_mut_val *)obj->uni.ptr;
  5602. while (idx-- > 0) key = key->next->next;
  5603. obj->uni.ptr = (void *)key;
  5604. }
  5605. yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val *obj,
  5606. yyjson_mut_val *key,
  5607. yyjson_mut_val *val) {
  5608. if (yyjson_likely(yyjson_mut_is_obj(obj) &&
  5609. yyjson_mut_is_str(key) && val)) {
  5610. unsafe_yyjson_mut_obj_add(obj, key, val, unsafe_yyjson_get_len(obj));
  5611. return true;
  5612. }
  5613. return false;
  5614. }
  5615. yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val *obj,
  5616. yyjson_mut_val *key,
  5617. yyjson_mut_val *val) {
  5618. bool replaced = false;
  5619. size_t key_len;
  5620. yyjson_mut_obj_iter iter;
  5621. yyjson_mut_val *cur_key;
  5622. if (yyjson_unlikely(!yyjson_mut_is_obj(obj) ||
  5623. !yyjson_mut_is_str(key))) return false;
  5624. key_len = unsafe_yyjson_get_len(key);
  5625. yyjson_mut_obj_iter_init(obj, &iter);
  5626. while ((cur_key = yyjson_mut_obj_iter_next(&iter)) != 0) {
  5627. if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
  5628. if (!replaced && val) {
  5629. replaced = true;
  5630. val->next = cur_key->next->next;
  5631. cur_key->next = val;
  5632. } else {
  5633. yyjson_mut_obj_iter_remove(&iter);
  5634. }
  5635. }
  5636. }
  5637. if (!replaced && val) unsafe_yyjson_mut_obj_add(obj, key, val, iter.max);
  5638. return true;
  5639. }
  5640. yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val *obj,
  5641. yyjson_mut_val *key,
  5642. yyjson_mut_val *val,
  5643. size_t idx) {
  5644. if (yyjson_likely(yyjson_mut_is_obj(obj) &&
  5645. yyjson_mut_is_str(key) && val)) {
  5646. size_t len = unsafe_yyjson_get_len(obj);
  5647. if (yyjson_likely(len >= idx)) {
  5648. if (len > idx) {
  5649. void *ptr = obj->uni.ptr;
  5650. unsafe_yyjson_mut_obj_rotate(obj, idx);
  5651. unsafe_yyjson_mut_obj_add(obj, key, val, len);
  5652. obj->uni.ptr = ptr;
  5653. } else {
  5654. unsafe_yyjson_mut_obj_add(obj, key, val, len);
  5655. }
  5656. return true;
  5657. }
  5658. }
  5659. return false;
  5660. }
  5661. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove(yyjson_mut_val *obj,
  5662. yyjson_mut_val *key) {
  5663. if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key))) {
  5664. return unsafe_yyjson_mut_obj_remove(obj, key->uni.str,
  5665. unsafe_yyjson_get_len(key));
  5666. }
  5667. return NULL;
  5668. }
  5669. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_key(
  5670. yyjson_mut_val *obj, const char *key) {
  5671. if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
  5672. size_t key_len = strlen(key);
  5673. return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
  5674. }
  5675. return NULL;
  5676. }
  5677. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_keyn(
  5678. yyjson_mut_val *obj, const char *key, size_t key_len) {
  5679. if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
  5680. return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
  5681. }
  5682. return NULL;
  5683. }
  5684. yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val *obj) {
  5685. if (yyjson_likely(yyjson_mut_is_obj(obj))) {
  5686. unsafe_yyjson_set_len(obj, 0);
  5687. return true;
  5688. }
  5689. return false;
  5690. }
  5691. yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val *obj,
  5692. yyjson_mut_val *key,
  5693. yyjson_mut_val *val) {
  5694. if (yyjson_likely(yyjson_mut_is_obj(obj) &&
  5695. yyjson_mut_is_str(key) && val)) {
  5696. return unsafe_yyjson_mut_obj_replace(obj, key, val);
  5697. }
  5698. return false;
  5699. }
  5700. yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
  5701. size_t idx) {
  5702. if (yyjson_likely(yyjson_mut_is_obj(obj) &&
  5703. unsafe_yyjson_get_len(obj) > idx)) {
  5704. unsafe_yyjson_mut_obj_rotate(obj, idx);
  5705. return true;
  5706. }
  5707. return false;
  5708. }
  5709. /*==============================================================================
  5710. * Mutable JSON Object Modification Convenience API (Implementation)
  5711. *============================================================================*/
  5712. #define yyjson_mut_obj_add_func(func) \
  5713. if (yyjson_likely(doc && yyjson_mut_is_obj(obj) && _key)) { \
  5714. yyjson_mut_val *key = unsafe_yyjson_mut_val(doc, 2); \
  5715. if (yyjson_likely(key)) { \
  5716. size_t len = unsafe_yyjson_get_len(obj); \
  5717. yyjson_mut_val *val = key + 1; \
  5718. size_t key_len = strlen(_key); \
  5719. bool noesc = unsafe_yyjson_is_str_noesc(_key, key_len); \
  5720. key->tag = YYJSON_TYPE_STR; \
  5721. key->tag |= noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE; \
  5722. key->tag |= (uint64_t)strlen(_key) << YYJSON_TAG_BIT; \
  5723. key->uni.str = _key; \
  5724. func \
  5725. unsafe_yyjson_mut_obj_add(obj, key, val, len); \
  5726. return true; \
  5727. } \
  5728. } \
  5729. return false
  5730. yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc,
  5731. yyjson_mut_val *obj,
  5732. const char *_key) {
  5733. yyjson_mut_obj_add_func({
  5734. val->tag = YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE;
  5735. });
  5736. }
  5737. yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc,
  5738. yyjson_mut_val *obj,
  5739. const char *_key) {
  5740. yyjson_mut_obj_add_func({
  5741. val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
  5742. });
  5743. }
  5744. yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc,
  5745. yyjson_mut_val *obj,
  5746. const char *_key) {
  5747. yyjson_mut_obj_add_func({
  5748. val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
  5749. });
  5750. }
  5751. yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
  5752. yyjson_mut_val *obj,
  5753. const char *_key,
  5754. bool _val) {
  5755. yyjson_mut_obj_add_func({
  5756. val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)(_val) << 3);
  5757. });
  5758. }
  5759. yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc,
  5760. yyjson_mut_val *obj,
  5761. const char *_key,
  5762. uint64_t _val) {
  5763. yyjson_mut_obj_add_func({
  5764. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
  5765. val->uni.u64 = _val;
  5766. });
  5767. }
  5768. yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc,
  5769. yyjson_mut_val *obj,
  5770. const char *_key,
  5771. int64_t _val) {
  5772. yyjson_mut_obj_add_func({
  5773. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  5774. val->uni.i64 = _val;
  5775. });
  5776. }
  5777. yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc,
  5778. yyjson_mut_val *obj,
  5779. const char *_key,
  5780. int64_t _val) {
  5781. yyjson_mut_obj_add_func({
  5782. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
  5783. val->uni.i64 = _val;
  5784. });
  5785. }
  5786. yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc,
  5787. yyjson_mut_val *obj,
  5788. const char *_key,
  5789. double _val) {
  5790. yyjson_mut_obj_add_func({
  5791. val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
  5792. val->uni.f64 = _val;
  5793. });
  5794. }
  5795. yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc,
  5796. yyjson_mut_val *obj,
  5797. const char *_key,
  5798. const char *_val) {
  5799. if (yyjson_unlikely(!_val)) return false;
  5800. yyjson_mut_obj_add_func({
  5801. size_t val_len = strlen(_val);
  5802. bool val_noesc = unsafe_yyjson_is_str_noesc(_val, val_len);
  5803. val->tag = ((uint64_t)strlen(_val) << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5804. val->tag |= val_noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
  5805. val->uni.str = _val;
  5806. });
  5807. }
  5808. yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc,
  5809. yyjson_mut_val *obj,
  5810. const char *_key,
  5811. const char *_val,
  5812. size_t _len) {
  5813. if (yyjson_unlikely(!_val)) return false;
  5814. yyjson_mut_obj_add_func({
  5815. val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5816. val->uni.str = _val;
  5817. });
  5818. }
  5819. yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
  5820. yyjson_mut_val *obj,
  5821. const char *_key,
  5822. const char *_val) {
  5823. if (yyjson_unlikely(!_val)) return false;
  5824. yyjson_mut_obj_add_func({
  5825. size_t _len = strlen(_val);
  5826. val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
  5827. if (yyjson_unlikely(!val->uni.str)) return false;
  5828. val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5829. });
  5830. }
  5831. yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc,
  5832. yyjson_mut_val *obj,
  5833. const char *_key,
  5834. const char *_val,
  5835. size_t _len) {
  5836. if (yyjson_unlikely(!_val)) return false;
  5837. yyjson_mut_obj_add_func({
  5838. val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
  5839. if (yyjson_unlikely(!val->uni.str)) return false;
  5840. val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
  5841. });
  5842. }
  5843. yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc,
  5844. yyjson_mut_val *obj,
  5845. const char *_key,
  5846. yyjson_mut_val *_val) {
  5847. if (yyjson_unlikely(!_val)) return false;
  5848. yyjson_mut_obj_add_func({
  5849. val = _val;
  5850. });
  5851. }
  5852. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_str(yyjson_mut_val *obj,
  5853. const char *key) {
  5854. return yyjson_mut_obj_remove_strn(obj, key, key ? strlen(key) : 0);
  5855. }
  5856. yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_strn(
  5857. yyjson_mut_val *obj, const char *_key, size_t _len) {
  5858. if (yyjson_likely(yyjson_mut_is_obj(obj) && _key)) {
  5859. yyjson_mut_val *key;
  5860. yyjson_mut_obj_iter iter;
  5861. yyjson_mut_val *val_removed = NULL;
  5862. yyjson_mut_obj_iter_init(obj, &iter);
  5863. while ((key = yyjson_mut_obj_iter_next(&iter)) != NULL) {
  5864. if (unsafe_yyjson_equals_strn(key, _key, _len)) {
  5865. if (!val_removed) val_removed = key->next;
  5866. yyjson_mut_obj_iter_remove(&iter);
  5867. }
  5868. }
  5869. return val_removed;
  5870. }
  5871. return NULL;
  5872. }
  5873. yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc *doc,
  5874. yyjson_mut_val *obj,
  5875. const char *key,
  5876. const char *new_key) {
  5877. if (!key || !new_key) return false;
  5878. return yyjson_mut_obj_rename_keyn(doc, obj, key, strlen(key),
  5879. new_key, strlen(new_key));
  5880. }
  5881. yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc,
  5882. yyjson_mut_val *obj,
  5883. const char *key,
  5884. size_t len,
  5885. const char *new_key,
  5886. size_t new_len) {
  5887. char *cpy_key = NULL;
  5888. yyjson_mut_val *old_key;
  5889. yyjson_mut_obj_iter iter;
  5890. if (!doc || !obj || !key || !new_key) return false;
  5891. yyjson_mut_obj_iter_init(obj, &iter);
  5892. while ((old_key = yyjson_mut_obj_iter_next(&iter))) {
  5893. if (unsafe_yyjson_equals_strn((void *)old_key, key, len)) {
  5894. if (!cpy_key) {
  5895. cpy_key = unsafe_yyjson_mut_strncpy(doc, new_key, new_len);
  5896. if (!cpy_key) return false;
  5897. }
  5898. yyjson_mut_set_strn(old_key, cpy_key, new_len);
  5899. }
  5900. }
  5901. return cpy_key != NULL;
  5902. }
  5903. /*==============================================================================
  5904. * JSON Pointer API (Implementation)
  5905. *============================================================================*/
  5906. #define yyjson_ptr_set_err(_code, _msg) do { \
  5907. if (err) { \
  5908. err->code = YYJSON_PTR_ERR_##_code; \
  5909. err->msg = _msg; \
  5910. err->pos = 0; \
  5911. } \
  5912. } while(false)
  5913. /* require: val != NULL, *ptr == '/', len > 0 */
  5914. yyjson_api yyjson_val *unsafe_yyjson_ptr_getx(yyjson_val *val,
  5915. const char *ptr, size_t len,
  5916. yyjson_ptr_err *err);
  5917. /* require: val != NULL, *ptr == '/', len > 0 */
  5918. yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_getx(yyjson_mut_val *val,
  5919. const char *ptr,
  5920. size_t len,
  5921. yyjson_ptr_ctx *ctx,
  5922. yyjson_ptr_err *err);
  5923. /* require: val/new_val/doc != NULL, *ptr == '/', len > 0 */
  5924. yyjson_api bool unsafe_yyjson_mut_ptr_putx(yyjson_mut_val *val,
  5925. const char *ptr, size_t len,
  5926. yyjson_mut_val *new_val,
  5927. yyjson_mut_doc *doc,
  5928. bool create_parent, bool insert_new,
  5929. yyjson_ptr_ctx *ctx,
  5930. yyjson_ptr_err *err);
  5931. /* require: val/err != NULL, *ptr == '/', len > 0 */
  5932. yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_replacex(
  5933. yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
  5934. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
  5935. /* require: val/err != NULL, *ptr == '/', len > 0 */
  5936. yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_removex(yyjson_mut_val *val,
  5937. const char *ptr,
  5938. size_t len,
  5939. yyjson_ptr_ctx *ctx,
  5940. yyjson_ptr_err *err);
  5941. yyjson_api_inline yyjson_val *yyjson_doc_ptr_get(yyjson_doc *doc,
  5942. const char *ptr) {
  5943. if (yyjson_unlikely(!ptr)) return NULL;
  5944. return yyjson_doc_ptr_getn(doc, ptr, strlen(ptr));
  5945. }
  5946. yyjson_api_inline yyjson_val *yyjson_doc_ptr_getn(yyjson_doc *doc,
  5947. const char *ptr, size_t len) {
  5948. return yyjson_doc_ptr_getx(doc, ptr, len, NULL);
  5949. }
  5950. yyjson_api_inline yyjson_val *yyjson_doc_ptr_getx(yyjson_doc *doc,
  5951. const char *ptr, size_t len,
  5952. yyjson_ptr_err *err) {
  5953. yyjson_ptr_set_err(NONE, NULL);
  5954. if (yyjson_unlikely(!doc || !ptr)) {
  5955. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  5956. return NULL;
  5957. }
  5958. if (yyjson_unlikely(!doc->root)) {
  5959. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  5960. return NULL;
  5961. }
  5962. if (yyjson_unlikely(len == 0)) {
  5963. return doc->root;
  5964. }
  5965. if (yyjson_unlikely(*ptr != '/')) {
  5966. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  5967. return NULL;
  5968. }
  5969. return unsafe_yyjson_ptr_getx(doc->root, ptr, len, err);
  5970. }
  5971. yyjson_api_inline yyjson_val *yyjson_ptr_get(yyjson_val *val,
  5972. const char *ptr) {
  5973. if (yyjson_unlikely(!ptr)) return NULL;
  5974. return yyjson_ptr_getn(val, ptr, strlen(ptr));
  5975. }
  5976. yyjson_api_inline yyjson_val *yyjson_ptr_getn(yyjson_val *val,
  5977. const char *ptr, size_t len) {
  5978. return yyjson_ptr_getx(val, ptr, len, NULL);
  5979. }
  5980. yyjson_api_inline yyjson_val *yyjson_ptr_getx(yyjson_val *val,
  5981. const char *ptr, size_t len,
  5982. yyjson_ptr_err *err) {
  5983. yyjson_ptr_set_err(NONE, NULL);
  5984. if (yyjson_unlikely(!val || !ptr)) {
  5985. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  5986. return NULL;
  5987. }
  5988. if (yyjson_unlikely(len == 0)) {
  5989. return val;
  5990. }
  5991. if (yyjson_unlikely(*ptr != '/')) {
  5992. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  5993. return NULL;
  5994. }
  5995. return unsafe_yyjson_ptr_getx(val, ptr, len, err);
  5996. }
  5997. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_get(yyjson_mut_doc *doc,
  5998. const char *ptr) {
  5999. if (!ptr) return NULL;
  6000. return yyjson_mut_doc_ptr_getn(doc, ptr, strlen(ptr));
  6001. }
  6002. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getn(yyjson_mut_doc *doc,
  6003. const char *ptr,
  6004. size_t len) {
  6005. return yyjson_mut_doc_ptr_getx(doc, ptr, len, NULL, NULL);
  6006. }
  6007. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getx(yyjson_mut_doc *doc,
  6008. const char *ptr,
  6009. size_t len,
  6010. yyjson_ptr_ctx *ctx,
  6011. yyjson_ptr_err *err) {
  6012. yyjson_ptr_set_err(NONE, NULL);
  6013. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6014. if (yyjson_unlikely(!doc || !ptr)) {
  6015. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6016. return NULL;
  6017. }
  6018. if (yyjson_unlikely(!doc->root)) {
  6019. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  6020. return NULL;
  6021. }
  6022. if (yyjson_unlikely(len == 0)) {
  6023. return doc->root;
  6024. }
  6025. if (yyjson_unlikely(*ptr != '/')) {
  6026. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6027. return NULL;
  6028. }
  6029. return unsafe_yyjson_mut_ptr_getx(doc->root, ptr, len, ctx, err);
  6030. }
  6031. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_get(yyjson_mut_val *val,
  6032. const char *ptr) {
  6033. if (!ptr) return NULL;
  6034. return yyjson_mut_ptr_getn(val, ptr, strlen(ptr));
  6035. }
  6036. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getn(yyjson_mut_val *val,
  6037. const char *ptr,
  6038. size_t len) {
  6039. return yyjson_mut_ptr_getx(val, ptr, len, NULL, NULL);
  6040. }
  6041. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getx(yyjson_mut_val *val,
  6042. const char *ptr,
  6043. size_t len,
  6044. yyjson_ptr_ctx *ctx,
  6045. yyjson_ptr_err *err) {
  6046. yyjson_ptr_set_err(NONE, NULL);
  6047. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6048. if (yyjson_unlikely(!val || !ptr)) {
  6049. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6050. return NULL;
  6051. }
  6052. if (yyjson_unlikely(len == 0)) {
  6053. return val;
  6054. }
  6055. if (yyjson_unlikely(*ptr != '/')) {
  6056. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6057. return NULL;
  6058. }
  6059. return unsafe_yyjson_mut_ptr_getx(val, ptr, len, ctx, err);
  6060. }
  6061. yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc *doc,
  6062. const char *ptr,
  6063. yyjson_mut_val *new_val) {
  6064. if (yyjson_unlikely(!ptr)) return false;
  6065. return yyjson_mut_doc_ptr_addn(doc, ptr, strlen(ptr), new_val);
  6066. }
  6067. yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc *doc,
  6068. const char *ptr,
  6069. size_t len,
  6070. yyjson_mut_val *new_val) {
  6071. return yyjson_mut_doc_ptr_addx(doc, ptr, len, new_val, true, NULL, NULL);
  6072. }
  6073. yyjson_api_inline bool yyjson_mut_doc_ptr_addx(yyjson_mut_doc *doc,
  6074. const char *ptr, size_t len,
  6075. yyjson_mut_val *new_val,
  6076. bool create_parent,
  6077. yyjson_ptr_ctx *ctx,
  6078. yyjson_ptr_err *err) {
  6079. yyjson_ptr_set_err(NONE, NULL);
  6080. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6081. if (yyjson_unlikely(!doc || !ptr || !new_val)) {
  6082. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6083. return false;
  6084. }
  6085. if (yyjson_unlikely(len == 0)) {
  6086. if (doc->root) {
  6087. yyjson_ptr_set_err(SET_ROOT, "cannot set document's root");
  6088. return false;
  6089. } else {
  6090. doc->root = new_val;
  6091. return true;
  6092. }
  6093. }
  6094. if (yyjson_unlikely(*ptr != '/')) {
  6095. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6096. return false;
  6097. }
  6098. if (yyjson_unlikely(!doc->root && !create_parent)) {
  6099. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  6100. return false;
  6101. }
  6102. if (yyjson_unlikely(!doc->root)) {
  6103. yyjson_mut_val *root = yyjson_mut_obj(doc);
  6104. if (yyjson_unlikely(!root)) {
  6105. yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
  6106. return false;
  6107. }
  6108. if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc,
  6109. create_parent, true, ctx, err)) {
  6110. doc->root = root;
  6111. return true;
  6112. }
  6113. return false;
  6114. }
  6115. return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc,
  6116. create_parent, true, ctx, err);
  6117. }
  6118. yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val *val,
  6119. const char *ptr,
  6120. yyjson_mut_val *new_val,
  6121. yyjson_mut_doc *doc) {
  6122. if (yyjson_unlikely(!ptr)) return false;
  6123. return yyjson_mut_ptr_addn(val, ptr, strlen(ptr), new_val, doc);
  6124. }
  6125. yyjson_api_inline bool yyjson_mut_ptr_addn(yyjson_mut_val *val,
  6126. const char *ptr, size_t len,
  6127. yyjson_mut_val *new_val,
  6128. yyjson_mut_doc *doc) {
  6129. return yyjson_mut_ptr_addx(val, ptr, len, new_val, doc, true, NULL, NULL);
  6130. }
  6131. yyjson_api_inline bool yyjson_mut_ptr_addx(yyjson_mut_val *val,
  6132. const char *ptr, size_t len,
  6133. yyjson_mut_val *new_val,
  6134. yyjson_mut_doc *doc,
  6135. bool create_parent,
  6136. yyjson_ptr_ctx *ctx,
  6137. yyjson_ptr_err *err) {
  6138. yyjson_ptr_set_err(NONE, NULL);
  6139. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6140. if (yyjson_unlikely(!val || !ptr || !new_val || !doc)) {
  6141. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6142. return false;
  6143. }
  6144. if (yyjson_unlikely(len == 0)) {
  6145. yyjson_ptr_set_err(SET_ROOT, "cannot set root");
  6146. return false;
  6147. }
  6148. if (yyjson_unlikely(*ptr != '/')) {
  6149. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6150. return false;
  6151. }
  6152. return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val,
  6153. doc, create_parent, true, ctx, err);
  6154. }
  6155. yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc *doc,
  6156. const char *ptr,
  6157. yyjson_mut_val *new_val) {
  6158. if (yyjson_unlikely(!ptr)) return false;
  6159. return yyjson_mut_doc_ptr_setn(doc, ptr, strlen(ptr), new_val);
  6160. }
  6161. yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc *doc,
  6162. const char *ptr, size_t len,
  6163. yyjson_mut_val *new_val) {
  6164. return yyjson_mut_doc_ptr_setx(doc, ptr, len, new_val, true, NULL, NULL);
  6165. }
  6166. yyjson_api_inline bool yyjson_mut_doc_ptr_setx(yyjson_mut_doc *doc,
  6167. const char *ptr, size_t len,
  6168. yyjson_mut_val *new_val,
  6169. bool create_parent,
  6170. yyjson_ptr_ctx *ctx,
  6171. yyjson_ptr_err *err) {
  6172. yyjson_ptr_set_err(NONE, NULL);
  6173. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6174. if (yyjson_unlikely(!doc || !ptr)) {
  6175. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6176. return false;
  6177. }
  6178. if (yyjson_unlikely(len == 0)) {
  6179. if (ctx) ctx->old = doc->root;
  6180. doc->root = new_val;
  6181. return true;
  6182. }
  6183. if (yyjson_unlikely(*ptr != '/')) {
  6184. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6185. return false;
  6186. }
  6187. if (!new_val) {
  6188. if (!doc->root) {
  6189. yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
  6190. return false;
  6191. }
  6192. return !!unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
  6193. }
  6194. if (yyjson_unlikely(!doc->root && !create_parent)) {
  6195. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  6196. return false;
  6197. }
  6198. if (yyjson_unlikely(!doc->root)) {
  6199. yyjson_mut_val *root = yyjson_mut_obj(doc);
  6200. if (yyjson_unlikely(!root)) {
  6201. yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
  6202. return false;
  6203. }
  6204. if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc,
  6205. create_parent, false, ctx, err)) {
  6206. doc->root = root;
  6207. return true;
  6208. }
  6209. return false;
  6210. }
  6211. return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc,
  6212. create_parent, false, ctx, err);
  6213. }
  6214. yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val *val,
  6215. const char *ptr,
  6216. yyjson_mut_val *new_val,
  6217. yyjson_mut_doc *doc) {
  6218. if (yyjson_unlikely(!ptr)) return false;
  6219. return yyjson_mut_ptr_setn(val, ptr, strlen(ptr), new_val, doc);
  6220. }
  6221. yyjson_api_inline bool yyjson_mut_ptr_setn(yyjson_mut_val *val,
  6222. const char *ptr, size_t len,
  6223. yyjson_mut_val *new_val,
  6224. yyjson_mut_doc *doc) {
  6225. return yyjson_mut_ptr_setx(val, ptr, len, new_val, doc, true, NULL, NULL);
  6226. }
  6227. yyjson_api_inline bool yyjson_mut_ptr_setx(yyjson_mut_val *val,
  6228. const char *ptr, size_t len,
  6229. yyjson_mut_val *new_val,
  6230. yyjson_mut_doc *doc,
  6231. bool create_parent,
  6232. yyjson_ptr_ctx *ctx,
  6233. yyjson_ptr_err *err) {
  6234. yyjson_ptr_set_err(NONE, NULL);
  6235. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6236. if (yyjson_unlikely(!val || !ptr || !doc)) {
  6237. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6238. return false;
  6239. }
  6240. if (yyjson_unlikely(len == 0)) {
  6241. yyjson_ptr_set_err(SET_ROOT, "cannot set root");
  6242. return false;
  6243. }
  6244. if (yyjson_unlikely(*ptr != '/')) {
  6245. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6246. return false;
  6247. }
  6248. if (!new_val) {
  6249. return !!unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
  6250. }
  6251. return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val, doc,
  6252. create_parent, false, ctx, err);
  6253. }
  6254. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replace(
  6255. yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val) {
  6256. if (!ptr) return NULL;
  6257. return yyjson_mut_doc_ptr_replacen(doc, ptr, strlen(ptr), new_val);
  6258. }
  6259. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacen(
  6260. yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val) {
  6261. return yyjson_mut_doc_ptr_replacex(doc, ptr, len, new_val, NULL, NULL);
  6262. }
  6263. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacex(
  6264. yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val,
  6265. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
  6266. yyjson_ptr_set_err(NONE, NULL);
  6267. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6268. if (yyjson_unlikely(!doc || !ptr || !new_val)) {
  6269. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6270. return NULL;
  6271. }
  6272. if (yyjson_unlikely(len == 0)) {
  6273. yyjson_mut_val *root = doc->root;
  6274. if (yyjson_unlikely(!root)) {
  6275. yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
  6276. return NULL;
  6277. }
  6278. if (ctx) ctx->old = root;
  6279. doc->root = new_val;
  6280. return root;
  6281. }
  6282. if (yyjson_unlikely(!doc->root)) {
  6283. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  6284. return NULL;
  6285. }
  6286. if (yyjson_unlikely(*ptr != '/')) {
  6287. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6288. return NULL;
  6289. }
  6290. return unsafe_yyjson_mut_ptr_replacex(doc->root, ptr, len, new_val,
  6291. ctx, err);
  6292. }
  6293. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replace(
  6294. yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val) {
  6295. if (!ptr) return NULL;
  6296. return yyjson_mut_ptr_replacen(val, ptr, strlen(ptr), new_val);
  6297. }
  6298. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacen(
  6299. yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val) {
  6300. return yyjson_mut_ptr_replacex(val, ptr, len, new_val, NULL, NULL);
  6301. }
  6302. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacex(
  6303. yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
  6304. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
  6305. yyjson_ptr_set_err(NONE, NULL);
  6306. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6307. if (yyjson_unlikely(!val || !ptr || !new_val)) {
  6308. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6309. return NULL;
  6310. }
  6311. if (yyjson_unlikely(len == 0)) {
  6312. yyjson_ptr_set_err(SET_ROOT, "cannot set root");
  6313. return NULL;
  6314. }
  6315. if (yyjson_unlikely(*ptr != '/')) {
  6316. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6317. return NULL;
  6318. }
  6319. return unsafe_yyjson_mut_ptr_replacex(val, ptr, len, new_val, ctx, err);
  6320. }
  6321. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_remove(
  6322. yyjson_mut_doc *doc, const char *ptr) {
  6323. if (!ptr) return NULL;
  6324. return yyjson_mut_doc_ptr_removen(doc, ptr, strlen(ptr));
  6325. }
  6326. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removen(
  6327. yyjson_mut_doc *doc, const char *ptr, size_t len) {
  6328. return yyjson_mut_doc_ptr_removex(doc, ptr, len, NULL, NULL);
  6329. }
  6330. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removex(
  6331. yyjson_mut_doc *doc, const char *ptr, size_t len,
  6332. yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
  6333. yyjson_ptr_set_err(NONE, NULL);
  6334. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6335. if (yyjson_unlikely(!doc || !ptr)) {
  6336. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6337. return NULL;
  6338. }
  6339. if (yyjson_unlikely(!doc->root)) {
  6340. yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
  6341. return NULL;
  6342. }
  6343. if (yyjson_unlikely(len == 0)) {
  6344. yyjson_mut_val *root = doc->root;
  6345. if (ctx) ctx->old = root;
  6346. doc->root = NULL;
  6347. return root;
  6348. }
  6349. if (yyjson_unlikely(*ptr != '/')) {
  6350. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6351. return NULL;
  6352. }
  6353. return unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
  6354. }
  6355. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_remove(yyjson_mut_val *val,
  6356. const char *ptr) {
  6357. if (!ptr) return NULL;
  6358. return yyjson_mut_ptr_removen(val, ptr, strlen(ptr));
  6359. }
  6360. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removen(yyjson_mut_val *val,
  6361. const char *ptr,
  6362. size_t len) {
  6363. return yyjson_mut_ptr_removex(val, ptr, len, NULL, NULL);
  6364. }
  6365. yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removex(yyjson_mut_val *val,
  6366. const char *ptr,
  6367. size_t len,
  6368. yyjson_ptr_ctx *ctx,
  6369. yyjson_ptr_err *err) {
  6370. yyjson_ptr_set_err(NONE, NULL);
  6371. if (ctx) memset(ctx, 0, sizeof(*ctx));
  6372. if (yyjson_unlikely(!val || !ptr)) {
  6373. yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
  6374. return NULL;
  6375. }
  6376. if (yyjson_unlikely(len == 0)) {
  6377. yyjson_ptr_set_err(SET_ROOT, "cannot set root");
  6378. return NULL;
  6379. }
  6380. if (yyjson_unlikely(*ptr != '/')) {
  6381. yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
  6382. return NULL;
  6383. }
  6384. return unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
  6385. }
  6386. yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx *ctx,
  6387. yyjson_mut_val *key,
  6388. yyjson_mut_val *val) {
  6389. yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
  6390. if (!ctx || !ctx->ctn || !val) return false;
  6391. ctn = ctx->ctn;
  6392. if (yyjson_mut_is_obj(ctn)) {
  6393. if (!key) return false;
  6394. key->next = val;
  6395. pre_key = ctx->pre;
  6396. if (unsafe_yyjson_get_len(ctn) == 0) {
  6397. val->next = key;
  6398. ctn->uni.ptr = key;
  6399. ctx->pre = key;
  6400. } else if (!pre_key) {
  6401. pre_key = (yyjson_mut_val *)ctn->uni.ptr;
  6402. pre_val = pre_key->next;
  6403. val->next = pre_val->next;
  6404. pre_val->next = key;
  6405. ctn->uni.ptr = key;
  6406. ctx->pre = pre_key;
  6407. } else {
  6408. cur_key = pre_key->next->next;
  6409. cur_val = cur_key->next;
  6410. val->next = cur_val->next;
  6411. cur_val->next = key;
  6412. if (ctn->uni.ptr == cur_key) ctn->uni.ptr = key;
  6413. ctx->pre = cur_key;
  6414. }
  6415. } else {
  6416. pre_val = ctx->pre;
  6417. if (unsafe_yyjson_get_len(ctn) == 0) {
  6418. val->next = val;
  6419. ctn->uni.ptr = val;
  6420. ctx->pre = val;
  6421. } else if (!pre_val) {
  6422. pre_val = (yyjson_mut_val *)ctn->uni.ptr;
  6423. val->next = pre_val->next;
  6424. pre_val->next = val;
  6425. ctn->uni.ptr = val;
  6426. ctx->pre = pre_val;
  6427. } else {
  6428. cur_val = pre_val->next;
  6429. val->next = cur_val->next;
  6430. cur_val->next = val;
  6431. if (ctn->uni.ptr == cur_val) ctn->uni.ptr = val;
  6432. ctx->pre = cur_val;
  6433. }
  6434. }
  6435. unsafe_yyjson_inc_len(ctn);
  6436. return true;
  6437. }
  6438. yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx *ctx,
  6439. yyjson_mut_val *val) {
  6440. yyjson_mut_val *ctn, *pre_key, *cur_key, *pre_val, *cur_val;
  6441. if (!ctx || !ctx->ctn || !ctx->pre || !val) return false;
  6442. ctn = ctx->ctn;
  6443. if (yyjson_mut_is_obj(ctn)) {
  6444. pre_key = ctx->pre;
  6445. pre_val = pre_key->next;
  6446. cur_key = pre_val->next;
  6447. cur_val = cur_key->next;
  6448. /* replace current value */
  6449. cur_key->next = val;
  6450. val->next = cur_val->next;
  6451. ctx->old = cur_val;
  6452. } else {
  6453. pre_val = ctx->pre;
  6454. cur_val = pre_val->next;
  6455. /* replace current value */
  6456. if (pre_val != cur_val) {
  6457. val->next = cur_val->next;
  6458. pre_val->next = val;
  6459. if (ctn->uni.ptr == cur_val) ctn->uni.ptr = val;
  6460. } else {
  6461. val->next = val;
  6462. ctn->uni.ptr = val;
  6463. ctx->pre = val;
  6464. }
  6465. ctx->old = cur_val;
  6466. }
  6467. return true;
  6468. }
  6469. yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx) {
  6470. yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
  6471. size_t len;
  6472. if (!ctx || !ctx->ctn || !ctx->pre) return false;
  6473. ctn = ctx->ctn;
  6474. if (yyjson_mut_is_obj(ctn)) {
  6475. pre_key = ctx->pre;
  6476. pre_val = pre_key->next;
  6477. cur_key = pre_val->next;
  6478. cur_val = cur_key->next;
  6479. /* remove current key-value */
  6480. pre_val->next = cur_val->next;
  6481. if (ctn->uni.ptr == cur_key) ctn->uni.ptr = pre_key;
  6482. ctx->pre = NULL;
  6483. ctx->old = cur_val;
  6484. } else {
  6485. pre_val = ctx->pre;
  6486. cur_val = pre_val->next;
  6487. /* remove current key-value */
  6488. pre_val->next = cur_val->next;
  6489. if (ctn->uni.ptr == cur_val) ctn->uni.ptr = pre_val;
  6490. ctx->pre = NULL;
  6491. ctx->old = cur_val;
  6492. }
  6493. len = unsafe_yyjson_get_len(ctn) - 1;
  6494. if (len == 0) ctn->uni.ptr = NULL;
  6495. unsafe_yyjson_set_len(ctn, len);
  6496. return true;
  6497. }
  6498. #undef yyjson_ptr_set_err
  6499. /*==============================================================================
  6500. * JSON Value at Pointer API (Implementation)
  6501. *============================================================================*/
  6502. /**
  6503. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type bool.
  6504. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6505. */
  6506. yyjson_api_inline bool yyjson_ptr_get_bool(
  6507. yyjson_val *root, const char *ptr, bool *value) {
  6508. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6509. if (value && yyjson_is_bool(val)) {
  6510. *value = unsafe_yyjson_get_bool(val);
  6511. return true;
  6512. } else {
  6513. return false;
  6514. }
  6515. }
  6516. /**
  6517. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type uint.
  6518. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6519. */
  6520. yyjson_api_inline bool yyjson_ptr_get_uint(
  6521. yyjson_val *root, const char *ptr, uint64_t *value) {
  6522. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6523. if (value && yyjson_is_uint(val)) {
  6524. *value = unsafe_yyjson_get_uint(val);
  6525. return true;
  6526. } else {
  6527. return false;
  6528. }
  6529. }
  6530. /**
  6531. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type sint.
  6532. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6533. */
  6534. yyjson_api_inline bool yyjson_ptr_get_sint(
  6535. yyjson_val *root, const char *ptr, int64_t *value) {
  6536. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6537. if (value && yyjson_is_sint(val)) {
  6538. *value = unsafe_yyjson_get_sint(val);
  6539. return true;
  6540. } else {
  6541. return false;
  6542. }
  6543. }
  6544. /**
  6545. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type real.
  6546. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6547. */
  6548. yyjson_api_inline bool yyjson_ptr_get_real(
  6549. yyjson_val *root, const char *ptr, double *value) {
  6550. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6551. if (value && yyjson_is_real(val)) {
  6552. *value = unsafe_yyjson_get_real(val);
  6553. return true;
  6554. } else {
  6555. return false;
  6556. }
  6557. }
  6558. /**
  6559. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type sint,
  6560. uint or real.
  6561. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6562. */
  6563. yyjson_api_inline bool yyjson_ptr_get_num(
  6564. yyjson_val *root, const char *ptr, double *value) {
  6565. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6566. if (value && yyjson_is_num(val)) {
  6567. *value = unsafe_yyjson_get_num(val);
  6568. return true;
  6569. } else {
  6570. return false;
  6571. }
  6572. }
  6573. /**
  6574. Set provided `value` if the JSON Pointer (RFC 6901) exists and is type string.
  6575. Returns true if value at `ptr` exists and is the correct type, otherwise false.
  6576. */
  6577. yyjson_api_inline bool yyjson_ptr_get_str(
  6578. yyjson_val *root, const char *ptr, const char **value) {
  6579. yyjson_val *val = yyjson_ptr_get(root, ptr);
  6580. if (value && yyjson_is_str(val)) {
  6581. *value = unsafe_yyjson_get_str(val);
  6582. return true;
  6583. } else {
  6584. return false;
  6585. }
  6586. }
  6587. /*==============================================================================
  6588. * Deprecated
  6589. *============================================================================*/
  6590. /** @deprecated renamed to `yyjson_doc_ptr_get` */
  6591. yyjson_deprecated("renamed to yyjson_doc_ptr_get")
  6592. yyjson_api_inline yyjson_val *yyjson_doc_get_pointer(yyjson_doc *doc,
  6593. const char *ptr) {
  6594. return yyjson_doc_ptr_get(doc, ptr);
  6595. }
  6596. /** @deprecated renamed to `yyjson_doc_ptr_getn` */
  6597. yyjson_deprecated("renamed to yyjson_doc_ptr_getn")
  6598. yyjson_api_inline yyjson_val *yyjson_doc_get_pointern(yyjson_doc *doc,
  6599. const char *ptr,
  6600. size_t len) {
  6601. return yyjson_doc_ptr_getn(doc, ptr, len);
  6602. }
  6603. /** @deprecated renamed to `yyjson_mut_doc_ptr_get` */
  6604. yyjson_deprecated("renamed to yyjson_mut_doc_ptr_get")
  6605. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_pointer(
  6606. yyjson_mut_doc *doc, const char *ptr) {
  6607. return yyjson_mut_doc_ptr_get(doc, ptr);
  6608. }
  6609. /** @deprecated renamed to `yyjson_mut_doc_ptr_getn` */
  6610. yyjson_deprecated("renamed to yyjson_mut_doc_ptr_getn")
  6611. yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_pointern(
  6612. yyjson_mut_doc *doc, const char *ptr, size_t len) {
  6613. return yyjson_mut_doc_ptr_getn(doc, ptr, len);
  6614. }
  6615. /** @deprecated renamed to `yyjson_ptr_get` */
  6616. yyjson_deprecated("renamed to yyjson_ptr_get")
  6617. yyjson_api_inline yyjson_val *yyjson_get_pointer(yyjson_val *val,
  6618. const char *ptr) {
  6619. return yyjson_ptr_get(val, ptr);
  6620. }
  6621. /** @deprecated renamed to `yyjson_ptr_getn` */
  6622. yyjson_deprecated("renamed to yyjson_ptr_getn")
  6623. yyjson_api_inline yyjson_val *yyjson_get_pointern(yyjson_val *val,
  6624. const char *ptr,
  6625. size_t len) {
  6626. return yyjson_ptr_getn(val, ptr, len);
  6627. }
  6628. /** @deprecated renamed to `yyjson_mut_ptr_get` */
  6629. yyjson_deprecated("renamed to yyjson_mut_ptr_get")
  6630. yyjson_api_inline yyjson_mut_val *yyjson_mut_get_pointer(yyjson_mut_val *val,
  6631. const char *ptr) {
  6632. return yyjson_mut_ptr_get(val, ptr);
  6633. }
  6634. /** @deprecated renamed to `yyjson_mut_ptr_getn` */
  6635. yyjson_deprecated("renamed to yyjson_mut_ptr_getn")
  6636. yyjson_api_inline yyjson_mut_val *yyjson_mut_get_pointern(yyjson_mut_val *val,
  6637. const char *ptr,
  6638. size_t len) {
  6639. return yyjson_mut_ptr_getn(val, ptr, len);
  6640. }
  6641. /** @deprecated renamed to `yyjson_mut_ptr_getn` */
  6642. yyjson_deprecated("renamed to unsafe_yyjson_ptr_getn")
  6643. yyjson_api_inline yyjson_val *unsafe_yyjson_get_pointer(yyjson_val *val,
  6644. const char *ptr,
  6645. size_t len) {
  6646. yyjson_ptr_err err;
  6647. return unsafe_yyjson_ptr_getx(val, ptr, len, &err);
  6648. }
  6649. /** @deprecated renamed to `unsafe_yyjson_mut_ptr_getx` */
  6650. yyjson_deprecated("renamed to unsafe_yyjson_mut_ptr_getx")
  6651. yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_get_pointer(
  6652. yyjson_mut_val *val, const char *ptr, size_t len) {
  6653. yyjson_ptr_err err;
  6654. return unsafe_yyjson_mut_ptr_getx(val, ptr, len, NULL, &err);
  6655. }
  6656. /*==============================================================================
  6657. * Compiler Hint End
  6658. *============================================================================*/
  6659. #if defined(__clang__)
  6660. # pragma clang diagnostic pop
  6661. #elif defined(__GNUC__)
  6662. # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  6663. # pragma GCC diagnostic pop
  6664. # endif
  6665. #elif defined(_MSC_VER)
  6666. # pragma warning(pop)
  6667. #endif /* warning suppress end */
  6668. #ifdef __cplusplus
  6669. }
  6670. #endif /* extern "C" end */
  6671. #endif /* YYJSON_H */