mpack.c 243 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2015-2021 Nicholas Fraser and the MPack authors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. *
  24. */
  25. /*
  26. * This is the MPack 1.1.1 amalgamation package.
  27. *
  28. * http://github.com/ludocode/mpack
  29. */
  30. #define MPACK_INTERNAL 1
  31. #define MPACK_EMIT_INLINE_DEFS 1
  32. #include "mpack.h"
  33. /* mpack/mpack-platform.c.c */
  34. // We define MPACK_EMIT_INLINE_DEFS and include mpack.h to emit
  35. // standalone definitions of all (non-static) inline functions in MPack.
  36. #define MPACK_INTERNAL 1
  37. #define MPACK_EMIT_INLINE_DEFS 1
  38. /* #include "mpack-platform.h" */
  39. /* #include "mpack.h" */
  40. MPACK_SILENCE_WARNINGS_BEGIN
  41. #if MPACK_DEBUG
  42. #if MPACK_STDIO
  43. void mpack_assert_fail_format(const char* format, ...) {
  44. char buffer[512];
  45. va_list args;
  46. va_start(args, format);
  47. vsnprintf(buffer, sizeof(buffer), format, args);
  48. va_end(args);
  49. buffer[sizeof(buffer) - 1] = 0;
  50. mpack_assert_fail_wrapper(buffer);
  51. }
  52. void mpack_break_hit_format(const char* format, ...) {
  53. char buffer[512];
  54. va_list args;
  55. va_start(args, format);
  56. vsnprintf(buffer, sizeof(buffer), format, args);
  57. va_end(args);
  58. buffer[sizeof(buffer) - 1] = 0;
  59. mpack_break_hit(buffer);
  60. }
  61. #endif
  62. #if !MPACK_CUSTOM_ASSERT
  63. void mpack_assert_fail(const char* message) {
  64. MPACK_UNUSED(message);
  65. #if MPACK_STDIO
  66. fprintf(stderr, "%s\n", message);
  67. #endif
  68. }
  69. #endif
  70. // We split the assert failure from the wrapper so that a
  71. // custom assert function can return.
  72. void mpack_assert_fail_wrapper(const char* message) {
  73. #ifdef MPACK_GCOV
  74. // gcov marks even __builtin_unreachable() as an uncovered line. this
  75. // silences it.
  76. (mpack_assert_fail(message), __builtin_unreachable());
  77. #else
  78. mpack_assert_fail(message);
  79. // mpack_assert_fail() is not supposed to return. in case it does, we
  80. // abort.
  81. #if !MPACK_NO_BUILTINS
  82. #if defined(__GNUC__) || defined(__clang__)
  83. __builtin_trap();
  84. #elif defined(WIN32)
  85. __debugbreak();
  86. #endif
  87. #endif
  88. #if (defined(__GNUC__) || defined(__clang__)) && !MPACK_NO_BUILTINS
  89. __builtin_abort();
  90. #elif MPACK_STDLIB
  91. abort();
  92. #endif
  93. MPACK_UNREACHABLE;
  94. #endif
  95. }
  96. #if !MPACK_CUSTOM_BREAK
  97. // If we have a custom assert handler, break wraps it by default.
  98. // This allows users of MPack to only implement mpack_assert_fail() without
  99. // having to worry about the difference between assert and break.
  100. //
  101. // MPACK_CUSTOM_BREAK is available to define a separate break handler
  102. // (which is needed by the unit test suite), but this is not offered in
  103. // mpack-config.h for simplicity.
  104. #if MPACK_CUSTOM_ASSERT
  105. void mpack_break_hit(const char* message) {
  106. mpack_assert_fail_wrapper(message);
  107. }
  108. #else
  109. void mpack_break_hit(const char* message) {
  110. MPACK_UNUSED(message);
  111. #if MPACK_STDIO
  112. fprintf(stderr, "%s\n", message);
  113. #endif
  114. #if defined(__GNUC__) || defined(__clang__) && !MPACK_NO_BUILTINS
  115. __builtin_trap();
  116. #elif defined(WIN32) && !MPACK_NO_BUILTINS
  117. __debugbreak();
  118. #elif MPACK_STDLIB
  119. abort();
  120. #endif
  121. }
  122. #endif
  123. #endif
  124. #endif
  125. // The below are adapted from the C wikibook:
  126. // https://en.wikibooks.org/wiki/C_Programming/Strings
  127. #ifndef mpack_memcmp
  128. int mpack_memcmp(const void* s1, const void* s2, size_t n) {
  129. const unsigned char *us1 = (const unsigned char *) s1;
  130. const unsigned char *us2 = (const unsigned char *) s2;
  131. while (n-- != 0) {
  132. if (*us1 != *us2)
  133. return (*us1 < *us2) ? -1 : +1;
  134. us1++;
  135. us2++;
  136. }
  137. return 0;
  138. }
  139. #endif
  140. #ifndef mpack_memcpy
  141. void* mpack_memcpy(void* MPACK_RESTRICT s1, const void* MPACK_RESTRICT s2, size_t n) {
  142. char* MPACK_RESTRICT dst = (char *)s1;
  143. const char* MPACK_RESTRICT src = (const char *)s2;
  144. while (n-- != 0)
  145. *dst++ = *src++;
  146. return s1;
  147. }
  148. #endif
  149. #ifndef mpack_memmove
  150. void* mpack_memmove(void* s1, const void* s2, size_t n) {
  151. char *p1 = (char *)s1;
  152. const char *p2 = (const char *)s2;
  153. if (p2 < p1 && p1 < p2 + n) {
  154. p2 += n;
  155. p1 += n;
  156. while (n-- != 0)
  157. *--p1 = *--p2;
  158. } else
  159. while (n-- != 0)
  160. *p1++ = *p2++;
  161. return s1;
  162. }
  163. #endif
  164. #ifndef mpack_memset
  165. void* mpack_memset(void* s, int c, size_t n) {
  166. unsigned char *us = (unsigned char *)s;
  167. unsigned char uc = (unsigned char)c;
  168. while (n-- != 0)
  169. *us++ = uc;
  170. return s;
  171. }
  172. #endif
  173. #ifndef mpack_strlen
  174. size_t mpack_strlen(const char* s) {
  175. const char* p = s;
  176. while (*p != '\0')
  177. p++;
  178. return (size_t)(p - s);
  179. }
  180. #endif
  181. #if defined(MPACK_MALLOC) && !defined(MPACK_REALLOC)
  182. void* mpack_realloc(void* old_ptr, size_t used_size, size_t new_size) {
  183. if (new_size == 0) {
  184. if (old_ptr)
  185. MPACK_FREE(old_ptr);
  186. return NULL;
  187. }
  188. void* new_ptr = MPACK_MALLOC(new_size);
  189. if (new_ptr == NULL)
  190. return NULL;
  191. mpack_memcpy(new_ptr, old_ptr, used_size);
  192. MPACK_FREE(old_ptr);
  193. return new_ptr;
  194. }
  195. #endif
  196. MPACK_SILENCE_WARNINGS_END
  197. /* mpack/mpack-common.c.c */
  198. #define MPACK_INTERNAL 1
  199. /* #include "mpack-common.h" */
  200. MPACK_SILENCE_WARNINGS_BEGIN
  201. const char* mpack_error_to_string(mpack_error_t error) {
  202. #if MPACK_STRINGS
  203. switch (error) {
  204. #define MPACK_ERROR_STRING_CASE(e) case e: return #e
  205. MPACK_ERROR_STRING_CASE(mpack_ok);
  206. MPACK_ERROR_STRING_CASE(mpack_error_io);
  207. MPACK_ERROR_STRING_CASE(mpack_error_invalid);
  208. MPACK_ERROR_STRING_CASE(mpack_error_unsupported);
  209. MPACK_ERROR_STRING_CASE(mpack_error_type);
  210. MPACK_ERROR_STRING_CASE(mpack_error_too_big);
  211. MPACK_ERROR_STRING_CASE(mpack_error_memory);
  212. MPACK_ERROR_STRING_CASE(mpack_error_bug);
  213. MPACK_ERROR_STRING_CASE(mpack_error_data);
  214. MPACK_ERROR_STRING_CASE(mpack_error_eof);
  215. #undef MPACK_ERROR_STRING_CASE
  216. }
  217. mpack_assert(0, "unrecognized error %i", (int)error);
  218. return "(unknown mpack_error_t)";
  219. #else
  220. MPACK_UNUSED(error);
  221. return "";
  222. #endif
  223. }
  224. const char* mpack_type_to_string(mpack_type_t type) {
  225. #if MPACK_STRINGS
  226. switch (type) {
  227. #define MPACK_TYPE_STRING_CASE(e) case e: return #e
  228. MPACK_TYPE_STRING_CASE(mpack_type_missing);
  229. MPACK_TYPE_STRING_CASE(mpack_type_nil);
  230. MPACK_TYPE_STRING_CASE(mpack_type_bool);
  231. MPACK_TYPE_STRING_CASE(mpack_type_float);
  232. MPACK_TYPE_STRING_CASE(mpack_type_double);
  233. MPACK_TYPE_STRING_CASE(mpack_type_int);
  234. MPACK_TYPE_STRING_CASE(mpack_type_uint);
  235. MPACK_TYPE_STRING_CASE(mpack_type_str);
  236. MPACK_TYPE_STRING_CASE(mpack_type_bin);
  237. MPACK_TYPE_STRING_CASE(mpack_type_array);
  238. MPACK_TYPE_STRING_CASE(mpack_type_map);
  239. #if MPACK_EXTENSIONS
  240. MPACK_TYPE_STRING_CASE(mpack_type_ext);
  241. #endif
  242. #undef MPACK_TYPE_STRING_CASE
  243. }
  244. mpack_assert(0, "unrecognized type %i", (int)type);
  245. return "(unknown mpack_type_t)";
  246. #else
  247. MPACK_UNUSED(type);
  248. return "";
  249. #endif
  250. }
  251. int mpack_tag_cmp(mpack_tag_t left, mpack_tag_t right) {
  252. // positive numbers may be stored as int; convert to uint
  253. if (left.type == mpack_type_int && left.v.i >= 0) {
  254. left.type = mpack_type_uint;
  255. left.v.u = (uint64_t)left.v.i;
  256. }
  257. if (right.type == mpack_type_int && right.v.i >= 0) {
  258. right.type = mpack_type_uint;
  259. right.v.u = (uint64_t)right.v.i;
  260. }
  261. if (left.type != right.type)
  262. return ((int)left.type < (int)right.type) ? -1 : 1;
  263. switch (left.type) {
  264. case mpack_type_missing: // fallthrough
  265. case mpack_type_nil:
  266. return 0;
  267. case mpack_type_bool:
  268. return (int)left.v.b - (int)right.v.b;
  269. case mpack_type_int:
  270. if (left.v.i == right.v.i)
  271. return 0;
  272. return (left.v.i < right.v.i) ? -1 : 1;
  273. case mpack_type_uint:
  274. if (left.v.u == right.v.u)
  275. return 0;
  276. return (left.v.u < right.v.u) ? -1 : 1;
  277. case mpack_type_array:
  278. case mpack_type_map:
  279. if (left.v.n == right.v.n)
  280. return 0;
  281. return (left.v.n < right.v.n) ? -1 : 1;
  282. case mpack_type_str:
  283. case mpack_type_bin:
  284. if (left.v.l == right.v.l)
  285. return 0;
  286. return (left.v.l < right.v.l) ? -1 : 1;
  287. #if MPACK_EXTENSIONS
  288. case mpack_type_ext:
  289. if (left.exttype == right.exttype) {
  290. if (left.v.l == right.v.l)
  291. return 0;
  292. return (left.v.l < right.v.l) ? -1 : 1;
  293. }
  294. return (int)left.exttype - (int)right.exttype;
  295. #endif
  296. // floats should not normally be compared for equality. we compare
  297. // with memcmp() to silence compiler warnings, but this will return
  298. // equal if both are NaNs with the same representation (though we may
  299. // want this, for instance if you are for some bizarre reason using
  300. // floats as map keys.) i'm not sure what the right thing to
  301. // do is here. check for NaN first? always return false if the type
  302. // is float? use operator== and pragmas to silence compiler warning?
  303. // please send me your suggestions.
  304. // note also that we don't convert floats to doubles, so when this is
  305. // used for ordering purposes, all floats are ordered before all
  306. // doubles.
  307. case mpack_type_float:
  308. return mpack_memcmp(&left.v.f, &right.v.f, sizeof(left.v.f));
  309. case mpack_type_double:
  310. return mpack_memcmp(&left.v.d, &right.v.d, sizeof(left.v.d));
  311. }
  312. mpack_assert(0, "unrecognized type %i", (int)left.type);
  313. return false;
  314. }
  315. #if MPACK_DEBUG && MPACK_STDIO
  316. static char mpack_hex_char(uint8_t hex_value) {
  317. // Older compilers (e.g. GCC 4.4.7) promote the result of this ternary to
  318. // int and warn under -Wconversion, so we have to cast it back to char.
  319. return (char)((hex_value < 10) ? (char)('0' + hex_value) : (char)('a' + (hex_value - 10)));
  320. }
  321. static void mpack_tag_debug_complete_bin_ext(mpack_tag_t tag, size_t string_length, char* buffer, size_t buffer_size,
  322. const char* prefix, size_t prefix_size)
  323. {
  324. // If at any point in this function we run out of space in the buffer, we
  325. // bail out. The outer tag print wrapper will make sure we have a
  326. // null-terminator.
  327. if (string_length == 0 || string_length >= buffer_size)
  328. return;
  329. buffer += string_length;
  330. buffer_size -= string_length;
  331. size_t total = mpack_tag_bytes(&tag);
  332. if (total == 0) {
  333. strncpy(buffer, ">", buffer_size);
  334. return;
  335. }
  336. strncpy(buffer, ": ", buffer_size);
  337. if (buffer_size < 2)
  338. return;
  339. buffer += 2;
  340. buffer_size -= 2;
  341. size_t hex_bytes = 0;
  342. size_t i;
  343. for (i = 0; i < MPACK_PRINT_BYTE_COUNT && i < prefix_size && buffer_size > 2; ++i) {
  344. uint8_t byte = (uint8_t)prefix[i];
  345. buffer[0] = mpack_hex_char((uint8_t)(byte >> 4));
  346. buffer[1] = mpack_hex_char((uint8_t)(byte & 0xfu));
  347. buffer += 2;
  348. buffer_size -= 2;
  349. ++hex_bytes;
  350. }
  351. if (buffer_size != 0)
  352. mpack_snprintf(buffer, buffer_size, "%s>", (total > hex_bytes) ? "..." : "");
  353. }
  354. static void mpack_tag_debug_pseudo_json_bin(mpack_tag_t tag, char* buffer, size_t buffer_size,
  355. const char* prefix, size_t prefix_size)
  356. {
  357. mpack_assert(mpack_tag_type(&tag) == mpack_type_bin);
  358. size_t length = (size_t)mpack_snprintf(buffer, buffer_size, "<binary data of length %" PRIu32 "", tag.v.l);
  359. mpack_tag_debug_complete_bin_ext(tag, length, buffer, buffer_size, prefix, prefix_size);
  360. }
  361. #if MPACK_EXTENSIONS
  362. static void mpack_tag_debug_pseudo_json_ext(mpack_tag_t tag, char* buffer, size_t buffer_size,
  363. const char* prefix, size_t prefix_size)
  364. {
  365. mpack_assert(mpack_tag_type(&tag) == mpack_type_ext);
  366. size_t length = (size_t)mpack_snprintf(buffer, buffer_size, "<ext data of type %i and length %" PRIu32 "",
  367. mpack_tag_ext_exttype(&tag), mpack_tag_ext_length(&tag));
  368. mpack_tag_debug_complete_bin_ext(tag, length, buffer, buffer_size, prefix, prefix_size);
  369. }
  370. #endif
  371. static void mpack_tag_debug_pseudo_json_impl(mpack_tag_t tag, char* buffer, size_t buffer_size,
  372. const char* prefix, size_t prefix_size)
  373. {
  374. switch (tag.type) {
  375. case mpack_type_missing:
  376. mpack_snprintf(buffer, buffer_size, "<missing!>");
  377. return;
  378. case mpack_type_nil:
  379. mpack_snprintf(buffer, buffer_size, "null");
  380. return;
  381. case mpack_type_bool:
  382. mpack_snprintf(buffer, buffer_size, tag.v.b ? "true" : "false");
  383. return;
  384. case mpack_type_int:
  385. mpack_snprintf(buffer, buffer_size, "%" PRIi64, tag.v.i);
  386. return;
  387. case mpack_type_uint:
  388. mpack_snprintf(buffer, buffer_size, "%" PRIu64, tag.v.u);
  389. return;
  390. case mpack_type_float:
  391. #if MPACK_FLOAT
  392. mpack_snprintf(buffer, buffer_size, "%f", tag.v.f);
  393. #else
  394. mpack_snprintf(buffer, buffer_size, "<float>");
  395. #endif
  396. return;
  397. case mpack_type_double:
  398. #if MPACK_DOUBLE
  399. mpack_snprintf(buffer, buffer_size, "%f", tag.v.d);
  400. #else
  401. mpack_snprintf(buffer, buffer_size, "<double>");
  402. #endif
  403. return;
  404. case mpack_type_str:
  405. mpack_snprintf(buffer, buffer_size, "<string of %" PRIu32 " bytes>", tag.v.l);
  406. return;
  407. case mpack_type_bin:
  408. mpack_tag_debug_pseudo_json_bin(tag, buffer, buffer_size, prefix, prefix_size);
  409. return;
  410. #if MPACK_EXTENSIONS
  411. case mpack_type_ext:
  412. mpack_tag_debug_pseudo_json_ext(tag, buffer, buffer_size, prefix, prefix_size);
  413. return;
  414. #endif
  415. case mpack_type_array:
  416. mpack_snprintf(buffer, buffer_size, "<array of %" PRIu32 " elements>", tag.v.n);
  417. return;
  418. case mpack_type_map:
  419. mpack_snprintf(buffer, buffer_size, "<map of %" PRIu32 " key-value pairs>", tag.v.n);
  420. return;
  421. }
  422. mpack_snprintf(buffer, buffer_size, "<unknown!>");
  423. }
  424. void mpack_tag_debug_pseudo_json(mpack_tag_t tag, char* buffer, size_t buffer_size,
  425. const char* prefix, size_t prefix_size)
  426. {
  427. mpack_assert(buffer_size > 0, "buffer size cannot be zero!");
  428. buffer[0] = 0;
  429. mpack_tag_debug_pseudo_json_impl(tag, buffer, buffer_size, prefix, prefix_size);
  430. // We always null-terminate the buffer manually just in case the snprintf()
  431. // function doesn't null-terminate when the string doesn't fit.
  432. buffer[buffer_size - 1] = 0;
  433. }
  434. static void mpack_tag_debug_describe_impl(mpack_tag_t tag, char* buffer, size_t buffer_size) {
  435. switch (tag.type) {
  436. case mpack_type_missing:
  437. mpack_snprintf(buffer, buffer_size, "missing");
  438. return;
  439. case mpack_type_nil:
  440. mpack_snprintf(buffer, buffer_size, "nil");
  441. return;
  442. case mpack_type_bool:
  443. mpack_snprintf(buffer, buffer_size, tag.v.b ? "true" : "false");
  444. return;
  445. case mpack_type_int:
  446. mpack_snprintf(buffer, buffer_size, "int %" PRIi64, tag.v.i);
  447. return;
  448. case mpack_type_uint:
  449. mpack_snprintf(buffer, buffer_size, "uint %" PRIu64, tag.v.u);
  450. return;
  451. case mpack_type_float:
  452. #if MPACK_FLOAT
  453. mpack_snprintf(buffer, buffer_size, "float %f", tag.v.f);
  454. #else
  455. mpack_snprintf(buffer, buffer_size, "float");
  456. #endif
  457. return;
  458. case mpack_type_double:
  459. #if MPACK_DOUBLE
  460. mpack_snprintf(buffer, buffer_size, "double %f", tag.v.d);
  461. #else
  462. mpack_snprintf(buffer, buffer_size, "double");
  463. #endif
  464. return;
  465. case mpack_type_str:
  466. mpack_snprintf(buffer, buffer_size, "str of %" PRIu32 " bytes", tag.v.l);
  467. return;
  468. case mpack_type_bin:
  469. mpack_snprintf(buffer, buffer_size, "bin of %" PRIu32 " bytes", tag.v.l);
  470. return;
  471. #if MPACK_EXTENSIONS
  472. case mpack_type_ext:
  473. mpack_snprintf(buffer, buffer_size, "ext of type %i, %" PRIu32 " bytes",
  474. mpack_tag_ext_exttype(&tag), mpack_tag_ext_length(&tag));
  475. return;
  476. #endif
  477. case mpack_type_array:
  478. mpack_snprintf(buffer, buffer_size, "array of %" PRIu32 " elements", tag.v.n);
  479. return;
  480. case mpack_type_map:
  481. mpack_snprintf(buffer, buffer_size, "map of %" PRIu32 " key-value pairs", tag.v.n);
  482. return;
  483. }
  484. mpack_snprintf(buffer, buffer_size, "unknown!");
  485. }
  486. void mpack_tag_debug_describe(mpack_tag_t tag, char* buffer, size_t buffer_size) {
  487. mpack_assert(buffer_size > 0, "buffer size cannot be zero!");
  488. buffer[0] = 0;
  489. mpack_tag_debug_describe_impl(tag, buffer, buffer_size);
  490. // We always null-terminate the buffer manually just in case the snprintf()
  491. // function doesn't null-terminate when the string doesn't fit.
  492. buffer[buffer_size - 1] = 0;
  493. }
  494. #endif
  495. #if MPACK_READ_TRACKING || MPACK_WRITE_TRACKING
  496. #ifndef MPACK_TRACKING_INITIAL_CAPACITY
  497. // seems like a reasonable number. we grow by doubling, and it only
  498. // needs to be as long as the maximum depth of the message.
  499. #define MPACK_TRACKING_INITIAL_CAPACITY 8
  500. #endif
  501. mpack_error_t mpack_track_init(mpack_track_t* track) {
  502. track->count = 0;
  503. track->capacity = MPACK_TRACKING_INITIAL_CAPACITY;
  504. track->elements = (mpack_track_element_t*)MPACK_MALLOC(sizeof(mpack_track_element_t) * track->capacity);
  505. if (track->elements == NULL)
  506. return mpack_error_memory;
  507. return mpack_ok;
  508. }
  509. mpack_error_t mpack_track_grow(mpack_track_t* track) {
  510. mpack_assert(track->elements, "null track elements!");
  511. mpack_assert(track->count == track->capacity, "incorrect growing?");
  512. size_t new_capacity = track->capacity * 2;
  513. mpack_track_element_t* new_elements = (mpack_track_element_t*)mpack_realloc(track->elements,
  514. sizeof(mpack_track_element_t) * track->count, sizeof(mpack_track_element_t) * new_capacity);
  515. if (new_elements == NULL)
  516. return mpack_error_memory;
  517. track->elements = new_elements;
  518. track->capacity = new_capacity;
  519. return mpack_ok;
  520. }
  521. mpack_error_t mpack_track_push(mpack_track_t* track, mpack_type_t type, uint32_t count) {
  522. mpack_assert(track->elements, "null track elements!");
  523. mpack_log("track pushing %s count %i\n", mpack_type_to_string(type), (int)count);
  524. // grow if needed
  525. if (track->count == track->capacity) {
  526. mpack_error_t error = mpack_track_grow(track);
  527. if (error != mpack_ok)
  528. return error;
  529. }
  530. // insert new track
  531. track->elements[track->count].type = type;
  532. track->elements[track->count].left = count;
  533. track->elements[track->count].builder = false;
  534. track->elements[track->count].key_needs_value = false;
  535. ++track->count;
  536. return mpack_ok;
  537. }
  538. // TODO dedupe this
  539. mpack_error_t mpack_track_push_builder(mpack_track_t* track, mpack_type_t type) {
  540. mpack_assert(track->elements, "null track elements!");
  541. mpack_log("track pushing %s builder\n", mpack_type_to_string(type));
  542. // grow if needed
  543. if (track->count == track->capacity) {
  544. mpack_error_t error = mpack_track_grow(track);
  545. if (error != mpack_ok)
  546. return error;
  547. }
  548. // insert new track
  549. track->elements[track->count].type = type;
  550. track->elements[track->count].left = 0;
  551. track->elements[track->count].builder = true;
  552. track->elements[track->count].key_needs_value = false;
  553. ++track->count;
  554. return mpack_ok;
  555. }
  556. static mpack_error_t mpack_track_pop_impl(mpack_track_t* track, mpack_type_t type, bool builder) {
  557. mpack_assert(track->elements, "null track elements!");
  558. mpack_log("track popping %s\n", mpack_type_to_string(type));
  559. if (track->count == 0) {
  560. mpack_break("attempting to close a %s but nothing was opened!", mpack_type_to_string(type));
  561. return mpack_error_bug;
  562. }
  563. mpack_track_element_t* element = &track->elements[track->count - 1];
  564. if (element->type != type) {
  565. mpack_break("attempting to close a %s but the open element is a %s!",
  566. mpack_type_to_string(type), mpack_type_to_string(element->type));
  567. return mpack_error_bug;
  568. }
  569. if (element->key_needs_value) {
  570. mpack_assert(type == mpack_type_map, "key_needs_value can only be true for maps!");
  571. mpack_break("attempting to close a %s but an odd number of elements were written",
  572. mpack_type_to_string(type));
  573. return mpack_error_bug;
  574. }
  575. if (element->left != 0) {
  576. mpack_break("attempting to close a %s but there are %i %s left",
  577. mpack_type_to_string(type), element->left,
  578. (type == mpack_type_map || type == mpack_type_array) ? "elements" : "bytes");
  579. return mpack_error_bug;
  580. }
  581. if (element->builder != builder) {
  582. mpack_break("attempting to pop a %sbuilder but the open element is %sa builder",
  583. builder ? "" : "non-",
  584. element->builder ? "" : "not ");
  585. return mpack_error_bug;
  586. }
  587. --track->count;
  588. return mpack_ok;
  589. }
  590. mpack_error_t mpack_track_pop(mpack_track_t* track, mpack_type_t type) {
  591. return mpack_track_pop_impl(track, type, false);
  592. }
  593. mpack_error_t mpack_track_pop_builder(mpack_track_t* track, mpack_type_t type) {
  594. return mpack_track_pop_impl(track, type, true);
  595. }
  596. mpack_error_t mpack_track_peek_element(mpack_track_t* track, bool read) {
  597. MPACK_UNUSED(read);
  598. mpack_assert(track->elements, "null track elements!");
  599. // if there are no open elements, that's fine, we can read/write elements at will
  600. if (track->count == 0)
  601. return mpack_ok;
  602. mpack_track_element_t* element = &track->elements[track->count - 1];
  603. if (element->type != mpack_type_map && element->type != mpack_type_array) {
  604. mpack_break("elements cannot be %s within an %s", read ? "read" : "written",
  605. mpack_type_to_string(element->type));
  606. return mpack_error_bug;
  607. }
  608. if (!element->builder && element->left == 0 && !element->key_needs_value) {
  609. mpack_break("too many elements %s for %s", read ? "read" : "written",
  610. mpack_type_to_string(element->type));
  611. return mpack_error_bug;
  612. }
  613. return mpack_ok;
  614. }
  615. mpack_error_t mpack_track_element(mpack_track_t* track, bool read) {
  616. mpack_error_t error = mpack_track_peek_element(track, read);
  617. if (track->count == 0 || error != mpack_ok)
  618. return error;
  619. mpack_track_element_t* element = &track->elements[track->count - 1];
  620. if (element->type == mpack_type_map) {
  621. if (!element->key_needs_value) {
  622. element->key_needs_value = true;
  623. return mpack_ok; // don't decrement
  624. }
  625. element->key_needs_value = false;
  626. }
  627. if (!element->builder)
  628. --element->left;
  629. return mpack_ok;
  630. }
  631. mpack_error_t mpack_track_bytes(mpack_track_t* track, bool read, size_t count) {
  632. MPACK_UNUSED(read);
  633. mpack_assert(track->elements, "null track elements!");
  634. if (count > MPACK_UINT32_MAX) {
  635. mpack_break("%s more bytes than could possibly fit in a str/bin/ext!",
  636. read ? "reading" : "writing");
  637. return mpack_error_bug;
  638. }
  639. if (track->count == 0) {
  640. mpack_break("bytes cannot be %s with no open bin, str or ext", read ? "read" : "written");
  641. return mpack_error_bug;
  642. }
  643. mpack_track_element_t* element = &track->elements[track->count - 1];
  644. if (element->type == mpack_type_map || element->type == mpack_type_array) {
  645. mpack_break("bytes cannot be %s within an %s", read ? "read" : "written",
  646. mpack_type_to_string(element->type));
  647. return mpack_error_bug;
  648. }
  649. if (element->left < count) {
  650. mpack_break("too many bytes %s for %s", read ? "read" : "written",
  651. mpack_type_to_string(element->type));
  652. return mpack_error_bug;
  653. }
  654. element->left -= (uint32_t)count;
  655. return mpack_ok;
  656. }
  657. mpack_error_t mpack_track_str_bytes_all(mpack_track_t* track, bool read, size_t count) {
  658. mpack_error_t error = mpack_track_bytes(track, read, count);
  659. if (error != mpack_ok)
  660. return error;
  661. mpack_track_element_t* element = &track->elements[track->count - 1];
  662. if (element->type != mpack_type_str) {
  663. mpack_break("the open type must be a string, not a %s", mpack_type_to_string(element->type));
  664. return mpack_error_bug;
  665. }
  666. if (element->left != 0) {
  667. mpack_break("not all bytes were read; the wrong byte count was requested for a string read.");
  668. return mpack_error_bug;
  669. }
  670. return mpack_ok;
  671. }
  672. mpack_error_t mpack_track_check_empty(mpack_track_t* track) {
  673. if (track->count != 0) {
  674. mpack_break("unclosed %s", mpack_type_to_string(track->elements[0].type));
  675. return mpack_error_bug;
  676. }
  677. return mpack_ok;
  678. }
  679. mpack_error_t mpack_track_destroy(mpack_track_t* track, bool cancel) {
  680. mpack_error_t error = cancel ? mpack_ok : mpack_track_check_empty(track);
  681. if (track->elements) {
  682. MPACK_FREE(track->elements);
  683. track->elements = NULL;
  684. }
  685. return error;
  686. }
  687. #endif
  688. static bool mpack_utf8_check_impl(const uint8_t* str, size_t count, bool allow_null) {
  689. while (count > 0) {
  690. uint8_t lead = str[0];
  691. // NUL
  692. if (!allow_null && lead == '\0') // we don't allow NUL bytes in MPack C-strings
  693. return false;
  694. // ASCII
  695. if (lead <= 0x7F) {
  696. ++str;
  697. --count;
  698. // 2-byte sequence
  699. } else if ((lead & 0xE0) == 0xC0) {
  700. if (count < 2) // truncated sequence
  701. return false;
  702. uint8_t cont = str[1];
  703. if ((cont & 0xC0) != 0x80) // not a continuation byte
  704. return false;
  705. str += 2;
  706. count -= 2;
  707. uint32_t z = ((uint32_t)(lead & ~0xE0) << 6) |
  708. (uint32_t)(cont & ~0xC0);
  709. if (z < 0x80) // overlong sequence
  710. return false;
  711. // 3-byte sequence
  712. } else if ((lead & 0xF0) == 0xE0) {
  713. if (count < 3) // truncated sequence
  714. return false;
  715. uint8_t cont1 = str[1];
  716. if ((cont1 & 0xC0) != 0x80) // not a continuation byte
  717. return false;
  718. uint8_t cont2 = str[2];
  719. if ((cont2 & 0xC0) != 0x80) // not a continuation byte
  720. return false;
  721. str += 3;
  722. count -= 3;
  723. uint32_t z = ((uint32_t)(lead & ~0xF0) << 12) |
  724. ((uint32_t)(cont1 & ~0xC0) << 6) |
  725. (uint32_t)(cont2 & ~0xC0);
  726. if (z < 0x800) // overlong sequence
  727. return false;
  728. if (z >= 0xD800 && z <= 0xDFFF) // surrogate
  729. return false;
  730. // 4-byte sequence
  731. } else if ((lead & 0xF8) == 0xF0) {
  732. if (count < 4) // truncated sequence
  733. return false;
  734. uint8_t cont1 = str[1];
  735. if ((cont1 & 0xC0) != 0x80) // not a continuation byte
  736. return false;
  737. uint8_t cont2 = str[2];
  738. if ((cont2 & 0xC0) != 0x80) // not a continuation byte
  739. return false;
  740. uint8_t cont3 = str[3];
  741. if ((cont3 & 0xC0) != 0x80) // not a continuation byte
  742. return false;
  743. str += 4;
  744. count -= 4;
  745. uint32_t z = ((uint32_t)(lead & ~0xF8) << 18) |
  746. ((uint32_t)(cont1 & ~0xC0) << 12) |
  747. ((uint32_t)(cont2 & ~0xC0) << 6) |
  748. (uint32_t)(cont3 & ~0xC0);
  749. if (z < 0x10000) // overlong sequence
  750. return false;
  751. if (z > 0x10FFFF) // codepoint limit
  752. return false;
  753. } else {
  754. return false; // continuation byte without a lead, or lead for a 5-byte sequence or longer
  755. }
  756. }
  757. return true;
  758. }
  759. bool mpack_utf8_check(const char* str, size_t bytes) {
  760. return mpack_utf8_check_impl((const uint8_t*)str, bytes, true);
  761. }
  762. bool mpack_utf8_check_no_null(const char* str, size_t bytes) {
  763. return mpack_utf8_check_impl((const uint8_t*)str, bytes, false);
  764. }
  765. bool mpack_str_check_no_null(const char* str, size_t bytes) {
  766. size_t i;
  767. for (i = 0; i < bytes; ++i)
  768. if (str[i] == '\0')
  769. return false;
  770. return true;
  771. }
  772. #if MPACK_DEBUG && MPACK_STDIO
  773. void mpack_print_append(mpack_print_t* print, const char* data, size_t count) {
  774. // copy whatever fits into the buffer
  775. size_t copy = print->size - print->count;
  776. if (copy > count)
  777. copy = count;
  778. mpack_memcpy(print->buffer + print->count, data, copy);
  779. print->count += copy;
  780. data += copy;
  781. count -= copy;
  782. // if we don't need to flush or can't flush there's nothing else to do
  783. if (count == 0 || print->callback == NULL)
  784. return;
  785. // flush the buffer
  786. print->callback(print->context, print->buffer, print->count);
  787. if (count > print->size / 2) {
  788. // flush the rest of the data
  789. print->count = 0;
  790. print->callback(print->context, data, count);
  791. } else {
  792. // copy the rest of the data into the buffer
  793. mpack_memcpy(print->buffer, data, count);
  794. print->count = count;
  795. }
  796. }
  797. void mpack_print_flush(mpack_print_t* print) {
  798. if (print->count > 0 && print->callback != NULL) {
  799. print->callback(print->context, print->buffer, print->count);
  800. print->count = 0;
  801. }
  802. }
  803. void mpack_print_file_callback(void* context, const char* data, size_t count) {
  804. FILE* file = (FILE*)context;
  805. fwrite(data, 1, count, file);
  806. }
  807. #endif
  808. MPACK_SILENCE_WARNINGS_END
  809. /* mpack/mpack-writer.c.c */
  810. #define MPACK_INTERNAL 1
  811. /* #include "mpack-writer.h" */
  812. MPACK_SILENCE_WARNINGS_BEGIN
  813. #if MPACK_WRITER
  814. #if MPACK_BUILDER
  815. static void mpack_builder_flush(mpack_writer_t* writer);
  816. #endif
  817. #if MPACK_WRITE_TRACKING
  818. static void mpack_writer_flag_if_error(mpack_writer_t* writer, mpack_error_t error) {
  819. if (error != mpack_ok)
  820. mpack_writer_flag_error(writer, error);
  821. }
  822. void mpack_writer_track_push(mpack_writer_t* writer, mpack_type_t type, uint32_t count) {
  823. if (writer->error == mpack_ok)
  824. mpack_writer_flag_if_error(writer, mpack_track_push(&writer->track, type, count));
  825. }
  826. void mpack_writer_track_push_builder(mpack_writer_t* writer, mpack_type_t type) {
  827. if (writer->error == mpack_ok)
  828. mpack_writer_flag_if_error(writer, mpack_track_push_builder(&writer->track, type));
  829. }
  830. void mpack_writer_track_pop(mpack_writer_t* writer, mpack_type_t type) {
  831. if (writer->error == mpack_ok)
  832. mpack_writer_flag_if_error(writer, mpack_track_pop(&writer->track, type));
  833. }
  834. void mpack_writer_track_pop_builder(mpack_writer_t* writer, mpack_type_t type) {
  835. if (writer->error == mpack_ok)
  836. mpack_writer_flag_if_error(writer, mpack_track_pop_builder(&writer->track, type));
  837. }
  838. void mpack_writer_track_bytes(mpack_writer_t* writer, size_t count) {
  839. if (writer->error == mpack_ok)
  840. mpack_writer_flag_if_error(writer, mpack_track_bytes(&writer->track, false, count));
  841. }
  842. #endif
  843. // This should probably be renamed. It's not solely used for tracking.
  844. static inline void mpack_writer_track_element(mpack_writer_t* writer) {
  845. (void)writer;
  846. #if MPACK_WRITE_TRACKING
  847. if (writer->error == mpack_ok)
  848. mpack_writer_flag_if_error(writer, mpack_track_element(&writer->track, false));
  849. #endif
  850. #if MPACK_BUILDER
  851. if (writer->builder.current_build != NULL) {
  852. mpack_build_t* build = writer->builder.current_build;
  853. // We only track this write if it's not nested within another non-build
  854. // map or array.
  855. if (build->nested_compound_elements == 0) {
  856. if (build->type != mpack_type_map) {
  857. ++build->count;
  858. mpack_log("adding element to build %p, now %" PRIu32 " elements\n", (void*)build, build->count);
  859. } else if (build->key_needs_value) {
  860. build->key_needs_value = false;
  861. ++build->count;
  862. } else {
  863. build->key_needs_value = true;
  864. }
  865. }
  866. }
  867. #endif
  868. }
  869. static void mpack_writer_clear(mpack_writer_t* writer) {
  870. #if MPACK_COMPATIBILITY
  871. writer->version = mpack_version_current;
  872. #endif
  873. writer->flush = NULL;
  874. writer->error_fn = NULL;
  875. writer->teardown = NULL;
  876. writer->context = NULL;
  877. writer->buffer = NULL;
  878. writer->position = NULL;
  879. writer->end = NULL;
  880. writer->error = mpack_ok;
  881. #if MPACK_WRITE_TRACKING
  882. mpack_memset(&writer->track, 0, sizeof(writer->track));
  883. #endif
  884. #if MPACK_BUILDER
  885. writer->builder.current_build = NULL;
  886. writer->builder.latest_build = NULL;
  887. writer->builder.current_page = NULL;
  888. writer->builder.pages = NULL;
  889. writer->builder.stash_buffer = NULL;
  890. writer->builder.stash_position = NULL;
  891. writer->builder.stash_end = NULL;
  892. #endif
  893. }
  894. void mpack_writer_init(mpack_writer_t* writer, char* buffer, size_t size) {
  895. mpack_assert(buffer != NULL, "cannot initialize writer with empty buffer");
  896. mpack_writer_clear(writer);
  897. writer->buffer = buffer;
  898. writer->position = buffer;
  899. writer->end = writer->buffer + size;
  900. #if MPACK_WRITE_TRACKING
  901. mpack_writer_flag_if_error(writer, mpack_track_init(&writer->track));
  902. #endif
  903. mpack_log("===========================\n");
  904. mpack_log("initializing writer with buffer size %i\n", (int)size);
  905. }
  906. void mpack_writer_init_error(mpack_writer_t* writer, mpack_error_t error) {
  907. mpack_writer_clear(writer);
  908. writer->error = error;
  909. mpack_log("===========================\n");
  910. mpack_log("initializing writer in error state %i\n", (int)error);
  911. }
  912. void mpack_writer_set_flush(mpack_writer_t* writer, mpack_writer_flush_t flush) {
  913. MPACK_STATIC_ASSERT(MPACK_WRITER_MINIMUM_BUFFER_SIZE >= MPACK_MAXIMUM_TAG_SIZE,
  914. "minimum buffer size must fit any tag!");
  915. MPACK_STATIC_ASSERT(31 + MPACK_TAG_SIZE_FIXSTR >= MPACK_WRITER_MINIMUM_BUFFER_SIZE,
  916. "minimum buffer size must fit the largest possible fixstr!");
  917. if (mpack_writer_buffer_size(writer) < MPACK_WRITER_MINIMUM_BUFFER_SIZE) {
  918. mpack_break("buffer size is %i, but minimum buffer size for flush is %i",
  919. (int)mpack_writer_buffer_size(writer), MPACK_WRITER_MINIMUM_BUFFER_SIZE);
  920. mpack_writer_flag_error(writer, mpack_error_bug);
  921. return;
  922. }
  923. writer->flush = flush;
  924. }
  925. #ifdef MPACK_MALLOC
  926. typedef struct mpack_growable_writer_t {
  927. char** target_data;
  928. size_t* target_size;
  929. } mpack_growable_writer_t;
  930. static char* mpack_writer_get_reserved(mpack_writer_t* writer) {
  931. // This is in a separate function in order to avoid false strict aliasing
  932. // warnings. We aren't actually violating strict aliasing (the reserved
  933. // space is only ever dereferenced as an mpack_growable_writer_t.)
  934. return (char*)writer->reserved;
  935. }
  936. static void mpack_growable_writer_flush(mpack_writer_t* writer, const char* data, size_t count) {
  937. // This is an intrusive flush function which modifies the writer's buffer
  938. // in response to a flush instead of emptying it in order to add more
  939. // capacity for data. This removes the need to copy data from a fixed buffer
  940. // into a growable one, improving performance.
  941. //
  942. // There are three ways flush can be called:
  943. // - flushing the buffer during writing (used is zero, count is all data, data is buffer)
  944. // - flushing extra data during writing (used is all flushed data, count is extra data, data is not buffer)
  945. // - flushing during teardown (used and count are both all flushed data, data is buffer)
  946. //
  947. // In the first two cases, we grow the buffer by at least double, enough
  948. // to ensure that new data will fit. We ignore the teardown flush.
  949. if (data == writer->buffer) {
  950. // teardown, do nothing
  951. if (mpack_writer_buffer_used(writer) == count)
  952. return;
  953. // otherwise leave the data in the buffer and just grow
  954. writer->position = writer->buffer + count;
  955. count = 0;
  956. }
  957. size_t used = mpack_writer_buffer_used(writer);
  958. size_t size = mpack_writer_buffer_size(writer);
  959. mpack_log("flush size %i used %i data %p buffer %p\n",
  960. (int)count, (int)used, data, writer->buffer);
  961. mpack_assert(data == writer->buffer || used + count > size,
  962. "extra flush for %i but there is %i space left in the buffer! (%i/%i)",
  963. (int)count, (int)mpack_writer_buffer_left(writer), (int)used, (int)size);
  964. // grow to fit the data
  965. // TODO: this really needs to correctly test for overflow
  966. size_t new_size = size * 2;
  967. while (new_size < used + count)
  968. new_size *= 2;
  969. mpack_log("flush growing buffer size from %i to %i\n", (int)size, (int)new_size);
  970. // grow the buffer
  971. char* new_buffer = (char*)mpack_realloc(writer->buffer, used, new_size);
  972. if (new_buffer == NULL) {
  973. mpack_writer_flag_error(writer, mpack_error_memory);
  974. return;
  975. }
  976. writer->position = new_buffer + used;
  977. writer->buffer = new_buffer;
  978. writer->end = writer->buffer + new_size;
  979. // append the extra data
  980. if (count > 0) {
  981. mpack_memcpy(writer->position, data, count);
  982. writer->position += count;
  983. }
  984. mpack_log("new buffer %p, used %i\n", new_buffer, (int)mpack_writer_buffer_used(writer));
  985. }
  986. static void mpack_growable_writer_teardown(mpack_writer_t* writer) {
  987. mpack_growable_writer_t* growable_writer = (mpack_growable_writer_t*)mpack_writer_get_reserved(writer);
  988. if (mpack_writer_error(writer) == mpack_ok) {
  989. // shrink the buffer to an appropriate size if the data is
  990. // much smaller than the buffer
  991. if (mpack_writer_buffer_used(writer) < mpack_writer_buffer_size(writer) / 2) {
  992. size_t used = mpack_writer_buffer_used(writer);
  993. // We always return a non-null pointer that must be freed, even if
  994. // nothing was written. malloc() and realloc() do not necessarily
  995. // do this so we enforce it ourselves.
  996. size_t size = (used != 0) ? used : 1;
  997. char* buffer = (char*)mpack_realloc(writer->buffer, used, size);
  998. if (!buffer) {
  999. MPACK_FREE(writer->buffer);
  1000. mpack_writer_flag_error(writer, mpack_error_memory);
  1001. return;
  1002. }
  1003. writer->buffer = buffer;
  1004. writer->end = (writer->position = writer->buffer + used);
  1005. }
  1006. *growable_writer->target_data = writer->buffer;
  1007. *growable_writer->target_size = mpack_writer_buffer_used(writer);
  1008. writer->buffer = NULL;
  1009. } else if (writer->buffer) {
  1010. MPACK_FREE(writer->buffer);
  1011. writer->buffer = NULL;
  1012. }
  1013. writer->context = NULL;
  1014. }
  1015. void mpack_writer_init_growable(mpack_writer_t* writer, char** target_data, size_t* target_size) {
  1016. mpack_assert(target_data != NULL, "cannot initialize writer without a destination for the data");
  1017. mpack_assert(target_size != NULL, "cannot initialize writer without a destination for the size");
  1018. *target_data = NULL;
  1019. *target_size = 0;
  1020. MPACK_STATIC_ASSERT(sizeof(mpack_growable_writer_t) <= sizeof(writer->reserved),
  1021. "not enough reserved space for growable writer!");
  1022. mpack_growable_writer_t* growable_writer = (mpack_growable_writer_t*)mpack_writer_get_reserved(writer);
  1023. growable_writer->target_data = target_data;
  1024. growable_writer->target_size = target_size;
  1025. size_t capacity = MPACK_BUFFER_SIZE;
  1026. char* buffer = (char*)MPACK_MALLOC(capacity);
  1027. if (buffer == NULL) {
  1028. mpack_writer_init_error(writer, mpack_error_memory);
  1029. return;
  1030. }
  1031. mpack_writer_init(writer, buffer, capacity);
  1032. mpack_writer_set_flush(writer, mpack_growable_writer_flush);
  1033. mpack_writer_set_teardown(writer, mpack_growable_writer_teardown);
  1034. }
  1035. #endif
  1036. #if MPACK_STDIO
  1037. static void mpack_file_writer_flush(mpack_writer_t* writer, const char* buffer, size_t count) {
  1038. FILE* file = (FILE*)writer->context;
  1039. size_t written = fwrite((const void*)buffer, 1, count, file);
  1040. if (written != count)
  1041. mpack_writer_flag_error(writer, mpack_error_io);
  1042. }
  1043. static void mpack_file_writer_teardown(mpack_writer_t* writer) {
  1044. MPACK_FREE(writer->buffer);
  1045. writer->buffer = NULL;
  1046. writer->context = NULL;
  1047. }
  1048. static void mpack_file_writer_teardown_close(mpack_writer_t* writer) {
  1049. FILE* file = (FILE*)writer->context;
  1050. if (file) {
  1051. int ret = fclose(file);
  1052. if (ret != 0)
  1053. mpack_writer_flag_error(writer, mpack_error_io);
  1054. }
  1055. mpack_file_writer_teardown(writer);
  1056. }
  1057. void mpack_writer_init_stdfile(mpack_writer_t* writer, FILE* file, bool close_when_done) {
  1058. mpack_assert(file != NULL, "file is NULL");
  1059. size_t capacity = MPACK_BUFFER_SIZE;
  1060. char* buffer = (char*)MPACK_MALLOC(capacity);
  1061. if (buffer == NULL) {
  1062. mpack_writer_init_error(writer, mpack_error_memory);
  1063. if (close_when_done) {
  1064. fclose(file);
  1065. }
  1066. return;
  1067. }
  1068. mpack_writer_init(writer, buffer, capacity);
  1069. mpack_writer_set_context(writer, file);
  1070. mpack_writer_set_flush(writer, mpack_file_writer_flush);
  1071. mpack_writer_set_teardown(writer, close_when_done ?
  1072. mpack_file_writer_teardown_close :
  1073. mpack_file_writer_teardown);
  1074. }
  1075. void mpack_writer_init_filename(mpack_writer_t* writer, const char* filename) {
  1076. mpack_assert(filename != NULL, "filename is NULL");
  1077. FILE* file = fopen(filename, "wb");
  1078. if (file == NULL) {
  1079. mpack_writer_init_error(writer, mpack_error_io);
  1080. return;
  1081. }
  1082. mpack_writer_init_stdfile(writer, file, true);
  1083. }
  1084. #endif
  1085. void mpack_writer_flag_error(mpack_writer_t* writer, mpack_error_t error) {
  1086. mpack_log("writer %p setting error %i: %s\n", (void*)writer, (int)error, mpack_error_to_string(error));
  1087. if (writer->error == mpack_ok) {
  1088. writer->error = error;
  1089. if (writer->error_fn)
  1090. writer->error_fn(writer, writer->error);
  1091. }
  1092. }
  1093. MPACK_STATIC_INLINE void mpack_writer_flush_unchecked(mpack_writer_t* writer) {
  1094. // This is a bit ugly; we reset used before calling flush so that
  1095. // a flush function can distinguish between flushing the buffer
  1096. // versus flushing external data. see mpack_growable_writer_flush()
  1097. size_t used = mpack_writer_buffer_used(writer);
  1098. writer->position = writer->buffer;
  1099. writer->flush(writer, writer->buffer, used);
  1100. }
  1101. void mpack_writer_flush_message(mpack_writer_t* writer) {
  1102. if (writer->error != mpack_ok)
  1103. return;
  1104. #if MPACK_WRITE_TRACKING
  1105. // You cannot flush while there are elements open.
  1106. mpack_writer_flag_if_error(writer, mpack_track_check_empty(&writer->track));
  1107. if (writer->error != mpack_ok)
  1108. return;
  1109. #endif
  1110. #if MPACK_BUILDER
  1111. if (writer->builder.current_build != NULL) {
  1112. mpack_break("cannot call mpack_writer_flush_message() while there are elements open!");
  1113. mpack_writer_flag_error(writer, mpack_error_bug);
  1114. return;
  1115. }
  1116. #endif
  1117. if (writer->flush == NULL) {
  1118. mpack_break("cannot call mpack_writer_flush_message() without a flush function!");
  1119. mpack_writer_flag_error(writer, mpack_error_bug);
  1120. return;
  1121. }
  1122. if (mpack_writer_buffer_used(writer) > 0)
  1123. mpack_writer_flush_unchecked(writer);
  1124. }
  1125. // Ensures there are at least count bytes free in the buffer. This
  1126. // will flag an error if the flush function fails to make enough
  1127. // room in the buffer.
  1128. MPACK_NOINLINE static bool mpack_writer_ensure(mpack_writer_t* writer, size_t count) {
  1129. mpack_assert(count != 0, "cannot ensure zero bytes!");
  1130. mpack_assert(count <= MPACK_WRITER_MINIMUM_BUFFER_SIZE,
  1131. "cannot ensure %i bytes, this is more than the minimum buffer size %i!",
  1132. (int)count, (int)MPACK_WRITER_MINIMUM_BUFFER_SIZE);
  1133. mpack_assert(count > mpack_writer_buffer_left(writer),
  1134. "request to ensure %i bytes but there are already %i left in the buffer!",
  1135. (int)count, (int)mpack_writer_buffer_left(writer));
  1136. mpack_log("ensuring %i bytes, %i left\n", (int)count, (int)mpack_writer_buffer_left(writer));
  1137. if (mpack_writer_error(writer) != mpack_ok)
  1138. return false;
  1139. #if MPACK_BUILDER
  1140. // if we have a build in progress, we just ask the builder for a page.
  1141. // either it will have space for a tag, or it will flag a memory error.
  1142. if (writer->builder.current_build != NULL) {
  1143. mpack_builder_flush(writer);
  1144. return mpack_writer_error(writer) == mpack_ok;
  1145. }
  1146. #endif
  1147. if (writer->flush == NULL) {
  1148. mpack_writer_flag_error(writer, mpack_error_too_big);
  1149. return false;
  1150. }
  1151. mpack_writer_flush_unchecked(writer);
  1152. if (mpack_writer_error(writer) != mpack_ok)
  1153. return false;
  1154. if (mpack_writer_buffer_left(writer) >= count)
  1155. return true;
  1156. mpack_writer_flag_error(writer, mpack_error_io);
  1157. return false;
  1158. }
  1159. // Writes encoded bytes to the buffer when we already know the data
  1160. // does not fit in the buffer (i.e. it straddles the edge of the
  1161. // buffer.) If there is a flush function, it is guaranteed to be
  1162. // called; otherwise mpack_error_too_big is raised.
  1163. MPACK_NOINLINE static void mpack_write_native_straddle(mpack_writer_t* writer, const char* p, size_t count) {
  1164. mpack_assert(count == 0 || p != NULL, "data pointer for %i bytes is NULL", (int)count);
  1165. if (mpack_writer_error(writer) != mpack_ok)
  1166. return;
  1167. mpack_log("big write for %i bytes from %p, %i space left in buffer\n",
  1168. (int)count, p, (int)mpack_writer_buffer_left(writer));
  1169. mpack_assert(count > mpack_writer_buffer_left(writer),
  1170. "big write requested for %i bytes, but there is %i available "
  1171. "space in buffer. should have called mpack_write_native() instead",
  1172. (int)count, (int)(mpack_writer_buffer_left(writer)));
  1173. #if MPACK_BUILDER
  1174. // if we have a build in progress, we can't flush. we need to copy all
  1175. // bytes into as many build buffer pages as it takes.
  1176. if (writer->builder.current_build != NULL) {
  1177. while (true) {
  1178. size_t step = (size_t)(writer->end - writer->position);
  1179. if (step > count)
  1180. step = count;
  1181. mpack_memcpy(writer->position, p, step);
  1182. writer->position += step;
  1183. p += step;
  1184. count -= step;
  1185. if (count == 0)
  1186. return;
  1187. mpack_builder_flush(writer);
  1188. if (mpack_writer_error(writer) != mpack_ok)
  1189. return;
  1190. mpack_assert(writer->position != writer->end);
  1191. }
  1192. }
  1193. #endif
  1194. // we'll need a flush function
  1195. if (!writer->flush) {
  1196. mpack_writer_flag_error(writer, mpack_error_too_big);
  1197. return;
  1198. }
  1199. // flush the buffer
  1200. mpack_writer_flush_unchecked(writer);
  1201. if (mpack_writer_error(writer) != mpack_ok)
  1202. return;
  1203. // note that an intrusive flush function (such as mpack_growable_writer_flush())
  1204. // may have changed size and/or reset used to a non-zero value. we treat both as
  1205. // though they may have changed, and there may still be data in the buffer.
  1206. // flush the extra data directly if it doesn't fit in the buffer
  1207. if (count > mpack_writer_buffer_left(writer)) {
  1208. writer->flush(writer, p, count);
  1209. if (mpack_writer_error(writer) != mpack_ok)
  1210. return;
  1211. } else {
  1212. mpack_memcpy(writer->position, p, count);
  1213. writer->position += count;
  1214. }
  1215. }
  1216. // Writes encoded bytes to the buffer, flushing if necessary.
  1217. MPACK_STATIC_INLINE void mpack_write_native(mpack_writer_t* writer, const char* p, size_t count) {
  1218. mpack_assert(count == 0 || p != NULL, "data pointer for %i bytes is NULL", (int)count);
  1219. if (mpack_writer_buffer_left(writer) < count) {
  1220. mpack_write_native_straddle(writer, p, count);
  1221. } else {
  1222. mpack_memcpy(writer->position, p, count);
  1223. writer->position += count;
  1224. }
  1225. }
  1226. mpack_error_t mpack_writer_destroy(mpack_writer_t* writer) {
  1227. // clean up tracking, asserting if we're not already in an error state
  1228. #if MPACK_WRITE_TRACKING
  1229. mpack_track_destroy(&writer->track, writer->error != mpack_ok);
  1230. #endif
  1231. #if MPACK_BUILDER
  1232. mpack_builder_t* builder = &writer->builder;
  1233. if (builder->current_build != NULL) {
  1234. // A builder is open!
  1235. // Flag an error, if there's not already an error. You can only skip
  1236. // closing any open compound types if a write error occurred. If there
  1237. // wasn't already an error, it's a bug, which will assert in debug.
  1238. if (mpack_writer_error(writer) == mpack_ok) {
  1239. mpack_break("writer cannot be destroyed with an incomplete builder unless "
  1240. "an error was flagged!");
  1241. mpack_writer_flag_error(writer, mpack_error_bug);
  1242. }
  1243. // Free any remaining builder pages
  1244. mpack_builder_page_t* page = builder->pages;
  1245. #if MPACK_BUILDER_INTERNAL_STORAGE
  1246. mpack_assert(page == (mpack_builder_page_t*)builder->internal);
  1247. page = page->next;
  1248. #endif
  1249. while (page != NULL) {
  1250. mpack_builder_page_t* next = page->next;
  1251. MPACK_FREE(page);
  1252. page = next;
  1253. }
  1254. // Restore the stashed pointers. The teardown function may need to free
  1255. // them (e.g. mpack_growable_writer_teardown().)
  1256. writer->buffer = builder->stash_buffer;
  1257. writer->position = builder->stash_position;
  1258. writer->end = builder->stash_end;
  1259. // Note: It's not necessary to clean up the current_build or other
  1260. // pointers at this point because we're guaranteed to be in an error
  1261. // state already so a user error callback can't longjmp out. This
  1262. // destroy function will complete no matter what so it doesn't matter
  1263. // what junk is left in the writer.
  1264. }
  1265. #endif
  1266. // flush any outstanding data
  1267. if (mpack_writer_error(writer) == mpack_ok && mpack_writer_buffer_used(writer) != 0 && writer->flush != NULL) {
  1268. writer->flush(writer, writer->buffer, mpack_writer_buffer_used(writer));
  1269. writer->flush = NULL;
  1270. }
  1271. if (writer->teardown) {
  1272. writer->teardown(writer);
  1273. writer->teardown = NULL;
  1274. }
  1275. return writer->error;
  1276. }
  1277. void mpack_write_tag(mpack_writer_t* writer, mpack_tag_t value) {
  1278. switch (value.type) {
  1279. case mpack_type_missing:
  1280. mpack_break("cannot write a missing value!");
  1281. mpack_writer_flag_error(writer, mpack_error_bug);
  1282. return;
  1283. case mpack_type_nil: mpack_write_nil (writer); return;
  1284. case mpack_type_bool: mpack_write_bool (writer, value.v.b); return;
  1285. case mpack_type_int: mpack_write_int (writer, value.v.i); return;
  1286. case mpack_type_uint: mpack_write_uint (writer, value.v.u); return;
  1287. case mpack_type_float:
  1288. #if MPACK_FLOAT
  1289. mpack_write_float
  1290. #else
  1291. mpack_write_raw_float
  1292. #endif
  1293. (writer, value.v.f);
  1294. return;
  1295. case mpack_type_double:
  1296. #if MPACK_DOUBLE
  1297. mpack_write_double
  1298. #else
  1299. mpack_write_raw_double
  1300. #endif
  1301. (writer, value.v.d);
  1302. return;
  1303. case mpack_type_str: mpack_start_str(writer, value.v.l); return;
  1304. case mpack_type_bin: mpack_start_bin(writer, value.v.l); return;
  1305. #if MPACK_EXTENSIONS
  1306. case mpack_type_ext:
  1307. mpack_start_ext(writer, mpack_tag_ext_exttype(&value), mpack_tag_ext_length(&value));
  1308. return;
  1309. #endif
  1310. case mpack_type_array: mpack_start_array(writer, value.v.n); return;
  1311. case mpack_type_map: mpack_start_map(writer, value.v.n); return;
  1312. }
  1313. mpack_break("unrecognized type %i", (int)value.type);
  1314. mpack_writer_flag_error(writer, mpack_error_bug);
  1315. }
  1316. MPACK_STATIC_INLINE void mpack_write_byte_element(mpack_writer_t* writer, char value) {
  1317. mpack_writer_track_element(writer);
  1318. if (MPACK_LIKELY(mpack_writer_buffer_left(writer) >= 1) || mpack_writer_ensure(writer, 1))
  1319. *(writer->position++) = value;
  1320. }
  1321. void mpack_write_nil(mpack_writer_t* writer) {
  1322. mpack_write_byte_element(writer, (char)0xc0);
  1323. }
  1324. void mpack_write_bool(mpack_writer_t* writer, bool value) {
  1325. mpack_write_byte_element(writer, (char)(0xc2 | (value ? 1 : 0)));
  1326. }
  1327. void mpack_write_true(mpack_writer_t* writer) {
  1328. mpack_write_byte_element(writer, (char)0xc3);
  1329. }
  1330. void mpack_write_false(mpack_writer_t* writer) {
  1331. mpack_write_byte_element(writer, (char)0xc2);
  1332. }
  1333. void mpack_write_object_bytes(mpack_writer_t* writer, const char* data, size_t bytes) {
  1334. mpack_writer_track_element(writer);
  1335. mpack_write_native(writer, data, bytes);
  1336. }
  1337. /*
  1338. * Encode functions
  1339. */
  1340. MPACK_STATIC_INLINE void mpack_encode_fixuint(char* p, uint8_t value) {
  1341. mpack_assert(value <= 127);
  1342. mpack_store_u8(p, value);
  1343. }
  1344. MPACK_STATIC_INLINE void mpack_encode_u8(char* p, uint8_t value) {
  1345. mpack_assert(value > 127);
  1346. mpack_store_u8(p, 0xcc);
  1347. mpack_store_u8(p + 1, value);
  1348. }
  1349. MPACK_STATIC_INLINE void mpack_encode_u16(char* p, uint16_t value) {
  1350. mpack_assert(value > MPACK_UINT8_MAX);
  1351. mpack_store_u8(p, 0xcd);
  1352. mpack_store_u16(p + 1, value);
  1353. }
  1354. MPACK_STATIC_INLINE void mpack_encode_u32(char* p, uint32_t value) {
  1355. mpack_assert(value > MPACK_UINT16_MAX);
  1356. mpack_store_u8(p, 0xce);
  1357. mpack_store_u32(p + 1, value);
  1358. }
  1359. MPACK_STATIC_INLINE void mpack_encode_u64(char* p, uint64_t value) {
  1360. mpack_assert(value > MPACK_UINT32_MAX);
  1361. mpack_store_u8(p, 0xcf);
  1362. mpack_store_u64(p + 1, value);
  1363. }
  1364. MPACK_STATIC_INLINE void mpack_encode_fixint(char* p, int8_t value) {
  1365. // this can encode positive or negative fixints
  1366. mpack_assert(value >= -32);
  1367. mpack_store_i8(p, value);
  1368. }
  1369. MPACK_STATIC_INLINE void mpack_encode_i8(char* p, int8_t value) {
  1370. mpack_assert(value < -32);
  1371. mpack_store_u8(p, 0xd0);
  1372. mpack_store_i8(p + 1, value);
  1373. }
  1374. MPACK_STATIC_INLINE void mpack_encode_i16(char* p, int16_t value) {
  1375. mpack_assert(value < MPACK_INT8_MIN);
  1376. mpack_store_u8(p, 0xd1);
  1377. mpack_store_i16(p + 1, value);
  1378. }
  1379. MPACK_STATIC_INLINE void mpack_encode_i32(char* p, int32_t value) {
  1380. mpack_assert(value < MPACK_INT16_MIN);
  1381. mpack_store_u8(p, 0xd2);
  1382. mpack_store_i32(p + 1, value);
  1383. }
  1384. MPACK_STATIC_INLINE void mpack_encode_i64(char* p, int64_t value) {
  1385. mpack_assert(value < MPACK_INT32_MIN);
  1386. mpack_store_u8(p, 0xd3);
  1387. mpack_store_i64(p + 1, value);
  1388. }
  1389. #if MPACK_FLOAT
  1390. MPACK_STATIC_INLINE void mpack_encode_float(char* p, float value) {
  1391. mpack_store_u8(p, 0xca);
  1392. mpack_store_float(p + 1, value);
  1393. }
  1394. #else
  1395. MPACK_STATIC_INLINE void mpack_encode_raw_float(char* p, uint32_t value) {
  1396. mpack_store_u8(p, 0xca);
  1397. mpack_store_u32(p + 1, value);
  1398. }
  1399. #endif
  1400. #if MPACK_DOUBLE
  1401. MPACK_STATIC_INLINE void mpack_encode_double(char* p, double value) {
  1402. mpack_store_u8(p, 0xcb);
  1403. mpack_store_double(p + 1, value);
  1404. }
  1405. #else
  1406. MPACK_STATIC_INLINE void mpack_encode_raw_double(char* p, uint64_t value) {
  1407. mpack_store_u8(p, 0xcb);
  1408. mpack_store_u64(p + 1, value);
  1409. }
  1410. #endif
  1411. MPACK_STATIC_INLINE void mpack_encode_fixarray(char* p, uint8_t count) {
  1412. mpack_assert(count <= 15);
  1413. mpack_store_u8(p, (uint8_t)(0x90 | count));
  1414. }
  1415. MPACK_STATIC_INLINE void mpack_encode_array16(char* p, uint16_t count) {
  1416. mpack_assert(count > 15);
  1417. mpack_store_u8(p, 0xdc);
  1418. mpack_store_u16(p + 1, count);
  1419. }
  1420. MPACK_STATIC_INLINE void mpack_encode_array32(char* p, uint32_t count) {
  1421. mpack_assert(count > MPACK_UINT16_MAX);
  1422. mpack_store_u8(p, 0xdd);
  1423. mpack_store_u32(p + 1, count);
  1424. }
  1425. MPACK_STATIC_INLINE void mpack_encode_fixmap(char* p, uint8_t count) {
  1426. mpack_assert(count <= 15);
  1427. mpack_store_u8(p, (uint8_t)(0x80 | count));
  1428. }
  1429. MPACK_STATIC_INLINE void mpack_encode_map16(char* p, uint16_t count) {
  1430. mpack_assert(count > 15);
  1431. mpack_store_u8(p, 0xde);
  1432. mpack_store_u16(p + 1, count);
  1433. }
  1434. MPACK_STATIC_INLINE void mpack_encode_map32(char* p, uint32_t count) {
  1435. mpack_assert(count > MPACK_UINT16_MAX);
  1436. mpack_store_u8(p, 0xdf);
  1437. mpack_store_u32(p + 1, count);
  1438. }
  1439. MPACK_STATIC_INLINE void mpack_encode_fixstr(char* p, uint8_t count) {
  1440. mpack_assert(count <= 31);
  1441. mpack_store_u8(p, (uint8_t)(0xa0 | count));
  1442. }
  1443. MPACK_STATIC_INLINE void mpack_encode_str8(char* p, uint8_t count) {
  1444. mpack_assert(count > 31);
  1445. mpack_store_u8(p, 0xd9);
  1446. mpack_store_u8(p + 1, count);
  1447. }
  1448. MPACK_STATIC_INLINE void mpack_encode_str16(char* p, uint16_t count) {
  1449. // we might be encoding a raw in compatibility mode, so we
  1450. // allow count to be in the range [32, MPACK_UINT8_MAX].
  1451. mpack_assert(count > 31);
  1452. mpack_store_u8(p, 0xda);
  1453. mpack_store_u16(p + 1, count);
  1454. }
  1455. MPACK_STATIC_INLINE void mpack_encode_str32(char* p, uint32_t count) {
  1456. mpack_assert(count > MPACK_UINT16_MAX);
  1457. mpack_store_u8(p, 0xdb);
  1458. mpack_store_u32(p + 1, count);
  1459. }
  1460. MPACK_STATIC_INLINE void mpack_encode_bin8(char* p, uint8_t count) {
  1461. mpack_store_u8(p, 0xc4);
  1462. mpack_store_u8(p + 1, count);
  1463. }
  1464. MPACK_STATIC_INLINE void mpack_encode_bin16(char* p, uint16_t count) {
  1465. mpack_assert(count > MPACK_UINT8_MAX);
  1466. mpack_store_u8(p, 0xc5);
  1467. mpack_store_u16(p + 1, count);
  1468. }
  1469. MPACK_STATIC_INLINE void mpack_encode_bin32(char* p, uint32_t count) {
  1470. mpack_assert(count > MPACK_UINT16_MAX);
  1471. mpack_store_u8(p, 0xc6);
  1472. mpack_store_u32(p + 1, count);
  1473. }
  1474. #if MPACK_EXTENSIONS
  1475. MPACK_STATIC_INLINE void mpack_encode_fixext1(char* p, int8_t exttype) {
  1476. mpack_store_u8(p, 0xd4);
  1477. mpack_store_i8(p + 1, exttype);
  1478. }
  1479. MPACK_STATIC_INLINE void mpack_encode_fixext2(char* p, int8_t exttype) {
  1480. mpack_store_u8(p, 0xd5);
  1481. mpack_store_i8(p + 1, exttype);
  1482. }
  1483. MPACK_STATIC_INLINE void mpack_encode_fixext4(char* p, int8_t exttype) {
  1484. mpack_store_u8(p, 0xd6);
  1485. mpack_store_i8(p + 1, exttype);
  1486. }
  1487. MPACK_STATIC_INLINE void mpack_encode_fixext8(char* p, int8_t exttype) {
  1488. mpack_store_u8(p, 0xd7);
  1489. mpack_store_i8(p + 1, exttype);
  1490. }
  1491. MPACK_STATIC_INLINE void mpack_encode_fixext16(char* p, int8_t exttype) {
  1492. mpack_store_u8(p, 0xd8);
  1493. mpack_store_i8(p + 1, exttype);
  1494. }
  1495. MPACK_STATIC_INLINE void mpack_encode_ext8(char* p, int8_t exttype, uint8_t count) {
  1496. mpack_assert(count != 1 && count != 2 && count != 4 && count != 8 && count != 16);
  1497. mpack_store_u8(p, 0xc7);
  1498. mpack_store_u8(p + 1, count);
  1499. mpack_store_i8(p + 2, exttype);
  1500. }
  1501. MPACK_STATIC_INLINE void mpack_encode_ext16(char* p, int8_t exttype, uint16_t count) {
  1502. mpack_assert(count > MPACK_UINT8_MAX);
  1503. mpack_store_u8(p, 0xc8);
  1504. mpack_store_u16(p + 1, count);
  1505. mpack_store_i8(p + 3, exttype);
  1506. }
  1507. MPACK_STATIC_INLINE void mpack_encode_ext32(char* p, int8_t exttype, uint32_t count) {
  1508. mpack_assert(count > MPACK_UINT16_MAX);
  1509. mpack_store_u8(p, 0xc9);
  1510. mpack_store_u32(p + 1, count);
  1511. mpack_store_i8(p + 5, exttype);
  1512. }
  1513. MPACK_STATIC_INLINE void mpack_encode_timestamp_4(char* p, uint32_t seconds) {
  1514. mpack_encode_fixext4(p, MPACK_EXTTYPE_TIMESTAMP);
  1515. mpack_store_u32(p + MPACK_TAG_SIZE_FIXEXT4, seconds);
  1516. }
  1517. MPACK_STATIC_INLINE void mpack_encode_timestamp_8(char* p, int64_t seconds, uint32_t nanoseconds) {
  1518. mpack_assert(nanoseconds <= MPACK_TIMESTAMP_NANOSECONDS_MAX);
  1519. mpack_encode_fixext8(p, MPACK_EXTTYPE_TIMESTAMP);
  1520. uint64_t encoded = ((uint64_t)nanoseconds << 34) | (uint64_t)seconds;
  1521. mpack_store_u64(p + MPACK_TAG_SIZE_FIXEXT8, encoded);
  1522. }
  1523. MPACK_STATIC_INLINE void mpack_encode_timestamp_12(char* p, int64_t seconds, uint32_t nanoseconds) {
  1524. mpack_assert(nanoseconds <= MPACK_TIMESTAMP_NANOSECONDS_MAX);
  1525. mpack_encode_ext8(p, MPACK_EXTTYPE_TIMESTAMP, 12);
  1526. mpack_store_u32(p + MPACK_TAG_SIZE_EXT8, nanoseconds);
  1527. mpack_store_i64(p + MPACK_TAG_SIZE_EXT8 + 4, seconds);
  1528. }
  1529. #endif
  1530. /*
  1531. * Write functions
  1532. */
  1533. // This is a macro wrapper to the encode functions to encode
  1534. // directly into the buffer. If mpack_writer_ensure() fails
  1535. // it will flag an error so we don't have to do anything.
  1536. #define MPACK_WRITE_ENCODED(encode_fn, size, ...) do { \
  1537. if (MPACK_LIKELY(mpack_writer_buffer_left(writer) >= size) || mpack_writer_ensure(writer, size)) { \
  1538. MPACK_EXPAND(encode_fn(writer->position, __VA_ARGS__)); \
  1539. writer->position += size; \
  1540. } \
  1541. } while (0)
  1542. void mpack_write_u8(mpack_writer_t* writer, uint8_t value) {
  1543. #if MPACK_OPTIMIZE_FOR_SIZE
  1544. mpack_write_u64(writer, value);
  1545. #else
  1546. mpack_writer_track_element(writer);
  1547. if (value <= 127) {
  1548. MPACK_WRITE_ENCODED(mpack_encode_fixuint, MPACK_TAG_SIZE_FIXUINT, value);
  1549. } else {
  1550. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, value);
  1551. }
  1552. #endif
  1553. }
  1554. void mpack_write_u16(mpack_writer_t* writer, uint16_t value) {
  1555. #if MPACK_OPTIMIZE_FOR_SIZE
  1556. mpack_write_u64(writer, value);
  1557. #else
  1558. mpack_writer_track_element(writer);
  1559. if (value <= 127) {
  1560. MPACK_WRITE_ENCODED(mpack_encode_fixuint, MPACK_TAG_SIZE_FIXUINT, (uint8_t)value);
  1561. } else if (value <= MPACK_UINT8_MAX) {
  1562. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1563. } else {
  1564. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, value);
  1565. }
  1566. #endif
  1567. }
  1568. void mpack_write_u32(mpack_writer_t* writer, uint32_t value) {
  1569. #if MPACK_OPTIMIZE_FOR_SIZE
  1570. mpack_write_u64(writer, value);
  1571. #else
  1572. mpack_writer_track_element(writer);
  1573. if (value <= 127) {
  1574. MPACK_WRITE_ENCODED(mpack_encode_fixuint, MPACK_TAG_SIZE_FIXUINT, (uint8_t)value);
  1575. } else if (value <= MPACK_UINT8_MAX) {
  1576. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1577. } else if (value <= MPACK_UINT16_MAX) {
  1578. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, (uint16_t)value);
  1579. } else {
  1580. MPACK_WRITE_ENCODED(mpack_encode_u32, MPACK_TAG_SIZE_U32, value);
  1581. }
  1582. #endif
  1583. }
  1584. void mpack_write_u64(mpack_writer_t* writer, uint64_t value) {
  1585. mpack_writer_track_element(writer);
  1586. if (value <= 127) {
  1587. MPACK_WRITE_ENCODED(mpack_encode_fixuint, MPACK_TAG_SIZE_FIXUINT, (uint8_t)value);
  1588. } else if (value <= MPACK_UINT8_MAX) {
  1589. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1590. } else if (value <= MPACK_UINT16_MAX) {
  1591. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, (uint16_t)value);
  1592. } else if (value <= MPACK_UINT32_MAX) {
  1593. MPACK_WRITE_ENCODED(mpack_encode_u32, MPACK_TAG_SIZE_U32, (uint32_t)value);
  1594. } else {
  1595. MPACK_WRITE_ENCODED(mpack_encode_u64, MPACK_TAG_SIZE_U64, value);
  1596. }
  1597. }
  1598. void mpack_write_i8(mpack_writer_t* writer, int8_t value) {
  1599. #if MPACK_OPTIMIZE_FOR_SIZE
  1600. mpack_write_i64(writer, value);
  1601. #else
  1602. mpack_writer_track_element(writer);
  1603. if (value >= -32) {
  1604. // we encode positive and negative fixints together
  1605. MPACK_WRITE_ENCODED(mpack_encode_fixint, MPACK_TAG_SIZE_FIXINT, (int8_t)value);
  1606. } else {
  1607. MPACK_WRITE_ENCODED(mpack_encode_i8, MPACK_TAG_SIZE_I8, (int8_t)value);
  1608. }
  1609. #endif
  1610. }
  1611. void mpack_write_i16(mpack_writer_t* writer, int16_t value) {
  1612. #if MPACK_OPTIMIZE_FOR_SIZE
  1613. mpack_write_i64(writer, value);
  1614. #else
  1615. mpack_writer_track_element(writer);
  1616. if (value >= -32) {
  1617. if (value <= 127) {
  1618. // we encode positive and negative fixints together
  1619. MPACK_WRITE_ENCODED(mpack_encode_fixint, MPACK_TAG_SIZE_FIXINT, (int8_t)value);
  1620. } else if (value <= MPACK_UINT8_MAX) {
  1621. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1622. } else {
  1623. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, (uint16_t)value);
  1624. }
  1625. } else if (value >= MPACK_INT8_MIN) {
  1626. MPACK_WRITE_ENCODED(mpack_encode_i8, MPACK_TAG_SIZE_I8, (int8_t)value);
  1627. } else {
  1628. MPACK_WRITE_ENCODED(mpack_encode_i16, MPACK_TAG_SIZE_I16, (int16_t)value);
  1629. }
  1630. #endif
  1631. }
  1632. void mpack_write_i32(mpack_writer_t* writer, int32_t value) {
  1633. #if MPACK_OPTIMIZE_FOR_SIZE
  1634. mpack_write_i64(writer, value);
  1635. #else
  1636. mpack_writer_track_element(writer);
  1637. if (value >= -32) {
  1638. if (value <= 127) {
  1639. // we encode positive and negative fixints together
  1640. MPACK_WRITE_ENCODED(mpack_encode_fixint, MPACK_TAG_SIZE_FIXINT, (int8_t)value);
  1641. } else if (value <= MPACK_UINT8_MAX) {
  1642. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1643. } else if (value <= MPACK_UINT16_MAX) {
  1644. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, (uint16_t)value);
  1645. } else {
  1646. MPACK_WRITE_ENCODED(mpack_encode_u32, MPACK_TAG_SIZE_U32, (uint32_t)value);
  1647. }
  1648. } else if (value >= MPACK_INT8_MIN) {
  1649. MPACK_WRITE_ENCODED(mpack_encode_i8, MPACK_TAG_SIZE_I8, (int8_t)value);
  1650. } else if (value >= MPACK_INT16_MIN) {
  1651. MPACK_WRITE_ENCODED(mpack_encode_i16, MPACK_TAG_SIZE_I16, (int16_t)value);
  1652. } else {
  1653. MPACK_WRITE_ENCODED(mpack_encode_i32, MPACK_TAG_SIZE_I32, value);
  1654. }
  1655. #endif
  1656. }
  1657. void mpack_write_i64(mpack_writer_t* writer, int64_t value) {
  1658. #if MPACK_OPTIMIZE_FOR_SIZE
  1659. if (value > 127) {
  1660. // for non-fix positive ints we call the u64 writer to save space
  1661. mpack_write_u64(writer, (uint64_t)value);
  1662. return;
  1663. }
  1664. #endif
  1665. mpack_writer_track_element(writer);
  1666. if (value >= -32) {
  1667. #if MPACK_OPTIMIZE_FOR_SIZE
  1668. MPACK_WRITE_ENCODED(mpack_encode_fixint, MPACK_TAG_SIZE_FIXINT, (int8_t)value);
  1669. #else
  1670. if (value <= 127) {
  1671. MPACK_WRITE_ENCODED(mpack_encode_fixint, MPACK_TAG_SIZE_FIXINT, (int8_t)value);
  1672. } else if (value <= MPACK_UINT8_MAX) {
  1673. MPACK_WRITE_ENCODED(mpack_encode_u8, MPACK_TAG_SIZE_U8, (uint8_t)value);
  1674. } else if (value <= MPACK_UINT16_MAX) {
  1675. MPACK_WRITE_ENCODED(mpack_encode_u16, MPACK_TAG_SIZE_U16, (uint16_t)value);
  1676. } else if (value <= MPACK_UINT32_MAX) {
  1677. MPACK_WRITE_ENCODED(mpack_encode_u32, MPACK_TAG_SIZE_U32, (uint32_t)value);
  1678. } else {
  1679. MPACK_WRITE_ENCODED(mpack_encode_u64, MPACK_TAG_SIZE_U64, (uint64_t)value);
  1680. }
  1681. #endif
  1682. } else if (value >= MPACK_INT8_MIN) {
  1683. MPACK_WRITE_ENCODED(mpack_encode_i8, MPACK_TAG_SIZE_I8, (int8_t)value);
  1684. } else if (value >= MPACK_INT16_MIN) {
  1685. MPACK_WRITE_ENCODED(mpack_encode_i16, MPACK_TAG_SIZE_I16, (int16_t)value);
  1686. } else if (value >= MPACK_INT32_MIN) {
  1687. MPACK_WRITE_ENCODED(mpack_encode_i32, MPACK_TAG_SIZE_I32, (int32_t)value);
  1688. } else {
  1689. MPACK_WRITE_ENCODED(mpack_encode_i64, MPACK_TAG_SIZE_I64, value);
  1690. }
  1691. }
  1692. #if MPACK_FLOAT
  1693. void mpack_write_float(mpack_writer_t* writer, float value) {
  1694. mpack_writer_track_element(writer);
  1695. MPACK_WRITE_ENCODED(mpack_encode_float, MPACK_TAG_SIZE_FLOAT, value);
  1696. }
  1697. #else
  1698. void mpack_write_raw_float(mpack_writer_t* writer, uint32_t value) {
  1699. mpack_writer_track_element(writer);
  1700. MPACK_WRITE_ENCODED(mpack_encode_raw_float, MPACK_TAG_SIZE_FLOAT, value);
  1701. }
  1702. #endif
  1703. #if MPACK_DOUBLE
  1704. void mpack_write_double(mpack_writer_t* writer, double value) {
  1705. mpack_writer_track_element(writer);
  1706. MPACK_WRITE_ENCODED(mpack_encode_double, MPACK_TAG_SIZE_DOUBLE, value);
  1707. }
  1708. #else
  1709. void mpack_write_raw_double(mpack_writer_t* writer, uint64_t value) {
  1710. mpack_writer_track_element(writer);
  1711. MPACK_WRITE_ENCODED(mpack_encode_raw_double, MPACK_TAG_SIZE_DOUBLE, value);
  1712. }
  1713. #endif
  1714. #if MPACK_EXTENSIONS
  1715. void mpack_write_timestamp(mpack_writer_t* writer, int64_t seconds, uint32_t nanoseconds) {
  1716. #if MPACK_COMPATIBILITY
  1717. if (writer->version <= mpack_version_v4) {
  1718. mpack_break("Timestamps require spec version v5 or later. This writer is in v%i mode.", (int)writer->version);
  1719. mpack_writer_flag_error(writer, mpack_error_bug);
  1720. return;
  1721. }
  1722. #endif
  1723. if (nanoseconds > MPACK_TIMESTAMP_NANOSECONDS_MAX) {
  1724. mpack_break("timestamp nanoseconds out of bounds: %" PRIu32 , nanoseconds);
  1725. mpack_writer_flag_error(writer, mpack_error_bug);
  1726. return;
  1727. }
  1728. mpack_writer_track_element(writer);
  1729. if (seconds < 0 || seconds >= (MPACK_INT64_C(1) << 34)) {
  1730. MPACK_WRITE_ENCODED(mpack_encode_timestamp_12, MPACK_EXT_SIZE_TIMESTAMP12, seconds, nanoseconds);
  1731. } else if (seconds > MPACK_UINT32_MAX || nanoseconds > 0) {
  1732. MPACK_WRITE_ENCODED(mpack_encode_timestamp_8, MPACK_EXT_SIZE_TIMESTAMP8, seconds, nanoseconds);
  1733. } else {
  1734. MPACK_WRITE_ENCODED(mpack_encode_timestamp_4, MPACK_EXT_SIZE_TIMESTAMP4, (uint32_t)seconds);
  1735. }
  1736. }
  1737. #endif
  1738. static void mpack_write_array_notrack(mpack_writer_t* writer, uint32_t count) {
  1739. if (count <= 15) {
  1740. MPACK_WRITE_ENCODED(mpack_encode_fixarray, MPACK_TAG_SIZE_FIXARRAY, (uint8_t)count);
  1741. } else if (count <= MPACK_UINT16_MAX) {
  1742. MPACK_WRITE_ENCODED(mpack_encode_array16, MPACK_TAG_SIZE_ARRAY16, (uint16_t)count);
  1743. } else {
  1744. MPACK_WRITE_ENCODED(mpack_encode_array32, MPACK_TAG_SIZE_ARRAY32, (uint32_t)count);
  1745. }
  1746. }
  1747. static void mpack_write_map_notrack(mpack_writer_t* writer, uint32_t count) {
  1748. if (count <= 15) {
  1749. MPACK_WRITE_ENCODED(mpack_encode_fixmap, MPACK_TAG_SIZE_FIXMAP, (uint8_t)count);
  1750. } else if (count <= MPACK_UINT16_MAX) {
  1751. MPACK_WRITE_ENCODED(mpack_encode_map16, MPACK_TAG_SIZE_MAP16, (uint16_t)count);
  1752. } else {
  1753. MPACK_WRITE_ENCODED(mpack_encode_map32, MPACK_TAG_SIZE_MAP32, (uint32_t)count);
  1754. }
  1755. }
  1756. void mpack_start_array(mpack_writer_t* writer, uint32_t count) {
  1757. mpack_writer_track_element(writer);
  1758. mpack_write_array_notrack(writer, count);
  1759. mpack_writer_track_push(writer, mpack_type_array, count);
  1760. mpack_builder_compound_push(writer);
  1761. }
  1762. void mpack_start_map(mpack_writer_t* writer, uint32_t count) {
  1763. mpack_writer_track_element(writer);
  1764. mpack_write_map_notrack(writer, count);
  1765. mpack_writer_track_push(writer, mpack_type_map, count);
  1766. mpack_builder_compound_push(writer);
  1767. }
  1768. static void mpack_start_str_notrack(mpack_writer_t* writer, uint32_t count) {
  1769. if (count <= 31) {
  1770. MPACK_WRITE_ENCODED(mpack_encode_fixstr, MPACK_TAG_SIZE_FIXSTR, (uint8_t)count);
  1771. // str8 is only supported in v5 or later.
  1772. } else if (count <= MPACK_UINT8_MAX
  1773. #if MPACK_COMPATIBILITY
  1774. && writer->version >= mpack_version_v5
  1775. #endif
  1776. ) {
  1777. MPACK_WRITE_ENCODED(mpack_encode_str8, MPACK_TAG_SIZE_STR8, (uint8_t)count);
  1778. } else if (count <= MPACK_UINT16_MAX) {
  1779. MPACK_WRITE_ENCODED(mpack_encode_str16, MPACK_TAG_SIZE_STR16, (uint16_t)count);
  1780. } else {
  1781. MPACK_WRITE_ENCODED(mpack_encode_str32, MPACK_TAG_SIZE_STR32, (uint32_t)count);
  1782. }
  1783. }
  1784. static void mpack_start_bin_notrack(mpack_writer_t* writer, uint32_t count) {
  1785. #if MPACK_COMPATIBILITY
  1786. // In the v4 spec, there was only the raw type for any kind of
  1787. // variable-length data. In v4 mode, we support the bin functions,
  1788. // but we produce an old-style raw.
  1789. if (writer->version <= mpack_version_v4) {
  1790. mpack_start_str_notrack(writer, count);
  1791. return;
  1792. }
  1793. #endif
  1794. if (count <= MPACK_UINT8_MAX) {
  1795. MPACK_WRITE_ENCODED(mpack_encode_bin8, MPACK_TAG_SIZE_BIN8, (uint8_t)count);
  1796. } else if (count <= MPACK_UINT16_MAX) {
  1797. MPACK_WRITE_ENCODED(mpack_encode_bin16, MPACK_TAG_SIZE_BIN16, (uint16_t)count);
  1798. } else {
  1799. MPACK_WRITE_ENCODED(mpack_encode_bin32, MPACK_TAG_SIZE_BIN32, (uint32_t)count);
  1800. }
  1801. }
  1802. void mpack_start_str(mpack_writer_t* writer, uint32_t count) {
  1803. mpack_writer_track_element(writer);
  1804. mpack_start_str_notrack(writer, count);
  1805. mpack_writer_track_push(writer, mpack_type_str, count);
  1806. }
  1807. void mpack_start_bin(mpack_writer_t* writer, uint32_t count) {
  1808. mpack_writer_track_element(writer);
  1809. mpack_start_bin_notrack(writer, count);
  1810. mpack_writer_track_push(writer, mpack_type_bin, count);
  1811. }
  1812. #if MPACK_EXTENSIONS
  1813. void mpack_start_ext(mpack_writer_t* writer, int8_t exttype, uint32_t count) {
  1814. #if MPACK_COMPATIBILITY
  1815. if (writer->version <= mpack_version_v4) {
  1816. mpack_break("Ext types require spec version v5 or later. This writer is in v%i mode.", (int)writer->version);
  1817. mpack_writer_flag_error(writer, mpack_error_bug);
  1818. return;
  1819. }
  1820. #endif
  1821. mpack_writer_track_element(writer);
  1822. if (count == 1) {
  1823. MPACK_WRITE_ENCODED(mpack_encode_fixext1, MPACK_TAG_SIZE_FIXEXT1, exttype);
  1824. } else if (count == 2) {
  1825. MPACK_WRITE_ENCODED(mpack_encode_fixext2, MPACK_TAG_SIZE_FIXEXT2, exttype);
  1826. } else if (count == 4) {
  1827. MPACK_WRITE_ENCODED(mpack_encode_fixext4, MPACK_TAG_SIZE_FIXEXT4, exttype);
  1828. } else if (count == 8) {
  1829. MPACK_WRITE_ENCODED(mpack_encode_fixext8, MPACK_TAG_SIZE_FIXEXT8, exttype);
  1830. } else if (count == 16) {
  1831. MPACK_WRITE_ENCODED(mpack_encode_fixext16, MPACK_TAG_SIZE_FIXEXT16, exttype);
  1832. } else if (count <= MPACK_UINT8_MAX) {
  1833. MPACK_WRITE_ENCODED(mpack_encode_ext8, MPACK_TAG_SIZE_EXT8, exttype, (uint8_t)count);
  1834. } else if (count <= MPACK_UINT16_MAX) {
  1835. MPACK_WRITE_ENCODED(mpack_encode_ext16, MPACK_TAG_SIZE_EXT16, exttype, (uint16_t)count);
  1836. } else {
  1837. MPACK_WRITE_ENCODED(mpack_encode_ext32, MPACK_TAG_SIZE_EXT32, exttype, (uint32_t)count);
  1838. }
  1839. mpack_writer_track_push(writer, mpack_type_ext, count);
  1840. }
  1841. #endif
  1842. /*
  1843. * Compound helpers and other functions
  1844. */
  1845. void mpack_write_str(mpack_writer_t* writer, const char* data, uint32_t count) {
  1846. mpack_assert(count == 0 || data != NULL, "data for string of length %i is NULL", (int)count);
  1847. #if MPACK_OPTIMIZE_FOR_SIZE
  1848. mpack_writer_track_element(writer);
  1849. mpack_start_str_notrack(writer, count);
  1850. mpack_write_native(writer, data, count);
  1851. #else
  1852. mpack_writer_track_element(writer);
  1853. if (count <= 31) {
  1854. // The minimum buffer size when using a flush function is guaranteed to
  1855. // fit the largest possible fixstr.
  1856. size_t size = count + MPACK_TAG_SIZE_FIXSTR;
  1857. if (MPACK_LIKELY(mpack_writer_buffer_left(writer) >= size) || mpack_writer_ensure(writer, size)) {
  1858. char* MPACK_RESTRICT p = writer->position;
  1859. mpack_encode_fixstr(p, (uint8_t)count);
  1860. mpack_memcpy(p + MPACK_TAG_SIZE_FIXSTR, data, count);
  1861. writer->position += count + MPACK_TAG_SIZE_FIXSTR;
  1862. }
  1863. return;
  1864. }
  1865. if (count <= MPACK_UINT8_MAX
  1866. #if MPACK_COMPATIBILITY
  1867. && writer->version >= mpack_version_v5
  1868. #endif
  1869. ) {
  1870. if (count + MPACK_TAG_SIZE_STR8 <= mpack_writer_buffer_left(writer)) {
  1871. char* MPACK_RESTRICT p = writer->position;
  1872. mpack_encode_str8(p, (uint8_t)count);
  1873. mpack_memcpy(p + MPACK_TAG_SIZE_STR8, data, count);
  1874. writer->position += count + MPACK_TAG_SIZE_STR8;
  1875. } else {
  1876. MPACK_WRITE_ENCODED(mpack_encode_str8, MPACK_TAG_SIZE_STR8, (uint8_t)count);
  1877. mpack_write_native(writer, data, count);
  1878. }
  1879. return;
  1880. }
  1881. // str16 and str32 are likely to be a significant fraction of the buffer
  1882. // size, so we don't bother with a combined space check in order to
  1883. // minimize code size.
  1884. if (count <= MPACK_UINT16_MAX) {
  1885. MPACK_WRITE_ENCODED(mpack_encode_str16, MPACK_TAG_SIZE_STR16, (uint16_t)count);
  1886. mpack_write_native(writer, data, count);
  1887. } else {
  1888. MPACK_WRITE_ENCODED(mpack_encode_str32, MPACK_TAG_SIZE_STR32, (uint32_t)count);
  1889. mpack_write_native(writer, data, count);
  1890. }
  1891. #endif
  1892. }
  1893. void mpack_write_bin(mpack_writer_t* writer, const char* data, uint32_t count) {
  1894. mpack_assert(count == 0 || data != NULL, "data pointer for bin of %i bytes is NULL", (int)count);
  1895. mpack_start_bin(writer, count);
  1896. mpack_write_bytes(writer, data, count);
  1897. mpack_finish_bin(writer);
  1898. }
  1899. #if MPACK_EXTENSIONS
  1900. void mpack_write_ext(mpack_writer_t* writer, int8_t exttype, const char* data, uint32_t count) {
  1901. mpack_assert(count == 0 || data != NULL, "data pointer for ext of type %i and %i bytes is NULL", exttype, (int)count);
  1902. mpack_start_ext(writer, exttype, count);
  1903. mpack_write_bytes(writer, data, count);
  1904. mpack_finish_ext(writer);
  1905. }
  1906. #endif
  1907. void mpack_write_bytes(mpack_writer_t* writer, const char* data, size_t count) {
  1908. mpack_assert(count == 0 || data != NULL, "data pointer for %i bytes is NULL", (int)count);
  1909. mpack_writer_track_bytes(writer, count);
  1910. mpack_write_native(writer, data, count);
  1911. }
  1912. void mpack_write_cstr(mpack_writer_t* writer, const char* cstr) {
  1913. mpack_assert(cstr != NULL, "cstr pointer is NULL");
  1914. size_t length = mpack_strlen(cstr);
  1915. if (length > MPACK_UINT32_MAX)
  1916. mpack_writer_flag_error(writer, mpack_error_invalid);
  1917. mpack_write_str(writer, cstr, (uint32_t)length);
  1918. }
  1919. void mpack_write_cstr_or_nil(mpack_writer_t* writer, const char* cstr) {
  1920. if (cstr)
  1921. mpack_write_cstr(writer, cstr);
  1922. else
  1923. mpack_write_nil(writer);
  1924. }
  1925. void mpack_write_utf8(mpack_writer_t* writer, const char* str, uint32_t length) {
  1926. mpack_assert(length == 0 || str != NULL, "data for string of length %i is NULL", (int)length);
  1927. if (!mpack_utf8_check(str, length)) {
  1928. mpack_writer_flag_error(writer, mpack_error_invalid);
  1929. return;
  1930. }
  1931. mpack_write_str(writer, str, length);
  1932. }
  1933. void mpack_write_utf8_cstr(mpack_writer_t* writer, const char* cstr) {
  1934. mpack_assert(cstr != NULL, "cstr pointer is NULL");
  1935. size_t length = mpack_strlen(cstr);
  1936. if (length > MPACK_UINT32_MAX) {
  1937. mpack_writer_flag_error(writer, mpack_error_invalid);
  1938. return;
  1939. }
  1940. mpack_write_utf8(writer, cstr, (uint32_t)length);
  1941. }
  1942. void mpack_write_utf8_cstr_or_nil(mpack_writer_t* writer, const char* cstr) {
  1943. if (cstr)
  1944. mpack_write_utf8_cstr(writer, cstr);
  1945. else
  1946. mpack_write_nil(writer);
  1947. }
  1948. /*
  1949. * Builder implementation
  1950. *
  1951. * When a writer is in build mode, it diverts writes to an internal growable
  1952. * buffer. All elements other than builder start tags are encoded as normal
  1953. * into the builder buffer (even nested maps and arrays of known size, e.g.
  1954. * `mpack_start_array()`.) But for compound elements of unknown size, an
  1955. * mpack_build_t is written to the buffer instead.
  1956. *
  1957. * The mpack_build_t tracks everything needed to re-constitute the final
  1958. * message once all sizes are known. When the last build element is completed,
  1959. * the builder resolves the build by walking through the builds, outputting the
  1960. * final encoded tag, and copying everything in between to the writer's true
  1961. * buffer.
  1962. *
  1963. * To make things extra complicated, the builder buffer is not contiguous. It's
  1964. * allocated in pages, where the first page may be an internal page in the
  1965. * writer. But, each mpack_build_t must itself be contiguous and aligned
  1966. * properly within the buffer. This means bytes can be skipped (and wasted)
  1967. * before the builds or at the end of pages.
  1968. *
  1969. * To keep track of this, builds store both their element count and the number
  1970. * of encoded bytes that follow, and pages store the number of bytes used. As
  1971. * elements are written, each element adds to the count in the current open
  1972. * build, and the number of bytes written adds to the current page and the byte
  1973. * count in the last started build (whether or not it is completed.)
  1974. */
  1975. #if MPACK_BUILDER
  1976. #ifdef MPACK_ALIGNOF
  1977. #define MPACK_BUILD_ALIGNMENT MPACK_ALIGNOF(mpack_build_t)
  1978. #else
  1979. // without alignof, we just align to the greater of size_t, void* and uint64_t.
  1980. // (we do this even though we don't have uint64_t in it in case we add it later.)
  1981. #define MPACK_BUILD_ALIGNMENT_MAX(x, y) ((x) > (y) ? (x) : (y))
  1982. #define MPACK_BUILD_ALIGNMENT (MPACK_BUILD_ALIGNMENT_MAX(sizeof(void*), \
  1983. MPACK_BUILD_ALIGNMENT_MAX(sizeof(size_t), sizeof(uint64_t))))
  1984. #endif
  1985. static inline void mpack_builder_check_sizes(mpack_writer_t* writer) {
  1986. // We check internal and page sizes here so that we don't have to check
  1987. // them again. A new page with a build in it will have a page header,
  1988. // build, and minimum space for a tag. This will perform horribly and waste
  1989. // tons of memory if the page size is small, so you're best off just
  1990. // sticking with the defaults.
  1991. //
  1992. // These are all known at compile time, so if they are large
  1993. // enough this function should trivially optimize to a no-op.
  1994. #if MPACK_BUILDER_INTERNAL_STORAGE
  1995. // make sure the internal storage is big enough to be useful
  1996. MPACK_STATIC_ASSERT(MPACK_BUILDER_INTERNAL_STORAGE_SIZE >= (sizeof(mpack_builder_page_t) +
  1997. sizeof(mpack_build_t) + MPACK_WRITER_MINIMUM_BUFFER_SIZE),
  1998. "MPACK_BUILDER_INTERNAL_STORAGE_SIZE is too small to be useful!");
  1999. if (MPACK_BUILDER_INTERNAL_STORAGE_SIZE < (sizeof(mpack_builder_page_t) +
  2000. sizeof(mpack_build_t) + MPACK_WRITER_MINIMUM_BUFFER_SIZE))
  2001. {
  2002. mpack_break("MPACK_BUILDER_INTERNAL_STORAGE_SIZE is too small to be useful!");
  2003. mpack_writer_flag_error(writer, mpack_error_bug);
  2004. }
  2005. #endif
  2006. // make sure the builder page size is big enough to be useful
  2007. MPACK_STATIC_ASSERT(MPACK_BUILDER_PAGE_SIZE >= (sizeof(mpack_builder_page_t) +
  2008. sizeof(mpack_build_t) + MPACK_WRITER_MINIMUM_BUFFER_SIZE),
  2009. "MPACK_BUILDER_PAGE_SIZE is too small to be useful!");
  2010. if (MPACK_BUILDER_PAGE_SIZE < (sizeof(mpack_builder_page_t) +
  2011. sizeof(mpack_build_t) + MPACK_WRITER_MINIMUM_BUFFER_SIZE))
  2012. {
  2013. mpack_break("MPACK_BUILDER_PAGE_SIZE is too small to be useful!");
  2014. mpack_writer_flag_error(writer, mpack_error_bug);
  2015. }
  2016. }
  2017. static inline size_t mpack_builder_page_size(mpack_writer_t* writer, mpack_builder_page_t* page) {
  2018. #if MPACK_BUILDER_INTERNAL_STORAGE
  2019. if ((char*)page == writer->builder.internal)
  2020. return sizeof(writer->builder.internal);
  2021. #else
  2022. (void)writer;
  2023. (void)page;
  2024. #endif
  2025. return MPACK_BUILDER_PAGE_SIZE;
  2026. }
  2027. static inline size_t mpack_builder_align_build(size_t bytes_used) {
  2028. size_t offset = bytes_used;
  2029. offset += MPACK_BUILD_ALIGNMENT - 1;
  2030. offset -= offset % MPACK_BUILD_ALIGNMENT;
  2031. mpack_log("aligned %zi to %zi\n", bytes_used, offset);
  2032. return offset;
  2033. }
  2034. static inline void mpack_builder_free_page(mpack_writer_t* writer, mpack_builder_page_t* page) {
  2035. mpack_log("freeing page %p\n", (void*)page);
  2036. #if MPACK_BUILDER_INTERNAL_STORAGE
  2037. if ((char*)page == writer->builder.internal)
  2038. return;
  2039. #else
  2040. (void)writer;
  2041. #endif
  2042. MPACK_FREE(page);
  2043. }
  2044. static inline size_t mpack_builder_page_remaining(mpack_writer_t* writer, mpack_builder_page_t* page) {
  2045. return mpack_builder_page_size(writer, page) - page->bytes_used;
  2046. }
  2047. static void mpack_builder_configure_buffer(mpack_writer_t* writer) {
  2048. if (mpack_writer_error(writer) != mpack_ok)
  2049. return;
  2050. mpack_builder_t* builder = &writer->builder;
  2051. mpack_builder_page_t* page = builder->current_page;
  2052. mpack_assert(page != NULL, "page is null??");
  2053. // This diverts the writer into the remainder of the current page of our
  2054. // build buffer.
  2055. writer->buffer = (char*)page + page->bytes_used;
  2056. writer->position = (char*)page + page->bytes_used;
  2057. writer->end = (char*)page + mpack_builder_page_size(writer, page);
  2058. mpack_log("configuring buffer from %p to %p\n", (void*)writer->position, (void*)writer->end);
  2059. }
  2060. static void mpack_builder_add_page(mpack_writer_t* writer) {
  2061. mpack_builder_t* builder = &writer->builder;
  2062. mpack_assert(writer->error == mpack_ok);
  2063. mpack_log("adding a page.\n");
  2064. mpack_builder_page_t* page = (mpack_builder_page_t*)MPACK_MALLOC(MPACK_BUILDER_PAGE_SIZE);
  2065. if (page == NULL) {
  2066. mpack_writer_flag_error(writer, mpack_error_memory);
  2067. return;
  2068. }
  2069. page->next = NULL;
  2070. page->bytes_used = sizeof(mpack_builder_page_t);
  2071. builder->current_page->next = page;
  2072. builder->current_page = page;
  2073. }
  2074. // Checks how many bytes the writer wrote to the page, adding it to the page's
  2075. // bytes_used. This must be followed up with mpack_builder_configure_buffer()
  2076. // (after adding a new page, build, etc) to reset the writer's buffer pointers.
  2077. static void mpack_builder_apply_writes(mpack_writer_t* writer) {
  2078. mpack_assert(writer->error == mpack_ok);
  2079. mpack_builder_t* builder = &writer->builder;
  2080. mpack_log("latest build is %p\n", (void*)builder->latest_build);
  2081. // The difference between buffer and current is the number of bytes that
  2082. // were written to the page.
  2083. size_t bytes_written = (size_t)(writer->position - writer->buffer);
  2084. mpack_log("applying write of %zi bytes to build %p\n", bytes_written, (void*)builder->latest_build);
  2085. mpack_assert(builder->current_page != NULL);
  2086. mpack_assert(builder->latest_build != NULL);
  2087. builder->current_page->bytes_used += bytes_written;
  2088. builder->latest_build->bytes += bytes_written;
  2089. mpack_log("latest build %p now has %zi bytes\n", (void*)builder->latest_build, builder->latest_build->bytes);
  2090. }
  2091. static void mpack_builder_flush(mpack_writer_t* writer) {
  2092. mpack_assert(writer->error == mpack_ok);
  2093. mpack_builder_apply_writes(writer);
  2094. mpack_builder_add_page(writer);
  2095. mpack_builder_configure_buffer(writer);
  2096. }
  2097. MPACK_NOINLINE static void mpack_builder_begin(mpack_writer_t* writer) {
  2098. mpack_builder_t* builder = &writer->builder;
  2099. mpack_assert(writer->error == mpack_ok);
  2100. mpack_assert(builder->current_build == NULL);
  2101. mpack_assert(builder->latest_build == NULL);
  2102. mpack_assert(builder->pages == NULL);
  2103. // If this is the first build, we need to stash the real buffer backing our
  2104. // writer. We'll be diverting the writer to our build buffer.
  2105. builder->stash_buffer = writer->buffer;
  2106. builder->stash_position = writer->position;
  2107. builder->stash_end = writer->end;
  2108. mpack_builder_page_t* page;
  2109. // we've checked that both these sizes are large enough above.
  2110. #if MPACK_BUILDER_INTERNAL_STORAGE
  2111. page = (mpack_builder_page_t*)builder->internal;
  2112. mpack_log("beginning builder with internal storage %p\n", (void*)page);
  2113. #else
  2114. page = (mpack_builder_page_t*)MPACK_MALLOC(MPACK_BUILDER_PAGE_SIZE);
  2115. if (page == NULL) {
  2116. mpack_writer_flag_error(writer, mpack_error_memory);
  2117. return;
  2118. }
  2119. mpack_log("beginning builder with allocated page %p\n", (void*)page);
  2120. #endif
  2121. page->next = NULL;
  2122. page->bytes_used = sizeof(mpack_builder_page_t);
  2123. builder->pages = page;
  2124. builder->current_page = page;
  2125. }
  2126. static void mpack_builder_build(mpack_writer_t* writer, mpack_type_t type) {
  2127. mpack_builder_check_sizes(writer);
  2128. if (mpack_writer_error(writer) != mpack_ok)
  2129. return;
  2130. mpack_writer_track_element(writer);
  2131. mpack_writer_track_push_builder(writer, type);
  2132. mpack_builder_t* builder = &writer->builder;
  2133. if (builder->current_build == NULL) {
  2134. mpack_builder_begin(writer);
  2135. } else {
  2136. mpack_builder_apply_writes(writer);
  2137. }
  2138. if (mpack_writer_error(writer) != mpack_ok)
  2139. return;
  2140. // find aligned space for a new build. if there isn't enough space in the
  2141. // current page, we discard the remaining space in it and allocate a new
  2142. // page.
  2143. size_t offset = mpack_builder_align_build(builder->current_page->bytes_used);
  2144. if (offset + sizeof(mpack_build_t) > mpack_builder_page_size(writer, builder->current_page)) {
  2145. mpack_log("not enough space for a build. %zi bytes used of %zi in this page\n",
  2146. builder->current_page->bytes_used, mpack_builder_page_size(writer, builder->current_page));
  2147. mpack_builder_add_page(writer);
  2148. // there is always enough space in a fresh page.
  2149. offset = mpack_builder_align_build(builder->current_page->bytes_used);
  2150. }
  2151. // allocate the build within the page. note that we don't keep track of the
  2152. // space wasted due to the offset. instead the previous build has stored
  2153. // how many bytes follow it, and we'll redo this offset calculation to find
  2154. // this build after it.
  2155. mpack_builder_page_t* page = builder->current_page;
  2156. page->bytes_used = offset + sizeof(mpack_build_t);
  2157. mpack_assert(page->bytes_used <= mpack_builder_page_size(writer, page));
  2158. mpack_build_t* build = (mpack_build_t*)((char*)page + offset);
  2159. mpack_log("created new build %p within page %p, which now has %zi bytes used\n",
  2160. (void*)build, (void*)page, page->bytes_used);
  2161. // configure the new build
  2162. build->parent = builder->current_build;
  2163. build->bytes = 0;
  2164. build->count = 0;
  2165. build->type = type;
  2166. build->key_needs_value = false;
  2167. build->nested_compound_elements = 0;
  2168. mpack_log("setting current and latest build to new build %p\n", (void*)build);
  2169. builder->current_build = build;
  2170. builder->latest_build = build;
  2171. // we always need to provide a buffer that meets the minimum buffer size.
  2172. // if there isn't enough space, we discard the remaining space in the
  2173. // current page and allocate a new one.
  2174. if (mpack_builder_page_remaining(writer, page) < MPACK_WRITER_MINIMUM_BUFFER_SIZE) {
  2175. mpack_log("less than minimum buffer size in current page. %zi bytes used of %zi in this page\n",
  2176. builder->current_page->bytes_used, mpack_builder_page_size(writer, builder->current_page));
  2177. mpack_builder_add_page(writer);
  2178. if (mpack_writer_error(writer) != mpack_ok)
  2179. return;
  2180. }
  2181. mpack_assert(mpack_builder_page_remaining(writer, builder->current_page) >= MPACK_WRITER_MINIMUM_BUFFER_SIZE);
  2182. mpack_builder_configure_buffer(writer);
  2183. }
  2184. MPACK_NOINLINE
  2185. static void mpack_builder_resolve(mpack_writer_t* writer) {
  2186. mpack_builder_t* builder = &writer->builder;
  2187. // We should not have gotten here if we are in an error state. If an error
  2188. // occurs with an open builder, the writer will free the open builder pages
  2189. // when destroyed.
  2190. mpack_assert(mpack_writer_error(writer) == mpack_ok, "can't resolve in error state!");
  2191. // We don't want the user to longjmp out of any I/O errors while we are
  2192. // walking the page list, so defer error callbacks to after we're done.
  2193. mpack_writer_error_t error_fn = writer->error_fn;
  2194. writer->error_fn = NULL;
  2195. // The starting page is the internal storage (if we have it), otherwise
  2196. // it's the first page in the array
  2197. mpack_builder_page_t* page =
  2198. #if MPACK_BUILDER_INTERNAL_STORAGE
  2199. (mpack_builder_page_t*)builder->internal
  2200. #else
  2201. builder->pages
  2202. #endif
  2203. ;
  2204. // We start by restoring the writer's original buffer so we can write the
  2205. // data for real.
  2206. writer->buffer = builder->stash_buffer;
  2207. writer->position = builder->stash_position;
  2208. writer->end = builder->stash_end;
  2209. // We can also close out the build now.
  2210. builder->current_build = NULL;
  2211. builder->latest_build = NULL;
  2212. builder->current_page = NULL;
  2213. builder->pages = NULL;
  2214. // the starting page always starts with the first build
  2215. size_t offset = mpack_builder_align_build(sizeof(mpack_builder_page_t));
  2216. mpack_build_t* build = (mpack_build_t*)((char*)page + offset);
  2217. mpack_log("starting resolve with build %p in page %p\n", (void*)build, (void*)page);
  2218. // encoded data immediately follows the build
  2219. offset += sizeof(mpack_build_t);
  2220. // Walk the list of builds, writing everything out in the buffer. Note that
  2221. // we don't check for errors anywhere. The lower-level write functions will
  2222. // all check for errors and do nothing after an error occurs. We need to
  2223. // walk all pages anyway to free them, so there's not much point in
  2224. // optimizing an error path at the expense of the normal path.
  2225. while (true) {
  2226. // write out the container tag
  2227. mpack_log("writing out an %s with count %" PRIu32 " followed by %zi bytes\n",
  2228. mpack_type_to_string(build->type), build->count, build->bytes);
  2229. switch (build->type) {
  2230. case mpack_type_map:
  2231. mpack_write_map_notrack(writer, build->count);
  2232. break;
  2233. case mpack_type_array:
  2234. mpack_write_array_notrack(writer, build->count);
  2235. break;
  2236. default:
  2237. mpack_break("invalid type in builder?");
  2238. mpack_writer_flag_error(writer, mpack_error_bug);
  2239. return;
  2240. }
  2241. // figure out how many bytes follow this container. we're going to be
  2242. // freeing pages as we write, so we need to be done with this build.
  2243. size_t left = build->bytes;
  2244. build = NULL;
  2245. // write out all bytes following this container
  2246. while (left > 0) {
  2247. size_t bytes_used = page->bytes_used;
  2248. if (offset < bytes_used) {
  2249. size_t step = bytes_used - offset;
  2250. if (step > left)
  2251. step = left;
  2252. mpack_log("writing out %zi bytes starting at %p in page %p\n",
  2253. step, (void*)((char*)page + offset), (void*)page);
  2254. mpack_write_native(writer, (char*)page + offset, step);
  2255. offset += step;
  2256. left -= step;
  2257. }
  2258. if (left == 0) {
  2259. mpack_log("done writing bytes for this build\n");
  2260. break;
  2261. }
  2262. // still need to write more bytes. free this page and jump to the
  2263. // next one.
  2264. mpack_builder_page_t* next_page = page->next;
  2265. mpack_builder_free_page(writer, page);
  2266. page = next_page;
  2267. // bytes on the next page immediately follow the header.
  2268. offset = sizeof(mpack_builder_page_t);
  2269. }
  2270. // now see if we can find another build.
  2271. offset = mpack_builder_align_build(offset);
  2272. if (offset + sizeof(mpack_build_t) > mpack_builder_page_size(writer, page)) {
  2273. mpack_log("not enough room in this page for another build\n");
  2274. mpack_builder_page_t* next_page = page->next;
  2275. mpack_builder_free_page(writer, page);
  2276. page = next_page;
  2277. if (page == NULL) {
  2278. mpack_log("no more pages\n");
  2279. // there are no more pages. we're done.
  2280. break;
  2281. }
  2282. offset = mpack_builder_align_build(sizeof(mpack_builder_page_t));
  2283. }
  2284. if (offset + sizeof(mpack_build_t) > page->bytes_used) {
  2285. // there is no more data. we're done.
  2286. mpack_log("no more data\n");
  2287. mpack_builder_free_page(writer, page);
  2288. break;
  2289. }
  2290. // we've found another build. loop around!
  2291. build = (mpack_build_t*)((char*)page + offset);
  2292. offset += sizeof(mpack_build_t);
  2293. mpack_log("found build %p\n", (void*)build);
  2294. }
  2295. mpack_log("done resolve.\n");
  2296. // We can now restore the error handler and call it if an error occurred.
  2297. writer->error_fn = error_fn;
  2298. if (writer->error_fn && mpack_writer_error(writer) != mpack_ok)
  2299. writer->error_fn(writer, writer->error);
  2300. }
  2301. static void mpack_builder_complete(mpack_writer_t* writer, mpack_type_t type) {
  2302. mpack_writer_track_pop_builder(writer, type);
  2303. if (mpack_writer_error(writer) != mpack_ok)
  2304. return;
  2305. mpack_builder_t* builder = &writer->builder;
  2306. mpack_assert(builder->current_build != NULL, "no build in progress!");
  2307. mpack_assert(builder->latest_build != NULL, "missing latest build!");
  2308. mpack_assert(builder->current_build->type == type, "completing wrong type!");
  2309. mpack_log("completing build %p\n", (void*)builder->current_build);
  2310. if (builder->current_build->key_needs_value) {
  2311. mpack_break("an odd number of elements were written in a map!");
  2312. mpack_writer_flag_error(writer, mpack_error_bug);
  2313. return;
  2314. }
  2315. if (builder->current_build->nested_compound_elements != 0) {
  2316. mpack_break("there is a nested unfinished non-build map or array in this build.");
  2317. mpack_writer_flag_error(writer, mpack_error_bug);
  2318. return;
  2319. }
  2320. // We need to apply whatever writes have been made to the current build
  2321. // before popping it.
  2322. mpack_builder_apply_writes(writer);
  2323. // For a nested build, we just switch the current build back to its parent.
  2324. if (builder->current_build->parent != NULL) {
  2325. mpack_log("setting current build to parent build %p. latest is still %p.\n",
  2326. (void*)builder->current_build->parent, (void*)builder->latest_build);
  2327. builder->current_build = builder->current_build->parent;
  2328. mpack_builder_configure_buffer(writer);
  2329. } else {
  2330. // We're completing the final build.
  2331. mpack_builder_resolve(writer);
  2332. }
  2333. }
  2334. void mpack_build_map(mpack_writer_t* writer) {
  2335. mpack_builder_build(writer, mpack_type_map);
  2336. }
  2337. void mpack_build_array(mpack_writer_t* writer) {
  2338. mpack_builder_build(writer, mpack_type_array);
  2339. }
  2340. void mpack_complete_map(mpack_writer_t* writer) {
  2341. mpack_builder_complete(writer, mpack_type_map);
  2342. }
  2343. void mpack_complete_array(mpack_writer_t* writer) {
  2344. mpack_builder_complete(writer, mpack_type_array);
  2345. }
  2346. #endif // MPACK_BUILDER
  2347. #endif // MPACK_WRITER
  2348. MPACK_SILENCE_WARNINGS_END
  2349. /* mpack/mpack-reader.c.c */
  2350. #define MPACK_INTERNAL 1
  2351. /* #include "mpack-reader.h" */
  2352. MPACK_SILENCE_WARNINGS_BEGIN
  2353. #if MPACK_READER
  2354. static void mpack_reader_skip_using_fill(mpack_reader_t* reader, size_t count);
  2355. void mpack_reader_init(mpack_reader_t* reader, char* buffer, size_t size, size_t count) {
  2356. mpack_assert(buffer != NULL, "buffer is NULL");
  2357. mpack_memset(reader, 0, sizeof(*reader));
  2358. reader->buffer = buffer;
  2359. reader->size = size;
  2360. reader->data = buffer;
  2361. reader->end = buffer + count;
  2362. #if MPACK_READ_TRACKING
  2363. mpack_reader_flag_if_error(reader, mpack_track_init(&reader->track));
  2364. #endif
  2365. mpack_log("===========================\n");
  2366. mpack_log("initializing reader with buffer size %i\n", (int)size);
  2367. }
  2368. void mpack_reader_init_error(mpack_reader_t* reader, mpack_error_t error) {
  2369. mpack_memset(reader, 0, sizeof(*reader));
  2370. reader->error = error;
  2371. mpack_log("===========================\n");
  2372. mpack_log("initializing reader error state %i\n", (int)error);
  2373. }
  2374. void mpack_reader_init_data(mpack_reader_t* reader, const char* data, size_t count) {
  2375. mpack_assert(data != NULL, "data is NULL");
  2376. mpack_memset(reader, 0, sizeof(*reader));
  2377. reader->data = data;
  2378. reader->end = data + count;
  2379. #if MPACK_READ_TRACKING
  2380. mpack_reader_flag_if_error(reader, mpack_track_init(&reader->track));
  2381. #endif
  2382. mpack_log("===========================\n");
  2383. mpack_log("initializing reader with data size %i\n", (int)count);
  2384. }
  2385. void mpack_reader_set_fill(mpack_reader_t* reader, mpack_reader_fill_t fill) {
  2386. MPACK_STATIC_ASSERT(MPACK_READER_MINIMUM_BUFFER_SIZE >= MPACK_MAXIMUM_TAG_SIZE,
  2387. "minimum buffer size must fit any tag!");
  2388. if (reader->size == 0) {
  2389. mpack_break("cannot use fill function without a writeable buffer!");
  2390. mpack_reader_flag_error(reader, mpack_error_bug);
  2391. return;
  2392. }
  2393. if (reader->size < MPACK_READER_MINIMUM_BUFFER_SIZE) {
  2394. mpack_break("buffer size is %i, but minimum buffer size for fill is %i",
  2395. (int)reader->size, MPACK_READER_MINIMUM_BUFFER_SIZE);
  2396. mpack_reader_flag_error(reader, mpack_error_bug);
  2397. return;
  2398. }
  2399. reader->fill = fill;
  2400. }
  2401. void mpack_reader_set_skip(mpack_reader_t* reader, mpack_reader_skip_t skip) {
  2402. mpack_assert(reader->size != 0, "cannot use skip function without a writeable buffer!");
  2403. reader->skip = skip;
  2404. }
  2405. #if MPACK_STDIO
  2406. static size_t mpack_file_reader_fill(mpack_reader_t* reader, char* buffer, size_t count) {
  2407. if (feof((FILE *)reader->context)) {
  2408. mpack_reader_flag_error(reader, mpack_error_eof);
  2409. return 0;
  2410. }
  2411. return fread((void*)buffer, 1, count, (FILE*)reader->context);
  2412. }
  2413. static void mpack_file_reader_skip(mpack_reader_t* reader, size_t count) {
  2414. if (mpack_reader_error(reader) != mpack_ok)
  2415. return;
  2416. FILE* file = (FILE*)reader->context;
  2417. // We call ftell() to test whether the stream is seekable
  2418. // without causing a file error.
  2419. if (ftell(file) >= 0) {
  2420. mpack_log("seeking forward %i bytes\n", (int)count);
  2421. if (fseek(file, (long int)count, SEEK_CUR) == 0)
  2422. return;
  2423. mpack_log("fseek() didn't return zero!\n");
  2424. if (ferror(file)) {
  2425. mpack_reader_flag_error(reader, mpack_error_io);
  2426. return;
  2427. }
  2428. }
  2429. // If the stream is not seekable, fall back to the fill function.
  2430. mpack_reader_skip_using_fill(reader, count);
  2431. }
  2432. static void mpack_file_reader_teardown(mpack_reader_t* reader) {
  2433. MPACK_FREE(reader->buffer);
  2434. reader->buffer = NULL;
  2435. reader->context = NULL;
  2436. reader->size = 0;
  2437. reader->fill = NULL;
  2438. reader->skip = NULL;
  2439. reader->teardown = NULL;
  2440. }
  2441. static void mpack_file_reader_teardown_close(mpack_reader_t* reader) {
  2442. FILE* file = (FILE*)reader->context;
  2443. if (file) {
  2444. int ret = fclose(file);
  2445. if (ret != 0)
  2446. mpack_reader_flag_error(reader, mpack_error_io);
  2447. }
  2448. mpack_file_reader_teardown(reader);
  2449. }
  2450. void mpack_reader_init_stdfile(mpack_reader_t* reader, FILE* file, bool close_when_done) {
  2451. mpack_assert(file != NULL, "file is NULL");
  2452. size_t capacity = MPACK_BUFFER_SIZE;
  2453. char* buffer = (char*)MPACK_MALLOC(capacity);
  2454. if (buffer == NULL) {
  2455. mpack_reader_init_error(reader, mpack_error_memory);
  2456. if (close_when_done) {
  2457. fclose(file);
  2458. }
  2459. return;
  2460. }
  2461. mpack_reader_init(reader, buffer, capacity, 0);
  2462. mpack_reader_set_context(reader, file);
  2463. mpack_reader_set_fill(reader, mpack_file_reader_fill);
  2464. mpack_reader_set_skip(reader, mpack_file_reader_skip);
  2465. mpack_reader_set_teardown(reader, close_when_done ?
  2466. mpack_file_reader_teardown_close :
  2467. mpack_file_reader_teardown);
  2468. }
  2469. void mpack_reader_init_filename(mpack_reader_t* reader, const char* filename) {
  2470. mpack_assert(filename != NULL, "filename is NULL");
  2471. FILE* file = fopen(filename, "rb");
  2472. if (file == NULL) {
  2473. mpack_reader_init_error(reader, mpack_error_io);
  2474. return;
  2475. }
  2476. mpack_reader_init_stdfile(reader, file, true);
  2477. }
  2478. #endif
  2479. mpack_error_t mpack_reader_destroy(mpack_reader_t* reader) {
  2480. // clean up tracking, asserting if we're not already in an error state
  2481. #if MPACK_READ_TRACKING
  2482. mpack_reader_flag_if_error(reader, mpack_track_destroy(&reader->track, mpack_reader_error(reader) != mpack_ok));
  2483. #endif
  2484. if (reader->teardown)
  2485. reader->teardown(reader);
  2486. reader->teardown = NULL;
  2487. return reader->error;
  2488. }
  2489. size_t mpack_reader_remaining(mpack_reader_t* reader, const char** data) {
  2490. if (mpack_reader_error(reader) != mpack_ok)
  2491. return 0;
  2492. #if MPACK_READ_TRACKING
  2493. if (mpack_reader_flag_if_error(reader, mpack_track_check_empty(&reader->track)) != mpack_ok)
  2494. return 0;
  2495. #endif
  2496. if (data)
  2497. *data = reader->data;
  2498. return (size_t)(reader->end - reader->data);
  2499. }
  2500. void mpack_reader_flag_error(mpack_reader_t* reader, mpack_error_t error) {
  2501. mpack_log("reader %p setting error %i: %s\n", (void*)reader, (int)error, mpack_error_to_string(error));
  2502. if (reader->error == mpack_ok) {
  2503. reader->error = error;
  2504. reader->end = reader->data;
  2505. if (reader->error_fn)
  2506. reader->error_fn(reader, error);
  2507. }
  2508. }
  2509. // Loops on the fill function, reading between the minimum and
  2510. // maximum number of bytes and flagging an error if it fails.
  2511. MPACK_NOINLINE static size_t mpack_fill_range(mpack_reader_t* reader, char* p, size_t min_bytes, size_t max_bytes) {
  2512. mpack_assert(reader->fill != NULL, "mpack_fill_range() called with no fill function?");
  2513. mpack_assert(min_bytes > 0, "cannot fill zero bytes!");
  2514. mpack_assert(max_bytes >= min_bytes, "min_bytes %i cannot be larger than max_bytes %i!",
  2515. (int)min_bytes, (int)max_bytes);
  2516. size_t count = 0;
  2517. while (count < min_bytes) {
  2518. size_t read = reader->fill(reader, p + count, max_bytes - count);
  2519. // Reader fill functions can flag an error or return 0 on failure. We
  2520. // also guard against functions that return -1 just in case.
  2521. if (mpack_reader_error(reader) != mpack_ok)
  2522. return 0;
  2523. if (read == 0 || read == ((size_t)(-1))) {
  2524. mpack_reader_flag_error(reader, mpack_error_io);
  2525. return 0;
  2526. }
  2527. count += read;
  2528. }
  2529. return count;
  2530. }
  2531. MPACK_NOINLINE bool mpack_reader_ensure_straddle(mpack_reader_t* reader, size_t count) {
  2532. mpack_assert(count != 0, "cannot ensure zero bytes!");
  2533. mpack_assert(reader->error == mpack_ok, "reader cannot be in an error state!");
  2534. mpack_assert(count > (size_t)(reader->end - reader->data),
  2535. "straddling ensure requested for %i bytes, but there are %i bytes "
  2536. "left in buffer. call mpack_reader_ensure() instead",
  2537. (int)count, (int)(reader->end - reader->data));
  2538. // we'll need a fill function to get more data. if there's no
  2539. // fill function, the buffer should contain an entire MessagePack
  2540. // object, so we raise mpack_error_invalid instead of mpack_error_io
  2541. // on truncated data.
  2542. if (reader->fill == NULL) {
  2543. mpack_reader_flag_error(reader, mpack_error_invalid);
  2544. return false;
  2545. }
  2546. // we need enough space in the buffer. if the buffer is not
  2547. // big enough, we return mpack_error_too_big (since this is
  2548. // for an in-place read larger than the buffer size.)
  2549. if (count > reader->size) {
  2550. mpack_reader_flag_error(reader, mpack_error_too_big);
  2551. return false;
  2552. }
  2553. // move the existing data to the start of the buffer
  2554. size_t left = (size_t)(reader->end - reader->data);
  2555. mpack_memmove(reader->buffer, reader->data, left);
  2556. reader->end -= reader->data - reader->buffer;
  2557. reader->data = reader->buffer;
  2558. // read at least the necessary number of bytes, accepting up to the
  2559. // buffer size
  2560. size_t read = mpack_fill_range(reader, reader->buffer + left,
  2561. count - left, reader->size - left);
  2562. if (mpack_reader_error(reader) != mpack_ok)
  2563. return false;
  2564. reader->end += read;
  2565. return true;
  2566. }
  2567. // Reads count bytes into p. Used when there are not enough bytes
  2568. // left in the buffer to satisfy a read.
  2569. MPACK_NOINLINE void mpack_read_native_straddle(mpack_reader_t* reader, char* p, size_t count) {
  2570. mpack_assert(count == 0 || p != NULL, "data pointer for %i bytes is NULL", (int)count);
  2571. if (mpack_reader_error(reader) != mpack_ok) {
  2572. mpack_memset(p, 0, count);
  2573. return;
  2574. }
  2575. size_t left = (size_t)(reader->end - reader->data);
  2576. mpack_log("big read for %i bytes into %p, %i left in buffer, buffer size %i\n",
  2577. (int)count, p, (int)left, (int)reader->size);
  2578. if (count <= left) {
  2579. mpack_assert(0,
  2580. "big read requested for %i bytes, but there are %i bytes "
  2581. "left in buffer. call mpack_read_native() instead",
  2582. (int)count, (int)left);
  2583. mpack_reader_flag_error(reader, mpack_error_bug);
  2584. mpack_memset(p, 0, count);
  2585. return;
  2586. }
  2587. // we'll need a fill function to get more data. if there's no
  2588. // fill function, the buffer should contain an entire MessagePack
  2589. // object, so we raise mpack_error_invalid instead of mpack_error_io
  2590. // on truncated data.
  2591. if (reader->fill == NULL) {
  2592. mpack_reader_flag_error(reader, mpack_error_invalid);
  2593. mpack_memset(p, 0, count);
  2594. return;
  2595. }
  2596. if (reader->size == 0) {
  2597. // somewhat debatable what error should be returned here. when
  2598. // initializing a reader with an in-memory buffer it's not
  2599. // necessarily a bug if the data is blank; it might just have
  2600. // been truncated to zero. for this reason we return the same
  2601. // error as if the data was truncated.
  2602. mpack_reader_flag_error(reader, mpack_error_io);
  2603. mpack_memset(p, 0, count);
  2604. return;
  2605. }
  2606. // flush what's left of the buffer
  2607. if (left > 0) {
  2608. mpack_log("flushing %i bytes remaining in buffer\n", (int)left);
  2609. mpack_memcpy(p, reader->data, left);
  2610. count -= left;
  2611. p += left;
  2612. reader->data += left;
  2613. }
  2614. // if the remaining data needed is some small fraction of the
  2615. // buffer size, we'll try to fill the buffer as much as possible
  2616. // and copy the needed data out.
  2617. if (count <= reader->size / MPACK_READER_SMALL_FRACTION_DENOMINATOR) {
  2618. size_t read = mpack_fill_range(reader, reader->buffer, count, reader->size);
  2619. if (mpack_reader_error(reader) != mpack_ok)
  2620. return;
  2621. mpack_memcpy(p, reader->buffer, count);
  2622. reader->data = reader->buffer + count;
  2623. reader->end = reader->buffer + read;
  2624. // otherwise we read the remaining data directly into the target.
  2625. } else {
  2626. mpack_log("reading %i additional bytes\n", (int)count);
  2627. mpack_fill_range(reader, p, count, count);
  2628. }
  2629. }
  2630. MPACK_NOINLINE static void mpack_skip_bytes_straddle(mpack_reader_t* reader, size_t count) {
  2631. // we'll need at least a fill function to skip more data. if there's
  2632. // no fill function, the buffer should contain an entire MessagePack
  2633. // object, so we raise mpack_error_invalid instead of mpack_error_io
  2634. // on truncated data. (see mpack_read_native_straddle())
  2635. if (reader->fill == NULL) {
  2636. mpack_log("reader has no fill function!\n");
  2637. mpack_reader_flag_error(reader, mpack_error_invalid);
  2638. return;
  2639. }
  2640. // discard whatever's left in the buffer
  2641. size_t left = (size_t)(reader->end - reader->data);
  2642. mpack_log("discarding %i bytes still in buffer\n", (int)left);
  2643. count -= left;
  2644. reader->data = reader->end;
  2645. // use the skip function if we've got one, and if we're trying
  2646. // to skip a lot of data. if we only need to skip some tiny
  2647. // fraction of the buffer size, it's probably better to just
  2648. // fill the buffer and skip from it instead of trying to seek.
  2649. if (reader->skip && count > reader->size / 16) {
  2650. mpack_log("calling skip function for %i bytes\n", (int)count);
  2651. reader->skip(reader, count);
  2652. return;
  2653. }
  2654. mpack_reader_skip_using_fill(reader, count);
  2655. }
  2656. void mpack_skip_bytes(mpack_reader_t* reader, size_t count) {
  2657. if (mpack_reader_error(reader) != mpack_ok)
  2658. return;
  2659. mpack_log("skip requested for %i bytes\n", (int)count);
  2660. mpack_reader_track_bytes(reader, count);
  2661. // check if we have enough in the buffer already
  2662. size_t left = (size_t)(reader->end - reader->data);
  2663. if (left >= count) {
  2664. mpack_log("skipping %" PRIu32 " bytes still in buffer\n", (uint32_t)count);
  2665. reader->data += count;
  2666. return;
  2667. }
  2668. mpack_skip_bytes_straddle(reader, count);
  2669. }
  2670. MPACK_NOINLINE static void mpack_reader_skip_using_fill(mpack_reader_t* reader, size_t count) {
  2671. mpack_assert(reader->fill != NULL, "missing fill function!");
  2672. mpack_assert(reader->data == reader->end, "there are bytes left in the buffer!");
  2673. mpack_assert(reader->error == mpack_ok, "should not have called this in an error state (%i)", reader->error);
  2674. mpack_log("skip using fill for %i bytes\n", (int)count);
  2675. // fill and discard multiples of the buffer size
  2676. while (count > reader->size) {
  2677. mpack_log("filling and discarding buffer of %i bytes\n", (int)reader->size);
  2678. if (mpack_fill_range(reader, reader->buffer, reader->size, reader->size) < reader->size) {
  2679. mpack_reader_flag_error(reader, mpack_error_io);
  2680. return;
  2681. }
  2682. count -= reader->size;
  2683. }
  2684. // fill the buffer as much as possible
  2685. reader->data = reader->buffer;
  2686. size_t read = mpack_fill_range(reader, reader->buffer, count, reader->size);
  2687. if (read < count) {
  2688. mpack_reader_flag_error(reader, mpack_error_io);
  2689. return;
  2690. }
  2691. reader->end = reader->data + read;
  2692. mpack_log("filled %i bytes into buffer; discarding %i bytes\n", (int)read, (int)count);
  2693. reader->data += count;
  2694. }
  2695. void mpack_read_bytes(mpack_reader_t* reader, char* p, size_t count) {
  2696. mpack_assert(p != NULL, "destination for read of %i bytes is NULL", (int)count);
  2697. mpack_reader_track_bytes(reader, count);
  2698. mpack_read_native(reader, p, count);
  2699. }
  2700. void mpack_read_utf8(mpack_reader_t* reader, char* p, size_t byte_count) {
  2701. mpack_assert(p != NULL, "destination for read of %i bytes is NULL", (int)byte_count);
  2702. mpack_reader_track_str_bytes_all(reader, byte_count);
  2703. mpack_read_native(reader, p, byte_count);
  2704. if (mpack_reader_error(reader) == mpack_ok && !mpack_utf8_check(p, byte_count))
  2705. mpack_reader_flag_error(reader, mpack_error_type);
  2706. }
  2707. static void mpack_read_cstr_unchecked(mpack_reader_t* reader, char* buf, size_t buffer_size, size_t byte_count) {
  2708. mpack_assert(buf != NULL, "destination for read of %i bytes is NULL", (int)byte_count);
  2709. mpack_assert(buffer_size >= 1, "buffer size is zero; you must have room for at least a null-terminator");
  2710. if (mpack_reader_error(reader)) {
  2711. buf[0] = 0;
  2712. return;
  2713. }
  2714. if (byte_count > buffer_size - 1) {
  2715. mpack_reader_flag_error(reader, mpack_error_too_big);
  2716. buf[0] = 0;
  2717. return;
  2718. }
  2719. mpack_reader_track_str_bytes_all(reader, byte_count);
  2720. mpack_read_native(reader, buf, byte_count);
  2721. buf[byte_count] = 0;
  2722. }
  2723. void mpack_read_cstr(mpack_reader_t* reader, char* buf, size_t buffer_size, size_t byte_count) {
  2724. mpack_read_cstr_unchecked(reader, buf, buffer_size, byte_count);
  2725. // check for null bytes
  2726. if (mpack_reader_error(reader) == mpack_ok && !mpack_str_check_no_null(buf, byte_count)) {
  2727. buf[0] = 0;
  2728. mpack_reader_flag_error(reader, mpack_error_type);
  2729. }
  2730. }
  2731. void mpack_read_utf8_cstr(mpack_reader_t* reader, char* buf, size_t buffer_size, size_t byte_count) {
  2732. mpack_read_cstr_unchecked(reader, buf, buffer_size, byte_count);
  2733. // check encoding
  2734. if (mpack_reader_error(reader) == mpack_ok && !mpack_utf8_check_no_null(buf, byte_count)) {
  2735. buf[0] = 0;
  2736. mpack_reader_flag_error(reader, mpack_error_type);
  2737. }
  2738. }
  2739. #ifdef MPACK_MALLOC
  2740. // Reads native bytes with error callback disabled. This allows MPack reader functions
  2741. // to hold an allocated buffer and read native data into it without leaking it in
  2742. // case of a non-local jump (longjmp, throw) out of an error handler.
  2743. static void mpack_read_native_noerrorfn(mpack_reader_t* reader, char* p, size_t count) {
  2744. mpack_assert(reader->error == mpack_ok, "cannot call if an error is already flagged!");
  2745. mpack_reader_error_t error_fn = reader->error_fn;
  2746. reader->error_fn = NULL;
  2747. mpack_read_native(reader, p, count);
  2748. reader->error_fn = error_fn;
  2749. }
  2750. char* mpack_read_bytes_alloc_impl(mpack_reader_t* reader, size_t count, bool null_terminated) {
  2751. // track the bytes first in case it jumps
  2752. mpack_reader_track_bytes(reader, count);
  2753. if (mpack_reader_error(reader) != mpack_ok)
  2754. return NULL;
  2755. // cannot allocate zero bytes. this is not an error.
  2756. if (count == 0 && null_terminated == false)
  2757. return NULL;
  2758. // allocate data
  2759. char* data = (char*)MPACK_MALLOC(count + (null_terminated ? 1 : 0)); // TODO: can this overflow?
  2760. if (data == NULL) {
  2761. mpack_reader_flag_error(reader, mpack_error_memory);
  2762. return NULL;
  2763. }
  2764. // read with error callback disabled so we don't leak our buffer
  2765. mpack_read_native_noerrorfn(reader, data, count);
  2766. // report flagged errors
  2767. if (mpack_reader_error(reader) != mpack_ok) {
  2768. MPACK_FREE(data);
  2769. if (reader->error_fn)
  2770. reader->error_fn(reader, mpack_reader_error(reader));
  2771. return NULL;
  2772. }
  2773. if (null_terminated)
  2774. data[count] = '\0';
  2775. return data;
  2776. }
  2777. #endif
  2778. // read inplace without tracking (since there are different
  2779. // tracking modes for different inplace readers)
  2780. static const char* mpack_read_bytes_inplace_notrack(mpack_reader_t* reader, size_t count) {
  2781. if (mpack_reader_error(reader) != mpack_ok)
  2782. return NULL;
  2783. // if we have enough bytes already in the buffer, we can return it directly.
  2784. if ((size_t)(reader->end - reader->data) >= count) {
  2785. const char* bytes = reader->data;
  2786. reader->data += count;
  2787. return bytes;
  2788. }
  2789. if (!mpack_reader_ensure(reader, count))
  2790. return NULL;
  2791. const char* bytes = reader->data;
  2792. reader->data += count;
  2793. return bytes;
  2794. }
  2795. const char* mpack_read_bytes_inplace(mpack_reader_t* reader, size_t count) {
  2796. mpack_reader_track_bytes(reader, count);
  2797. return mpack_read_bytes_inplace_notrack(reader, count);
  2798. }
  2799. const char* mpack_read_utf8_inplace(mpack_reader_t* reader, size_t count) {
  2800. mpack_reader_track_str_bytes_all(reader, count);
  2801. const char* str = mpack_read_bytes_inplace_notrack(reader, count);
  2802. if (mpack_reader_error(reader) == mpack_ok && !mpack_utf8_check(str, count)) {
  2803. mpack_reader_flag_error(reader, mpack_error_type);
  2804. return NULL;
  2805. }
  2806. return str;
  2807. }
  2808. static size_t mpack_parse_tag(mpack_reader_t* reader, mpack_tag_t* tag) {
  2809. mpack_assert(reader->error == mpack_ok, "reader cannot be in an error state!");
  2810. if (!mpack_reader_ensure(reader, 1))
  2811. return 0;
  2812. uint8_t type = mpack_load_u8(reader->data);
  2813. // unfortunately, by far the fastest way to parse a tag is to switch
  2814. // on the first byte, and to explicitly list every possible byte. so for
  2815. // infix types, the list of cases is quite large.
  2816. //
  2817. // in size-optimized builds, we switch on the top four bits first to
  2818. // handle most infix types with a smaller jump table to save space.
  2819. #if MPACK_OPTIMIZE_FOR_SIZE
  2820. switch (type >> 4) {
  2821. // positive fixnum
  2822. case 0x0: case 0x1: case 0x2: case 0x3:
  2823. case 0x4: case 0x5: case 0x6: case 0x7:
  2824. *tag = mpack_tag_make_uint(type);
  2825. return 1;
  2826. // negative fixnum
  2827. case 0xe: case 0xf:
  2828. *tag = mpack_tag_make_int((int8_t)type);
  2829. return 1;
  2830. // fixmap
  2831. case 0x8:
  2832. *tag = mpack_tag_make_map(type & ~0xf0u);
  2833. return 1;
  2834. // fixarray
  2835. case 0x9:
  2836. *tag = mpack_tag_make_array(type & ~0xf0u);
  2837. return 1;
  2838. // fixstr
  2839. case 0xa: case 0xb:
  2840. *tag = mpack_tag_make_str(type & ~0xe0u);
  2841. return 1;
  2842. // not one of the common infix types
  2843. default:
  2844. break;
  2845. }
  2846. #endif
  2847. // handle individual type tags
  2848. switch (type) {
  2849. #if !MPACK_OPTIMIZE_FOR_SIZE
  2850. // positive fixnum
  2851. case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
  2852. case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  2853. case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
  2854. case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
  2855. case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
  2856. case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
  2857. case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
  2858. case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
  2859. case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
  2860. case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  2861. case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
  2862. case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  2863. case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
  2864. case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  2865. case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
  2866. case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
  2867. *tag = mpack_tag_make_uint(type);
  2868. return 1;
  2869. // negative fixnum
  2870. case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  2871. case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
  2872. case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  2873. case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
  2874. *tag = mpack_tag_make_int((int8_t)type);
  2875. return 1;
  2876. // fixmap
  2877. case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
  2878. case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  2879. *tag = mpack_tag_make_map(type & ~0xf0u);
  2880. return 1;
  2881. // fixarray
  2882. case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
  2883. case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  2884. *tag = mpack_tag_make_array(type & ~0xf0u);
  2885. return 1;
  2886. // fixstr
  2887. case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  2888. case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
  2889. case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  2890. case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  2891. *tag = mpack_tag_make_str(type & ~0xe0u);
  2892. return 1;
  2893. #endif
  2894. // nil
  2895. case 0xc0:
  2896. *tag = mpack_tag_make_nil();
  2897. return 1;
  2898. // bool
  2899. case 0xc2: case 0xc3:
  2900. *tag = mpack_tag_make_bool((bool)(type & 1));
  2901. return 1;
  2902. // bin8
  2903. case 0xc4:
  2904. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_BIN8))
  2905. return 0;
  2906. *tag = mpack_tag_make_bin(mpack_load_u8(reader->data + 1));
  2907. return MPACK_TAG_SIZE_BIN8;
  2908. // bin16
  2909. case 0xc5:
  2910. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_BIN16))
  2911. return 0;
  2912. *tag = mpack_tag_make_bin(mpack_load_u16(reader->data + 1));
  2913. return MPACK_TAG_SIZE_BIN16;
  2914. // bin32
  2915. case 0xc6:
  2916. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_BIN32))
  2917. return 0;
  2918. *tag = mpack_tag_make_bin(mpack_load_u32(reader->data + 1));
  2919. return MPACK_TAG_SIZE_BIN32;
  2920. #if MPACK_EXTENSIONS
  2921. // ext8
  2922. case 0xc7:
  2923. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_EXT8))
  2924. return 0;
  2925. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 2), mpack_load_u8(reader->data + 1));
  2926. return MPACK_TAG_SIZE_EXT8;
  2927. // ext16
  2928. case 0xc8:
  2929. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_EXT16))
  2930. return 0;
  2931. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 3), mpack_load_u16(reader->data + 1));
  2932. return MPACK_TAG_SIZE_EXT16;
  2933. // ext32
  2934. case 0xc9:
  2935. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_EXT32))
  2936. return 0;
  2937. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 5), mpack_load_u32(reader->data + 1));
  2938. return MPACK_TAG_SIZE_EXT32;
  2939. #endif
  2940. // float
  2941. case 0xca:
  2942. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FLOAT))
  2943. return 0;
  2944. #if MPACK_FLOAT
  2945. *tag = mpack_tag_make_float(mpack_load_float(reader->data + 1));
  2946. #else
  2947. *tag = mpack_tag_make_raw_float(mpack_load_u32(reader->data + 1));
  2948. #endif
  2949. return MPACK_TAG_SIZE_FLOAT;
  2950. // double
  2951. case 0xcb:
  2952. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_DOUBLE))
  2953. return 0;
  2954. #if MPACK_DOUBLE
  2955. *tag = mpack_tag_make_double(mpack_load_double(reader->data + 1));
  2956. #else
  2957. *tag = mpack_tag_make_raw_double(mpack_load_u64(reader->data + 1));
  2958. #endif
  2959. return MPACK_TAG_SIZE_DOUBLE;
  2960. // uint8
  2961. case 0xcc:
  2962. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_U8))
  2963. return 0;
  2964. *tag = mpack_tag_make_uint(mpack_load_u8(reader->data + 1));
  2965. return MPACK_TAG_SIZE_U8;
  2966. // uint16
  2967. case 0xcd:
  2968. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_U16))
  2969. return 0;
  2970. *tag = mpack_tag_make_uint(mpack_load_u16(reader->data + 1));
  2971. return MPACK_TAG_SIZE_U16;
  2972. // uint32
  2973. case 0xce:
  2974. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_U32))
  2975. return 0;
  2976. *tag = mpack_tag_make_uint(mpack_load_u32(reader->data + 1));
  2977. return MPACK_TAG_SIZE_U32;
  2978. // uint64
  2979. case 0xcf:
  2980. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_U64))
  2981. return 0;
  2982. *tag = mpack_tag_make_uint(mpack_load_u64(reader->data + 1));
  2983. return MPACK_TAG_SIZE_U64;
  2984. // int8
  2985. case 0xd0:
  2986. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_I8))
  2987. return 0;
  2988. *tag = mpack_tag_make_int(mpack_load_i8(reader->data + 1));
  2989. return MPACK_TAG_SIZE_I8;
  2990. // int16
  2991. case 0xd1:
  2992. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_I16))
  2993. return 0;
  2994. *tag = mpack_tag_make_int(mpack_load_i16(reader->data + 1));
  2995. return MPACK_TAG_SIZE_I16;
  2996. // int32
  2997. case 0xd2:
  2998. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_I32))
  2999. return 0;
  3000. *tag = mpack_tag_make_int(mpack_load_i32(reader->data + 1));
  3001. return MPACK_TAG_SIZE_I32;
  3002. // int64
  3003. case 0xd3:
  3004. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_I64))
  3005. return 0;
  3006. *tag = mpack_tag_make_int(mpack_load_i64(reader->data + 1));
  3007. return MPACK_TAG_SIZE_I64;
  3008. #if MPACK_EXTENSIONS
  3009. // fixext1
  3010. case 0xd4:
  3011. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FIXEXT1))
  3012. return 0;
  3013. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 1), 1);
  3014. return MPACK_TAG_SIZE_FIXEXT1;
  3015. // fixext2
  3016. case 0xd5:
  3017. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FIXEXT2))
  3018. return 0;
  3019. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 1), 2);
  3020. return MPACK_TAG_SIZE_FIXEXT2;
  3021. // fixext4
  3022. case 0xd6:
  3023. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FIXEXT4))
  3024. return 0;
  3025. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 1), 4);
  3026. return 2;
  3027. // fixext8
  3028. case 0xd7:
  3029. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FIXEXT8))
  3030. return 0;
  3031. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 1), 8);
  3032. return MPACK_TAG_SIZE_FIXEXT8;
  3033. // fixext16
  3034. case 0xd8:
  3035. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_FIXEXT16))
  3036. return 0;
  3037. *tag = mpack_tag_make_ext(mpack_load_i8(reader->data + 1), 16);
  3038. return MPACK_TAG_SIZE_FIXEXT16;
  3039. #endif
  3040. // str8
  3041. case 0xd9:
  3042. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_STR8))
  3043. return 0;
  3044. *tag = mpack_tag_make_str(mpack_load_u8(reader->data + 1));
  3045. return MPACK_TAG_SIZE_STR8;
  3046. // str16
  3047. case 0xda:
  3048. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_STR16))
  3049. return 0;
  3050. *tag = mpack_tag_make_str(mpack_load_u16(reader->data + 1));
  3051. return MPACK_TAG_SIZE_STR16;
  3052. // str32
  3053. case 0xdb:
  3054. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_STR32))
  3055. return 0;
  3056. *tag = mpack_tag_make_str(mpack_load_u32(reader->data + 1));
  3057. return MPACK_TAG_SIZE_STR32;
  3058. // array16
  3059. case 0xdc:
  3060. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_ARRAY16))
  3061. return 0;
  3062. *tag = mpack_tag_make_array(mpack_load_u16(reader->data + 1));
  3063. return MPACK_TAG_SIZE_ARRAY16;
  3064. // array32
  3065. case 0xdd:
  3066. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_ARRAY32))
  3067. return 0;
  3068. *tag = mpack_tag_make_array(mpack_load_u32(reader->data + 1));
  3069. return MPACK_TAG_SIZE_ARRAY32;
  3070. // map16
  3071. case 0xde:
  3072. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_MAP16))
  3073. return 0;
  3074. *tag = mpack_tag_make_map(mpack_load_u16(reader->data + 1));
  3075. return MPACK_TAG_SIZE_MAP16;
  3076. // map32
  3077. case 0xdf:
  3078. if (!mpack_reader_ensure(reader, MPACK_TAG_SIZE_MAP32))
  3079. return 0;
  3080. *tag = mpack_tag_make_map(mpack_load_u32(reader->data + 1));
  3081. return MPACK_TAG_SIZE_MAP32;
  3082. // reserved
  3083. case 0xc1:
  3084. mpack_reader_flag_error(reader, mpack_error_invalid);
  3085. return 0;
  3086. #if !MPACK_EXTENSIONS
  3087. // ext
  3088. case 0xc7: // fallthrough
  3089. case 0xc8: // fallthrough
  3090. case 0xc9: // fallthrough
  3091. // fixext
  3092. case 0xd4: // fallthrough
  3093. case 0xd5: // fallthrough
  3094. case 0xd6: // fallthrough
  3095. case 0xd7: // fallthrough
  3096. case 0xd8:
  3097. mpack_reader_flag_error(reader, mpack_error_unsupported);
  3098. return 0;
  3099. #endif
  3100. #if MPACK_OPTIMIZE_FOR_SIZE
  3101. // any other bytes should have been handled by the infix switch
  3102. default:
  3103. break;
  3104. #endif
  3105. }
  3106. mpack_assert(0, "unreachable");
  3107. return 0;
  3108. }
  3109. mpack_tag_t mpack_read_tag(mpack_reader_t* reader) {
  3110. mpack_log("reading tag\n");
  3111. // make sure we can read a tag
  3112. if (mpack_reader_error(reader) != mpack_ok)
  3113. return mpack_tag_nil();
  3114. if (mpack_reader_track_element(reader) != mpack_ok)
  3115. return mpack_tag_nil();
  3116. mpack_tag_t tag = MPACK_TAG_ZERO;
  3117. size_t count = mpack_parse_tag(reader, &tag);
  3118. if (count == 0)
  3119. return mpack_tag_nil();
  3120. #if MPACK_READ_TRACKING
  3121. mpack_error_t track_error = mpack_ok;
  3122. switch (tag.type) {
  3123. case mpack_type_map:
  3124. case mpack_type_array:
  3125. track_error = mpack_track_push(&reader->track, tag.type, tag.v.n);
  3126. break;
  3127. #if MPACK_EXTENSIONS
  3128. case mpack_type_ext:
  3129. #endif
  3130. case mpack_type_str:
  3131. case mpack_type_bin:
  3132. track_error = mpack_track_push(&reader->track, tag.type, tag.v.l);
  3133. break;
  3134. default:
  3135. break;
  3136. }
  3137. if (track_error != mpack_ok) {
  3138. mpack_reader_flag_error(reader, track_error);
  3139. return mpack_tag_nil();
  3140. }
  3141. #endif
  3142. reader->data += count;
  3143. return tag;
  3144. }
  3145. mpack_tag_t mpack_peek_tag(mpack_reader_t* reader) {
  3146. mpack_log("peeking tag\n");
  3147. // make sure we can peek a tag
  3148. if (mpack_reader_error(reader) != mpack_ok)
  3149. return mpack_tag_nil();
  3150. if (mpack_reader_track_peek_element(reader) != mpack_ok)
  3151. return mpack_tag_nil();
  3152. mpack_tag_t tag = MPACK_TAG_ZERO;
  3153. if (mpack_parse_tag(reader, &tag) == 0)
  3154. return mpack_tag_nil();
  3155. return tag;
  3156. }
  3157. void mpack_discard(mpack_reader_t* reader) {
  3158. mpack_tag_t var = mpack_read_tag(reader);
  3159. if (mpack_reader_error(reader))
  3160. return;
  3161. switch (var.type) {
  3162. case mpack_type_str:
  3163. mpack_skip_bytes(reader, var.v.l);
  3164. mpack_done_str(reader);
  3165. break;
  3166. case mpack_type_bin:
  3167. mpack_skip_bytes(reader, var.v.l);
  3168. mpack_done_bin(reader);
  3169. break;
  3170. #if MPACK_EXTENSIONS
  3171. case mpack_type_ext:
  3172. mpack_skip_bytes(reader, var.v.l);
  3173. mpack_done_ext(reader);
  3174. break;
  3175. #endif
  3176. case mpack_type_array: {
  3177. for (; var.v.n > 0; --var.v.n) {
  3178. mpack_discard(reader);
  3179. if (mpack_reader_error(reader))
  3180. break;
  3181. }
  3182. mpack_done_array(reader);
  3183. break;
  3184. }
  3185. case mpack_type_map: {
  3186. for (; var.v.n > 0; --var.v.n) {
  3187. mpack_discard(reader);
  3188. mpack_discard(reader);
  3189. if (mpack_reader_error(reader))
  3190. break;
  3191. }
  3192. mpack_done_map(reader);
  3193. break;
  3194. }
  3195. default:
  3196. break;
  3197. }
  3198. }
  3199. #if MPACK_EXTENSIONS
  3200. mpack_timestamp_t mpack_read_timestamp(mpack_reader_t* reader, size_t size) {
  3201. mpack_timestamp_t timestamp = {0, 0};
  3202. if (size != 4 && size != 8 && size != 12) {
  3203. mpack_reader_flag_error(reader, mpack_error_invalid);
  3204. return timestamp;
  3205. }
  3206. char buf[12];
  3207. mpack_read_bytes(reader, buf, size);
  3208. mpack_done_ext(reader);
  3209. if (mpack_reader_error(reader) != mpack_ok)
  3210. return timestamp;
  3211. switch (size) {
  3212. case 4:
  3213. timestamp.seconds = (int64_t)(uint64_t)mpack_load_u32(buf);
  3214. break;
  3215. case 8: {
  3216. uint64_t packed = mpack_load_u64(buf);
  3217. timestamp.seconds = (int64_t)(packed & ((MPACK_UINT64_C(1) << 34) - 1));
  3218. timestamp.nanoseconds = (uint32_t)(packed >> 34);
  3219. break;
  3220. }
  3221. case 12:
  3222. timestamp.nanoseconds = mpack_load_u32(buf);
  3223. timestamp.seconds = mpack_load_i64(buf + 4);
  3224. break;
  3225. default:
  3226. mpack_assert(false, "unreachable");
  3227. break;
  3228. }
  3229. if (timestamp.nanoseconds > MPACK_TIMESTAMP_NANOSECONDS_MAX) {
  3230. mpack_reader_flag_error(reader, mpack_error_invalid);
  3231. mpack_timestamp_t zero = {0, 0};
  3232. return zero;
  3233. }
  3234. return timestamp;
  3235. }
  3236. #endif
  3237. #if MPACK_READ_TRACKING
  3238. void mpack_done_type(mpack_reader_t* reader, mpack_type_t type) {
  3239. if (mpack_reader_error(reader) == mpack_ok)
  3240. mpack_reader_flag_if_error(reader, mpack_track_pop(&reader->track, type));
  3241. }
  3242. #endif
  3243. #if MPACK_DEBUG && MPACK_STDIO
  3244. static size_t mpack_print_read_prefix(mpack_reader_t* reader, size_t length, char* buffer, size_t buffer_size) {
  3245. if (length == 0)
  3246. return 0;
  3247. size_t read = (length < buffer_size) ? length : buffer_size;
  3248. mpack_read_bytes(reader, buffer, read);
  3249. if (mpack_reader_error(reader) != mpack_ok)
  3250. return 0;
  3251. mpack_skip_bytes(reader, length - read);
  3252. return read;
  3253. }
  3254. static void mpack_print_element(mpack_reader_t* reader, mpack_print_t* print, size_t depth) {
  3255. mpack_tag_t val = mpack_read_tag(reader);
  3256. if (mpack_reader_error(reader) != mpack_ok)
  3257. return;
  3258. // We read some bytes from bin and ext so we can print its prefix in hex.
  3259. char buffer[MPACK_PRINT_BYTE_COUNT];
  3260. size_t count = 0;
  3261. size_t i, j;
  3262. switch (val.type) {
  3263. case mpack_type_str:
  3264. mpack_print_append_cstr(print, "\"");
  3265. for (i = 0; i < val.v.l; ++i) {
  3266. char c;
  3267. mpack_read_bytes(reader, &c, 1);
  3268. if (mpack_reader_error(reader) != mpack_ok)
  3269. return;
  3270. switch (c) {
  3271. case '\n': mpack_print_append_cstr(print, "\\n"); break;
  3272. case '\\': mpack_print_append_cstr(print, "\\\\"); break;
  3273. case '"': mpack_print_append_cstr(print, "\\\""); break;
  3274. default: mpack_print_append(print, &c, 1); break;
  3275. }
  3276. }
  3277. mpack_print_append_cstr(print, "\"");
  3278. mpack_done_str(reader);
  3279. return;
  3280. case mpack_type_array:
  3281. mpack_print_append_cstr(print, "[\n");
  3282. for (i = 0; i < val.v.n; ++i) {
  3283. for (j = 0; j < depth + 1; ++j)
  3284. mpack_print_append_cstr(print, " ");
  3285. mpack_print_element(reader, print, depth + 1);
  3286. if (mpack_reader_error(reader) != mpack_ok)
  3287. return;
  3288. if (i != val.v.n - 1)
  3289. mpack_print_append_cstr(print, ",");
  3290. mpack_print_append_cstr(print, "\n");
  3291. }
  3292. for (i = 0; i < depth; ++i)
  3293. mpack_print_append_cstr(print, " ");
  3294. mpack_print_append_cstr(print, "]");
  3295. mpack_done_array(reader);
  3296. return;
  3297. case mpack_type_map:
  3298. mpack_print_append_cstr(print, "{\n");
  3299. for (i = 0; i < val.v.n; ++i) {
  3300. for (j = 0; j < depth + 1; ++j)
  3301. mpack_print_append_cstr(print, " ");
  3302. mpack_print_element(reader, print, depth + 1);
  3303. if (mpack_reader_error(reader) != mpack_ok)
  3304. return;
  3305. mpack_print_append_cstr(print, ": ");
  3306. mpack_print_element(reader, print, depth + 1);
  3307. if (mpack_reader_error(reader) != mpack_ok)
  3308. return;
  3309. if (i != val.v.n - 1)
  3310. mpack_print_append_cstr(print, ",");
  3311. mpack_print_append_cstr(print, "\n");
  3312. }
  3313. for (i = 0; i < depth; ++i)
  3314. mpack_print_append_cstr(print, " ");
  3315. mpack_print_append_cstr(print, "}");
  3316. mpack_done_map(reader);
  3317. return;
  3318. // The above cases return so as not to print a pseudo-json value. The
  3319. // below cases break and print pseudo-json.
  3320. case mpack_type_bin:
  3321. count = mpack_print_read_prefix(reader, mpack_tag_bin_length(&val), buffer, sizeof(buffer));
  3322. mpack_done_bin(reader);
  3323. break;
  3324. #if MPACK_EXTENSIONS
  3325. case mpack_type_ext:
  3326. count = mpack_print_read_prefix(reader, mpack_tag_ext_length(&val), buffer, sizeof(buffer));
  3327. mpack_done_ext(reader);
  3328. break;
  3329. #endif
  3330. default:
  3331. break;
  3332. }
  3333. char buf[256];
  3334. mpack_tag_debug_pseudo_json(val, buf, sizeof(buf), buffer, count);
  3335. mpack_print_append_cstr(print, buf);
  3336. }
  3337. static void mpack_print_and_destroy(mpack_reader_t* reader, mpack_print_t* print, size_t depth) {
  3338. size_t i;
  3339. for (i = 0; i < depth; ++i)
  3340. mpack_print_append_cstr(print, " ");
  3341. mpack_print_element(reader, print, depth);
  3342. size_t remaining = mpack_reader_remaining(reader, NULL);
  3343. char buf[256];
  3344. if (mpack_reader_destroy(reader) != mpack_ok) {
  3345. mpack_snprintf(buf, sizeof(buf), "\n<mpack parsing error %s>", mpack_error_to_string(mpack_reader_error(reader)));
  3346. buf[sizeof(buf) - 1] = '\0';
  3347. mpack_print_append_cstr(print, buf);
  3348. } else if (remaining > 0) {
  3349. mpack_snprintf(buf, sizeof(buf), "\n<%i extra bytes at end of message>", (int)remaining);
  3350. buf[sizeof(buf) - 1] = '\0';
  3351. mpack_print_append_cstr(print, buf);
  3352. }
  3353. }
  3354. static void mpack_print_data(const char* data, size_t len, mpack_print_t* print, size_t depth) {
  3355. mpack_reader_t reader;
  3356. mpack_reader_init_data(&reader, data, len);
  3357. mpack_print_and_destroy(&reader, print, depth);
  3358. }
  3359. void mpack_print_data_to_buffer(const char* data, size_t data_size, char* buffer, size_t buffer_size) {
  3360. if (buffer_size == 0) {
  3361. mpack_assert(false, "buffer size is zero!");
  3362. return;
  3363. }
  3364. mpack_print_t print;
  3365. mpack_memset(&print, 0, sizeof(print));
  3366. print.buffer = buffer;
  3367. print.size = buffer_size;
  3368. mpack_print_data(data, data_size, &print, 0);
  3369. mpack_print_append(&print, "", 1); // null-terminator
  3370. mpack_print_flush(&print);
  3371. // we always make sure there's a null-terminator at the end of the buffer
  3372. // in case we ran out of space.
  3373. print.buffer[print.size - 1] = '\0';
  3374. }
  3375. void mpack_print_data_to_callback(const char* data, size_t size, mpack_print_callback_t callback, void* context) {
  3376. char buffer[1024];
  3377. mpack_print_t print;
  3378. mpack_memset(&print, 0, sizeof(print));
  3379. print.buffer = buffer;
  3380. print.size = sizeof(buffer);
  3381. print.callback = callback;
  3382. print.context = context;
  3383. mpack_print_data(data, size, &print, 0);
  3384. mpack_print_flush(&print);
  3385. }
  3386. void mpack_print_data_to_file(const char* data, size_t len, FILE* file) {
  3387. mpack_assert(data != NULL, "data is NULL");
  3388. mpack_assert(file != NULL, "file is NULL");
  3389. char buffer[1024];
  3390. mpack_print_t print;
  3391. mpack_memset(&print, 0, sizeof(print));
  3392. print.buffer = buffer;
  3393. print.size = sizeof(buffer);
  3394. print.callback = &mpack_print_file_callback;
  3395. print.context = file;
  3396. mpack_print_data(data, len, &print, 2);
  3397. mpack_print_append_cstr(&print, "\n");
  3398. mpack_print_flush(&print);
  3399. }
  3400. void mpack_print_stdfile_to_callback(FILE* file, mpack_print_callback_t callback, void* context) {
  3401. char buffer[1024];
  3402. mpack_print_t print;
  3403. mpack_memset(&print, 0, sizeof(print));
  3404. print.buffer = buffer;
  3405. print.size = sizeof(buffer);
  3406. print.callback = callback;
  3407. print.context = context;
  3408. mpack_reader_t reader;
  3409. mpack_reader_init_stdfile(&reader, file, false);
  3410. mpack_print_and_destroy(&reader, &print, 0);
  3411. mpack_print_flush(&print);
  3412. }
  3413. #endif
  3414. #endif
  3415. MPACK_SILENCE_WARNINGS_END
  3416. /* mpack/mpack-expect.c.c */
  3417. #define MPACK_INTERNAL 1
  3418. /* #include "mpack-expect.h" */
  3419. MPACK_SILENCE_WARNINGS_BEGIN
  3420. #if MPACK_EXPECT
  3421. // Helpers
  3422. MPACK_STATIC_INLINE uint8_t mpack_expect_native_u8(mpack_reader_t* reader) {
  3423. if (mpack_reader_error(reader) != mpack_ok)
  3424. return 0;
  3425. uint8_t type;
  3426. if (!mpack_reader_ensure(reader, sizeof(type)))
  3427. return 0;
  3428. type = mpack_load_u8(reader->data);
  3429. reader->data += sizeof(type);
  3430. return type;
  3431. }
  3432. #if !MPACK_OPTIMIZE_FOR_SIZE
  3433. MPACK_STATIC_INLINE uint16_t mpack_expect_native_u16(mpack_reader_t* reader) {
  3434. if (mpack_reader_error(reader) != mpack_ok)
  3435. return 0;
  3436. uint16_t type;
  3437. if (!mpack_reader_ensure(reader, sizeof(type)))
  3438. return 0;
  3439. type = mpack_load_u16(reader->data);
  3440. reader->data += sizeof(type);
  3441. return type;
  3442. }
  3443. MPACK_STATIC_INLINE uint32_t mpack_expect_native_u32(mpack_reader_t* reader) {
  3444. if (mpack_reader_error(reader) != mpack_ok)
  3445. return 0;
  3446. uint32_t type;
  3447. if (!mpack_reader_ensure(reader, sizeof(type)))
  3448. return 0;
  3449. type = mpack_load_u32(reader->data);
  3450. reader->data += sizeof(type);
  3451. return type;
  3452. }
  3453. #endif
  3454. MPACK_STATIC_INLINE uint8_t mpack_expect_type_byte(mpack_reader_t* reader) {
  3455. mpack_reader_track_element(reader);
  3456. return mpack_expect_native_u8(reader);
  3457. }
  3458. // Basic Number Functions
  3459. uint8_t mpack_expect_u8(mpack_reader_t* reader) {
  3460. mpack_tag_t var = mpack_read_tag(reader);
  3461. if (var.type == mpack_type_uint) {
  3462. if (var.v.u <= MPACK_UINT8_MAX)
  3463. return (uint8_t)var.v.u;
  3464. } else if (var.type == mpack_type_int) {
  3465. if (var.v.i >= 0 && var.v.i <= MPACK_UINT8_MAX)
  3466. return (uint8_t)var.v.i;
  3467. }
  3468. mpack_reader_flag_error(reader, mpack_error_type);
  3469. return 0;
  3470. }
  3471. uint16_t mpack_expect_u16(mpack_reader_t* reader) {
  3472. mpack_tag_t var = mpack_read_tag(reader);
  3473. if (var.type == mpack_type_uint) {
  3474. if (var.v.u <= MPACK_UINT16_MAX)
  3475. return (uint16_t)var.v.u;
  3476. } else if (var.type == mpack_type_int) {
  3477. if (var.v.i >= 0 && var.v.i <= MPACK_UINT16_MAX)
  3478. return (uint16_t)var.v.i;
  3479. }
  3480. mpack_reader_flag_error(reader, mpack_error_type);
  3481. return 0;
  3482. }
  3483. uint32_t mpack_expect_u32(mpack_reader_t* reader) {
  3484. mpack_tag_t var = mpack_read_tag(reader);
  3485. if (var.type == mpack_type_uint) {
  3486. if (var.v.u <= MPACK_UINT32_MAX)
  3487. return (uint32_t)var.v.u;
  3488. } else if (var.type == mpack_type_int) {
  3489. if (var.v.i >= 0 && var.v.i <= MPACK_UINT32_MAX)
  3490. return (uint32_t)var.v.i;
  3491. }
  3492. mpack_reader_flag_error(reader, mpack_error_type);
  3493. return 0;
  3494. }
  3495. uint64_t mpack_expect_u64(mpack_reader_t* reader) {
  3496. mpack_tag_t var = mpack_read_tag(reader);
  3497. if (var.type == mpack_type_uint) {
  3498. return var.v.u;
  3499. } else if (var.type == mpack_type_int) {
  3500. if (var.v.i >= 0)
  3501. return (uint64_t)var.v.i;
  3502. }
  3503. mpack_reader_flag_error(reader, mpack_error_type);
  3504. return 0;
  3505. }
  3506. int8_t mpack_expect_i8(mpack_reader_t* reader) {
  3507. mpack_tag_t var = mpack_read_tag(reader);
  3508. if (var.type == mpack_type_uint) {
  3509. if (var.v.u <= MPACK_INT8_MAX)
  3510. return (int8_t)var.v.u;
  3511. } else if (var.type == mpack_type_int) {
  3512. if (var.v.i >= MPACK_INT8_MIN && var.v.i <= MPACK_INT8_MAX)
  3513. return (int8_t)var.v.i;
  3514. }
  3515. mpack_reader_flag_error(reader, mpack_error_type);
  3516. return 0;
  3517. }
  3518. int16_t mpack_expect_i16(mpack_reader_t* reader) {
  3519. mpack_tag_t var = mpack_read_tag(reader);
  3520. if (var.type == mpack_type_uint) {
  3521. if (var.v.u <= MPACK_INT16_MAX)
  3522. return (int16_t)var.v.u;
  3523. } else if (var.type == mpack_type_int) {
  3524. if (var.v.i >= MPACK_INT16_MIN && var.v.i <= MPACK_INT16_MAX)
  3525. return (int16_t)var.v.i;
  3526. }
  3527. mpack_reader_flag_error(reader, mpack_error_type);
  3528. return 0;
  3529. }
  3530. int32_t mpack_expect_i32(mpack_reader_t* reader) {
  3531. mpack_tag_t var = mpack_read_tag(reader);
  3532. if (var.type == mpack_type_uint) {
  3533. if (var.v.u <= MPACK_INT32_MAX)
  3534. return (int32_t)var.v.u;
  3535. } else if (var.type == mpack_type_int) {
  3536. if (var.v.i >= MPACK_INT32_MIN && var.v.i <= MPACK_INT32_MAX)
  3537. return (int32_t)var.v.i;
  3538. }
  3539. mpack_reader_flag_error(reader, mpack_error_type);
  3540. return 0;
  3541. }
  3542. int64_t mpack_expect_i64(mpack_reader_t* reader) {
  3543. mpack_tag_t var = mpack_read_tag(reader);
  3544. if (var.type == mpack_type_uint) {
  3545. if (var.v.u <= MPACK_INT64_MAX)
  3546. return (int64_t)var.v.u;
  3547. } else if (var.type == mpack_type_int) {
  3548. return var.v.i;
  3549. }
  3550. mpack_reader_flag_error(reader, mpack_error_type);
  3551. return 0;
  3552. }
  3553. #if MPACK_FLOAT
  3554. float mpack_expect_float(mpack_reader_t* reader) {
  3555. mpack_tag_t var = mpack_read_tag(reader);
  3556. if (var.type == mpack_type_uint)
  3557. return (float)var.v.u;
  3558. if (var.type == mpack_type_int)
  3559. return (float)var.v.i;
  3560. if (var.type == mpack_type_float)
  3561. return var.v.f;
  3562. if (var.type == mpack_type_double) {
  3563. #if MPACK_DOUBLE
  3564. return (float)var.v.d;
  3565. #else
  3566. return mpack_shorten_raw_double_to_float(var.v.d);
  3567. #endif
  3568. }
  3569. mpack_reader_flag_error(reader, mpack_error_type);
  3570. return 0.0f;
  3571. }
  3572. #endif
  3573. #if MPACK_DOUBLE
  3574. double mpack_expect_double(mpack_reader_t* reader) {
  3575. mpack_tag_t var = mpack_read_tag(reader);
  3576. if (var.type == mpack_type_uint)
  3577. return (double)var.v.u;
  3578. else if (var.type == mpack_type_int)
  3579. return (double)var.v.i;
  3580. else if (var.type == mpack_type_float)
  3581. return (double)var.v.f;
  3582. else if (var.type == mpack_type_double)
  3583. return var.v.d;
  3584. mpack_reader_flag_error(reader, mpack_error_type);
  3585. return 0.0;
  3586. }
  3587. #endif
  3588. #if MPACK_FLOAT
  3589. float mpack_expect_float_strict(mpack_reader_t* reader) {
  3590. mpack_tag_t var = mpack_read_tag(reader);
  3591. if (var.type == mpack_type_float)
  3592. return var.v.f;
  3593. mpack_reader_flag_error(reader, mpack_error_type);
  3594. return 0.0f;
  3595. }
  3596. #endif
  3597. #if MPACK_DOUBLE
  3598. double mpack_expect_double_strict(mpack_reader_t* reader) {
  3599. mpack_tag_t var = mpack_read_tag(reader);
  3600. if (var.type == mpack_type_float)
  3601. return (double)var.v.f;
  3602. else if (var.type == mpack_type_double)
  3603. return var.v.d;
  3604. mpack_reader_flag_error(reader, mpack_error_type);
  3605. return 0.0;
  3606. }
  3607. #endif
  3608. #if !MPACK_FLOAT
  3609. uint32_t mpack_expect_raw_float(mpack_reader_t* reader) {
  3610. mpack_tag_t var = mpack_read_tag(reader);
  3611. if (var.type == mpack_type_float)
  3612. return var.v.f;
  3613. mpack_reader_flag_error(reader, mpack_error_type);
  3614. return 0;
  3615. }
  3616. #endif
  3617. #if !MPACK_DOUBLE
  3618. uint64_t mpack_expect_raw_double(mpack_reader_t* reader) {
  3619. mpack_tag_t var = mpack_read_tag(reader);
  3620. if (var.type == mpack_type_double)
  3621. return var.v.d;
  3622. mpack_reader_flag_error(reader, mpack_error_type);
  3623. return 0;
  3624. }
  3625. #endif
  3626. // Ranged Number Functions
  3627. //
  3628. // All ranged functions are identical other than the type, so we
  3629. // define their content with a macro. The prototypes are still written
  3630. // out in full to support ctags/IDE tools.
  3631. #define MPACK_EXPECT_RANGE_IMPL(name, type_t) \
  3632. \
  3633. /* make sure the range is sensible */ \
  3634. mpack_assert(min_value <= max_value, \
  3635. "min_value %i must be less than or equal to max_value %i", \
  3636. min_value, max_value); \
  3637. \
  3638. /* read the value */ \
  3639. type_t val = mpack_expect_##name(reader); \
  3640. if (mpack_reader_error(reader) != mpack_ok) \
  3641. return min_value; \
  3642. \
  3643. /* make sure it fits */ \
  3644. if (val < min_value || val > max_value) { \
  3645. mpack_reader_flag_error(reader, mpack_error_type); \
  3646. return min_value; \
  3647. } \
  3648. \
  3649. return val;
  3650. uint8_t mpack_expect_u8_range(mpack_reader_t* reader, uint8_t min_value, uint8_t max_value) {MPACK_EXPECT_RANGE_IMPL(u8, uint8_t)}
  3651. uint16_t mpack_expect_u16_range(mpack_reader_t* reader, uint16_t min_value, uint16_t max_value) {MPACK_EXPECT_RANGE_IMPL(u16, uint16_t)}
  3652. uint32_t mpack_expect_u32_range(mpack_reader_t* reader, uint32_t min_value, uint32_t max_value) {MPACK_EXPECT_RANGE_IMPL(u32, uint32_t)}
  3653. uint64_t mpack_expect_u64_range(mpack_reader_t* reader, uint64_t min_value, uint64_t max_value) {MPACK_EXPECT_RANGE_IMPL(u64, uint64_t)}
  3654. int8_t mpack_expect_i8_range(mpack_reader_t* reader, int8_t min_value, int8_t max_value) {MPACK_EXPECT_RANGE_IMPL(i8, int8_t)}
  3655. int16_t mpack_expect_i16_range(mpack_reader_t* reader, int16_t min_value, int16_t max_value) {MPACK_EXPECT_RANGE_IMPL(i16, int16_t)}
  3656. int32_t mpack_expect_i32_range(mpack_reader_t* reader, int32_t min_value, int32_t max_value) {MPACK_EXPECT_RANGE_IMPL(i32, int32_t)}
  3657. int64_t mpack_expect_i64_range(mpack_reader_t* reader, int64_t min_value, int64_t max_value) {MPACK_EXPECT_RANGE_IMPL(i64, int64_t)}
  3658. #if MPACK_FLOAT
  3659. float mpack_expect_float_range(mpack_reader_t* reader, float min_value, float max_value) {MPACK_EXPECT_RANGE_IMPL(float, float)}
  3660. #endif
  3661. #if MPACK_DOUBLE
  3662. double mpack_expect_double_range(mpack_reader_t* reader, double min_value, double max_value) {MPACK_EXPECT_RANGE_IMPL(double, double)}
  3663. #endif
  3664. uint32_t mpack_expect_map_range(mpack_reader_t* reader, uint32_t min_value, uint32_t max_value) {MPACK_EXPECT_RANGE_IMPL(map, uint32_t)}
  3665. uint32_t mpack_expect_array_range(mpack_reader_t* reader, uint32_t min_value, uint32_t max_value) {MPACK_EXPECT_RANGE_IMPL(array, uint32_t)}
  3666. // Matching Number Functions
  3667. void mpack_expect_uint_match(mpack_reader_t* reader, uint64_t value) {
  3668. if (mpack_expect_u64(reader) != value)
  3669. mpack_reader_flag_error(reader, mpack_error_type);
  3670. }
  3671. void mpack_expect_int_match(mpack_reader_t* reader, int64_t value) {
  3672. if (mpack_expect_i64(reader) != value)
  3673. mpack_reader_flag_error(reader, mpack_error_type);
  3674. }
  3675. // Other Basic Types
  3676. void mpack_expect_nil(mpack_reader_t* reader) {
  3677. if (mpack_expect_type_byte(reader) != 0xc0)
  3678. mpack_reader_flag_error(reader, mpack_error_type);
  3679. }
  3680. bool mpack_expect_bool(mpack_reader_t* reader) {
  3681. uint8_t type = mpack_expect_type_byte(reader);
  3682. if ((type & ~1) != 0xc2)
  3683. mpack_reader_flag_error(reader, mpack_error_type);
  3684. return (bool)(type & 1);
  3685. }
  3686. void mpack_expect_true(mpack_reader_t* reader) {
  3687. if (mpack_expect_bool(reader) != true)
  3688. mpack_reader_flag_error(reader, mpack_error_type);
  3689. }
  3690. void mpack_expect_false(mpack_reader_t* reader) {
  3691. if (mpack_expect_bool(reader) != false)
  3692. mpack_reader_flag_error(reader, mpack_error_type);
  3693. }
  3694. #if MPACK_EXTENSIONS
  3695. mpack_timestamp_t mpack_expect_timestamp(mpack_reader_t* reader) {
  3696. mpack_timestamp_t zero = {0, 0};
  3697. mpack_tag_t tag = mpack_read_tag(reader);
  3698. if (tag.type != mpack_type_ext) {
  3699. mpack_reader_flag_error(reader, mpack_error_type);
  3700. return zero;
  3701. }
  3702. if (mpack_tag_ext_exttype(&tag) != MPACK_EXTTYPE_TIMESTAMP) {
  3703. mpack_reader_flag_error(reader, mpack_error_type);
  3704. return zero;
  3705. }
  3706. return mpack_read_timestamp(reader, mpack_tag_ext_length(&tag));
  3707. }
  3708. int64_t mpack_expect_timestamp_truncate(mpack_reader_t* reader) {
  3709. return mpack_expect_timestamp(reader).seconds;
  3710. }
  3711. #endif
  3712. // Compound Types
  3713. uint32_t mpack_expect_map(mpack_reader_t* reader) {
  3714. mpack_tag_t var = mpack_read_tag(reader);
  3715. if (var.type == mpack_type_map)
  3716. return var.v.n;
  3717. mpack_reader_flag_error(reader, mpack_error_type);
  3718. return 0;
  3719. }
  3720. void mpack_expect_map_match(mpack_reader_t* reader, uint32_t count) {
  3721. if (mpack_expect_map(reader) != count)
  3722. mpack_reader_flag_error(reader, mpack_error_type);
  3723. }
  3724. bool mpack_expect_map_or_nil(mpack_reader_t* reader, uint32_t* count) {
  3725. mpack_assert(count != NULL, "count cannot be NULL");
  3726. mpack_tag_t var = mpack_read_tag(reader);
  3727. if (var.type == mpack_type_nil) {
  3728. *count = 0;
  3729. return false;
  3730. }
  3731. if (var.type == mpack_type_map) {
  3732. *count = var.v.n;
  3733. return true;
  3734. }
  3735. mpack_reader_flag_error(reader, mpack_error_type);
  3736. *count = 0;
  3737. return false;
  3738. }
  3739. bool mpack_expect_map_max_or_nil(mpack_reader_t* reader, uint32_t max_count, uint32_t* count) {
  3740. mpack_assert(count != NULL, "count cannot be NULL");
  3741. bool has_map = mpack_expect_map_or_nil(reader, count);
  3742. if (has_map && *count > max_count) {
  3743. *count = 0;
  3744. mpack_reader_flag_error(reader, mpack_error_type);
  3745. return false;
  3746. }
  3747. return has_map;
  3748. }
  3749. uint32_t mpack_expect_array(mpack_reader_t* reader) {
  3750. mpack_tag_t var = mpack_read_tag(reader);
  3751. if (var.type == mpack_type_array)
  3752. return var.v.n;
  3753. mpack_reader_flag_error(reader, mpack_error_type);
  3754. return 0;
  3755. }
  3756. void mpack_expect_array_match(mpack_reader_t* reader, uint32_t count) {
  3757. if (mpack_expect_array(reader) != count)
  3758. mpack_reader_flag_error(reader, mpack_error_type);
  3759. }
  3760. bool mpack_expect_array_or_nil(mpack_reader_t* reader, uint32_t* count) {
  3761. mpack_assert(count != NULL, "count cannot be NULL");
  3762. mpack_tag_t var = mpack_read_tag(reader);
  3763. if (var.type == mpack_type_nil) {
  3764. *count = 0;
  3765. return false;
  3766. }
  3767. if (var.type == mpack_type_array) {
  3768. *count = var.v.n;
  3769. return true;
  3770. }
  3771. mpack_reader_flag_error(reader, mpack_error_type);
  3772. *count = 0;
  3773. return false;
  3774. }
  3775. bool mpack_expect_array_max_or_nil(mpack_reader_t* reader, uint32_t max_count, uint32_t* count) {
  3776. mpack_assert(count != NULL, "count cannot be NULL");
  3777. bool has_array = mpack_expect_array_or_nil(reader, count);
  3778. if (has_array && *count > max_count) {
  3779. *count = 0;
  3780. mpack_reader_flag_error(reader, mpack_error_type);
  3781. return false;
  3782. }
  3783. return has_array;
  3784. }
  3785. #ifdef MPACK_MALLOC
  3786. void* mpack_expect_array_alloc_impl(mpack_reader_t* reader, size_t element_size, uint32_t max_count, uint32_t* out_count, bool allow_nil) {
  3787. mpack_assert(out_count != NULL, "out_count cannot be NULL");
  3788. *out_count = 0;
  3789. uint32_t count;
  3790. bool has_array = true;
  3791. if (allow_nil)
  3792. has_array = mpack_expect_array_max_or_nil(reader, max_count, &count);
  3793. else
  3794. count = mpack_expect_array_max(reader, max_count);
  3795. if (mpack_reader_error(reader))
  3796. return NULL;
  3797. // size 0 is not an error; we return NULL for no elements.
  3798. if (count == 0) {
  3799. // we call mpack_done_array() automatically ONLY if we are using
  3800. // the _or_nil variant. this is the only way to allow nil and empty
  3801. // to work the same way.
  3802. if (allow_nil && has_array)
  3803. mpack_done_array(reader);
  3804. return NULL;
  3805. }
  3806. void* p = MPACK_MALLOC(element_size * count);
  3807. if (p == NULL) {
  3808. mpack_reader_flag_error(reader, mpack_error_memory);
  3809. return NULL;
  3810. }
  3811. *out_count = count;
  3812. return p;
  3813. }
  3814. #endif
  3815. // Str, Bin and Ext Functions
  3816. uint32_t mpack_expect_str(mpack_reader_t* reader) {
  3817. #if MPACK_OPTIMIZE_FOR_SIZE
  3818. mpack_tag_t var = mpack_read_tag(reader);
  3819. if (var.type == mpack_type_str)
  3820. return var.v.l;
  3821. mpack_reader_flag_error(reader, mpack_error_type);
  3822. return 0;
  3823. #else
  3824. uint8_t type = mpack_expect_type_byte(reader);
  3825. uint32_t count;
  3826. if ((type >> 5) == 5) {
  3827. count = type & (uint8_t)~0xe0;
  3828. } else if (type == 0xd9) {
  3829. count = mpack_expect_native_u8(reader);
  3830. } else if (type == 0xda) {
  3831. count = mpack_expect_native_u16(reader);
  3832. } else if (type == 0xdb) {
  3833. count = mpack_expect_native_u32(reader);
  3834. } else {
  3835. mpack_reader_flag_error(reader, mpack_error_type);
  3836. return 0;
  3837. }
  3838. #if MPACK_READ_TRACKING
  3839. mpack_reader_flag_if_error(reader, mpack_track_push(&reader->track, mpack_type_str, count));
  3840. #endif
  3841. return count;
  3842. #endif
  3843. }
  3844. size_t mpack_expect_str_buf(mpack_reader_t* reader, char* buf, size_t bufsize) {
  3845. mpack_assert(buf != NULL, "buf cannot be NULL");
  3846. size_t length = mpack_expect_str(reader);
  3847. if (mpack_reader_error(reader))
  3848. return 0;
  3849. if (length > bufsize) {
  3850. mpack_reader_flag_error(reader, mpack_error_too_big);
  3851. return 0;
  3852. }
  3853. mpack_read_bytes(reader, buf, length);
  3854. if (mpack_reader_error(reader))
  3855. return 0;
  3856. mpack_done_str(reader);
  3857. return length;
  3858. }
  3859. size_t mpack_expect_utf8(mpack_reader_t* reader, char* buf, size_t size) {
  3860. mpack_assert(buf != NULL, "buf cannot be NULL");
  3861. size_t length = mpack_expect_str_buf(reader, buf, size);
  3862. if (!mpack_utf8_check(buf, length)) {
  3863. mpack_reader_flag_error(reader, mpack_error_type);
  3864. return 0;
  3865. }
  3866. return length;
  3867. }
  3868. uint32_t mpack_expect_bin(mpack_reader_t* reader) {
  3869. mpack_tag_t var = mpack_read_tag(reader);
  3870. if (var.type == mpack_type_bin)
  3871. return var.v.l;
  3872. mpack_reader_flag_error(reader, mpack_error_type);
  3873. return 0;
  3874. }
  3875. size_t mpack_expect_bin_buf(mpack_reader_t* reader, char* buf, size_t bufsize) {
  3876. mpack_assert(buf != NULL, "buf cannot be NULL");
  3877. size_t binsize = mpack_expect_bin(reader);
  3878. if (mpack_reader_error(reader))
  3879. return 0;
  3880. if (binsize > bufsize) {
  3881. mpack_reader_flag_error(reader, mpack_error_too_big);
  3882. return 0;
  3883. }
  3884. mpack_read_bytes(reader, buf, binsize);
  3885. if (mpack_reader_error(reader))
  3886. return 0;
  3887. mpack_done_bin(reader);
  3888. return binsize;
  3889. }
  3890. void mpack_expect_bin_size_buf(mpack_reader_t* reader, char* buf, uint32_t size) {
  3891. mpack_assert(buf != NULL, "buf cannot be NULL");
  3892. mpack_expect_bin_size(reader, size);
  3893. mpack_read_bytes(reader, buf, size);
  3894. mpack_done_bin(reader);
  3895. }
  3896. #if MPACK_EXTENSIONS
  3897. uint32_t mpack_expect_ext(mpack_reader_t* reader, int8_t* type) {
  3898. mpack_tag_t var = mpack_read_tag(reader);
  3899. if (var.type == mpack_type_ext) {
  3900. *type = mpack_tag_ext_exttype(&var);
  3901. return mpack_tag_ext_length(&var);
  3902. }
  3903. *type = 0;
  3904. mpack_reader_flag_error(reader, mpack_error_type);
  3905. return 0;
  3906. }
  3907. size_t mpack_expect_ext_buf(mpack_reader_t* reader, int8_t* type, char* buf, size_t bufsize) {
  3908. mpack_assert(buf != NULL, "buf cannot be NULL");
  3909. size_t extsize = mpack_expect_ext(reader, type);
  3910. if (mpack_reader_error(reader))
  3911. return 0;
  3912. if (extsize > bufsize) {
  3913. *type = 0;
  3914. mpack_reader_flag_error(reader, mpack_error_too_big);
  3915. return 0;
  3916. }
  3917. mpack_read_bytes(reader, buf, extsize);
  3918. if (mpack_reader_error(reader)) {
  3919. *type = 0;
  3920. return 0;
  3921. }
  3922. mpack_done_ext(reader);
  3923. return extsize;
  3924. }
  3925. #endif
  3926. void mpack_expect_cstr(mpack_reader_t* reader, char* buf, size_t bufsize) {
  3927. uint32_t length = mpack_expect_str(reader);
  3928. mpack_read_cstr(reader, buf, bufsize, length);
  3929. mpack_done_str(reader);
  3930. }
  3931. void mpack_expect_utf8_cstr(mpack_reader_t* reader, char* buf, size_t bufsize) {
  3932. uint32_t length = mpack_expect_str(reader);
  3933. mpack_read_utf8_cstr(reader, buf, bufsize, length);
  3934. mpack_done_str(reader);
  3935. }
  3936. #ifdef MPACK_MALLOC
  3937. static char* mpack_expect_cstr_alloc_unchecked(mpack_reader_t* reader, size_t maxsize, size_t* out_length) {
  3938. mpack_assert(out_length != NULL, "out_length cannot be NULL");
  3939. *out_length = 0;
  3940. // make sure argument makes sense
  3941. if (maxsize < 1) {
  3942. mpack_break("maxsize is zero; you must have room for at least a null-terminator");
  3943. mpack_reader_flag_error(reader, mpack_error_bug);
  3944. return NULL;
  3945. }
  3946. if (SIZE_MAX < MPACK_UINT32_MAX) {
  3947. if (maxsize > SIZE_MAX)
  3948. maxsize = SIZE_MAX;
  3949. } else {
  3950. if (maxsize > (size_t)MPACK_UINT32_MAX)
  3951. maxsize = (size_t)MPACK_UINT32_MAX;
  3952. }
  3953. size_t length = mpack_expect_str_max(reader, (uint32_t)maxsize - 1);
  3954. char* str = mpack_read_bytes_alloc_impl(reader, length, true);
  3955. mpack_done_str(reader);
  3956. if (str)
  3957. *out_length = length;
  3958. return str;
  3959. }
  3960. char* mpack_expect_cstr_alloc(mpack_reader_t* reader, size_t maxsize) {
  3961. size_t length;
  3962. char* str = mpack_expect_cstr_alloc_unchecked(reader, maxsize, &length);
  3963. if (str && !mpack_str_check_no_null(str, length)) {
  3964. MPACK_FREE(str);
  3965. mpack_reader_flag_error(reader, mpack_error_type);
  3966. return NULL;
  3967. }
  3968. return str;
  3969. }
  3970. char* mpack_expect_utf8_cstr_alloc(mpack_reader_t* reader, size_t maxsize) {
  3971. size_t length;
  3972. char* str = mpack_expect_cstr_alloc_unchecked(reader, maxsize, &length);
  3973. if (str && !mpack_utf8_check_no_null(str, length)) {
  3974. MPACK_FREE(str);
  3975. mpack_reader_flag_error(reader, mpack_error_type);
  3976. return NULL;
  3977. }
  3978. return str;
  3979. }
  3980. #endif
  3981. void mpack_expect_str_match(mpack_reader_t* reader, const char* str, size_t len) {
  3982. mpack_assert(str != NULL, "str cannot be NULL");
  3983. // expect a str the correct length
  3984. if (len > MPACK_UINT32_MAX)
  3985. mpack_reader_flag_error(reader, mpack_error_type);
  3986. mpack_expect_str_length(reader, (uint32_t)len);
  3987. if (mpack_reader_error(reader))
  3988. return;
  3989. mpack_reader_track_bytes(reader, (uint32_t)len);
  3990. // check each byte one by one (matched strings are likely to be very small)
  3991. for (; len > 0; --len) {
  3992. if (mpack_expect_native_u8(reader) != *str++) {
  3993. mpack_reader_flag_error(reader, mpack_error_type);
  3994. return;
  3995. }
  3996. }
  3997. mpack_done_str(reader);
  3998. }
  3999. void mpack_expect_tag(mpack_reader_t* reader, mpack_tag_t expected) {
  4000. mpack_tag_t actual = mpack_read_tag(reader);
  4001. if (!mpack_tag_equal(actual, expected))
  4002. mpack_reader_flag_error(reader, mpack_error_type);
  4003. }
  4004. #ifdef MPACK_MALLOC
  4005. char* mpack_expect_bin_alloc(mpack_reader_t* reader, size_t maxsize, size_t* size) {
  4006. mpack_assert(size != NULL, "size cannot be NULL");
  4007. *size = 0;
  4008. if (SIZE_MAX < MPACK_UINT32_MAX) {
  4009. if (maxsize > SIZE_MAX)
  4010. maxsize = SIZE_MAX;
  4011. } else {
  4012. if (maxsize > (size_t)MPACK_UINT32_MAX)
  4013. maxsize = (size_t)MPACK_UINT32_MAX;
  4014. }
  4015. size_t length = mpack_expect_bin_max(reader, (uint32_t)maxsize);
  4016. if (mpack_reader_error(reader))
  4017. return NULL;
  4018. char* data = mpack_read_bytes_alloc(reader, length);
  4019. mpack_done_bin(reader);
  4020. if (data)
  4021. *size = length;
  4022. return data;
  4023. }
  4024. #endif
  4025. #if MPACK_EXTENSIONS && defined(MPACK_MALLOC)
  4026. char* mpack_expect_ext_alloc(mpack_reader_t* reader, int8_t* type, size_t maxsize, size_t* size) {
  4027. mpack_assert(size != NULL, "size cannot be NULL");
  4028. *size = 0;
  4029. if (SIZE_MAX < MPACK_UINT32_MAX) {
  4030. if (maxsize > SIZE_MAX)
  4031. maxsize = SIZE_MAX;
  4032. } else {
  4033. if (maxsize > (size_t)MPACK_UINT32_MAX)
  4034. maxsize = (size_t)MPACK_UINT32_MAX;
  4035. }
  4036. size_t length = mpack_expect_ext_max(reader, type, (uint32_t)maxsize);
  4037. if (mpack_reader_error(reader))
  4038. return NULL;
  4039. char* data = mpack_read_bytes_alloc(reader, length);
  4040. mpack_done_ext(reader);
  4041. if (data) {
  4042. *size = length;
  4043. } else {
  4044. *type = 0;
  4045. }
  4046. return data;
  4047. }
  4048. #endif
  4049. size_t mpack_expect_enum(mpack_reader_t* reader, const char* strings[], size_t count) {
  4050. // read the string in-place
  4051. size_t keylen = mpack_expect_str(reader);
  4052. const char* key = mpack_read_bytes_inplace(reader, keylen);
  4053. mpack_done_str(reader);
  4054. if (mpack_reader_error(reader) != mpack_ok)
  4055. return count;
  4056. // find what key it matches
  4057. size_t i;
  4058. for (i = 0; i < count; ++i) {
  4059. const char* other = strings[i];
  4060. size_t otherlen = mpack_strlen(other);
  4061. if (keylen == otherlen && mpack_memcmp(key, other, keylen) == 0)
  4062. return i;
  4063. }
  4064. // no matches
  4065. mpack_reader_flag_error(reader, mpack_error_type);
  4066. return count;
  4067. }
  4068. size_t mpack_expect_enum_optional(mpack_reader_t* reader, const char* strings[], size_t count) {
  4069. if (mpack_reader_error(reader) != mpack_ok)
  4070. return count;
  4071. mpack_assert(count != 0, "count cannot be zero; no strings are valid!");
  4072. mpack_assert(strings != NULL, "strings cannot be NULL");
  4073. // the key is only recognized if it is a string
  4074. if (mpack_peek_tag(reader).type != mpack_type_str) {
  4075. mpack_discard(reader);
  4076. return count;
  4077. }
  4078. // read the string in-place
  4079. size_t keylen = mpack_expect_str(reader);
  4080. const char* key = mpack_read_bytes_inplace(reader, keylen);
  4081. mpack_done_str(reader);
  4082. if (mpack_reader_error(reader) != mpack_ok)
  4083. return count;
  4084. // find what key it matches
  4085. size_t i;
  4086. for (i = 0; i < count; ++i) {
  4087. const char* other = strings[i];
  4088. size_t otherlen = mpack_strlen(other);
  4089. if (keylen == otherlen && mpack_memcmp(key, other, keylen) == 0)
  4090. return i;
  4091. }
  4092. // no matches
  4093. return count;
  4094. }
  4095. size_t mpack_expect_key_uint(mpack_reader_t* reader, bool found[], size_t count) {
  4096. if (mpack_reader_error(reader) != mpack_ok)
  4097. return count;
  4098. if (count == 0) {
  4099. mpack_break("count cannot be zero; no keys are valid!");
  4100. mpack_reader_flag_error(reader, mpack_error_bug);
  4101. return count;
  4102. }
  4103. mpack_assert(found != NULL, "found cannot be NULL");
  4104. // the key is only recognized if it is an unsigned int
  4105. if (mpack_peek_tag(reader).type != mpack_type_uint) {
  4106. mpack_discard(reader);
  4107. return count;
  4108. }
  4109. // read the key
  4110. uint64_t value = mpack_expect_u64(reader);
  4111. if (mpack_reader_error(reader) != mpack_ok)
  4112. return count;
  4113. // unrecognized keys are fine, we just return count
  4114. if (value >= count)
  4115. return count;
  4116. // check if this key is a duplicate
  4117. if (found[value]) {
  4118. mpack_reader_flag_error(reader, mpack_error_invalid);
  4119. return count;
  4120. }
  4121. found[value] = true;
  4122. return (size_t)value;
  4123. }
  4124. size_t mpack_expect_key_cstr(mpack_reader_t* reader, const char* keys[], bool found[], size_t count) {
  4125. size_t i = mpack_expect_enum_optional(reader, keys, count);
  4126. // unrecognized keys are fine, we just return count
  4127. if (i == count)
  4128. return count;
  4129. // check if this key is a duplicate
  4130. mpack_assert(found != NULL, "found cannot be NULL");
  4131. if (found[i]) {
  4132. mpack_reader_flag_error(reader, mpack_error_invalid);
  4133. return count;
  4134. }
  4135. found[i] = true;
  4136. return i;
  4137. }
  4138. #endif
  4139. MPACK_SILENCE_WARNINGS_END
  4140. /* mpack/mpack-node.c.c */
  4141. #define MPACK_INTERNAL 1
  4142. /* #include "mpack-node.h" */
  4143. MPACK_SILENCE_WARNINGS_BEGIN
  4144. #if MPACK_NODE
  4145. MPACK_STATIC_INLINE const char* mpack_node_data_unchecked(mpack_node_t node) {
  4146. mpack_assert(mpack_node_error(node) == mpack_ok, "tree is in an error state!");
  4147. mpack_type_t type = node.data->type;
  4148. MPACK_UNUSED(type);
  4149. #if MPACK_EXTENSIONS
  4150. mpack_assert(type == mpack_type_str || type == mpack_type_bin || type == mpack_type_ext,
  4151. "node of type %i (%s) is not a data type!", type, mpack_type_to_string(type));
  4152. #else
  4153. mpack_assert(type == mpack_type_str || type == mpack_type_bin,
  4154. "node of type %i (%s) is not a data type!", type, mpack_type_to_string(type));
  4155. #endif
  4156. return node.tree->data + node.data->value.offset;
  4157. }
  4158. #if MPACK_EXTENSIONS
  4159. MPACK_STATIC_INLINE int8_t mpack_node_exttype_unchecked(mpack_node_t node) {
  4160. mpack_assert(mpack_node_error(node) == mpack_ok, "tree is in an error state!");
  4161. mpack_type_t type = node.data->type;
  4162. MPACK_UNUSED(type);
  4163. mpack_assert(type == mpack_type_ext, "node of type %i (%s) is not an ext type!",
  4164. type, mpack_type_to_string(type));
  4165. // the exttype of an ext node is stored in the byte preceding the data
  4166. return mpack_load_i8(mpack_node_data_unchecked(node) - 1);
  4167. }
  4168. #endif
  4169. /*
  4170. * Tree Parsing
  4171. */
  4172. #ifdef MPACK_MALLOC
  4173. // fix up the alloc size to make sure it exactly fits the
  4174. // maximum number of nodes it can contain (the allocator will
  4175. // waste it back anyway, but we round it down just in case)
  4176. #define MPACK_NODES_PER_PAGE \
  4177. ((MPACK_NODE_PAGE_SIZE - sizeof(mpack_tree_page_t)) / sizeof(mpack_node_data_t) + 1)
  4178. #define MPACK_PAGE_ALLOC_SIZE \
  4179. (sizeof(mpack_tree_page_t) + sizeof(mpack_node_data_t) * (MPACK_NODES_PER_PAGE - 1))
  4180. #endif
  4181. #ifdef MPACK_MALLOC
  4182. /*
  4183. * Fills the tree until we have at least enough bytes for the current node.
  4184. */
  4185. static bool mpack_tree_reserve_fill(mpack_tree_t* tree) {
  4186. mpack_assert(tree->parser.state == mpack_tree_parse_state_in_progress);
  4187. size_t bytes = tree->parser.current_node_reserved;
  4188. mpack_assert(bytes > tree->parser.possible_nodes_left,
  4189. "there are already enough bytes! call mpack_tree_ensure() instead.");
  4190. mpack_log("filling to reserve %i bytes\n", (int)bytes);
  4191. // if the necessary bytes would put us over the maximum tree
  4192. // size, fail right away.
  4193. // TODO: check for overflow?
  4194. if (tree->data_length + bytes > tree->max_size) {
  4195. mpack_tree_flag_error(tree, mpack_error_too_big);
  4196. return false;
  4197. }
  4198. // we'll need a read function to fetch more data. if there's
  4199. // no read function, the data should contain an entire message
  4200. // (or messages), so we flag it as invalid.
  4201. if (tree->read_fn == NULL) {
  4202. mpack_log("tree has no read function!\n");
  4203. mpack_tree_flag_error(tree, mpack_error_invalid);
  4204. return false;
  4205. }
  4206. // expand the buffer if needed
  4207. if (tree->data_length + bytes > tree->buffer_capacity) {
  4208. // TODO: check for overflow?
  4209. size_t new_capacity = (tree->buffer_capacity == 0) ? MPACK_BUFFER_SIZE : tree->buffer_capacity;
  4210. while (new_capacity < tree->data_length + bytes)
  4211. new_capacity *= 2;
  4212. if (new_capacity > tree->max_size)
  4213. new_capacity = tree->max_size;
  4214. mpack_log("expanding buffer from %i to %i\n", (int)tree->buffer_capacity, (int)new_capacity);
  4215. char* new_buffer;
  4216. if (tree->buffer == NULL)
  4217. new_buffer = (char*)MPACK_MALLOC(new_capacity);
  4218. else
  4219. new_buffer = (char*)mpack_realloc(tree->buffer, tree->data_length, new_capacity);
  4220. if (new_buffer == NULL) {
  4221. mpack_tree_flag_error(tree, mpack_error_memory);
  4222. return false;
  4223. }
  4224. tree->data = new_buffer;
  4225. tree->buffer = new_buffer;
  4226. tree->buffer_capacity = new_capacity;
  4227. }
  4228. // request as much data as possible, looping until we have
  4229. // all the data we need
  4230. do {
  4231. size_t read = tree->read_fn(tree, tree->buffer + tree->data_length, tree->buffer_capacity - tree->data_length);
  4232. // If the fill function encounters an error, it should flag an error on
  4233. // the tree.
  4234. if (mpack_tree_error(tree) != mpack_ok)
  4235. return false;
  4236. // We guard against fill functions that return -1 just in case.
  4237. if (read == (size_t)(-1)) {
  4238. mpack_tree_flag_error(tree, mpack_error_io);
  4239. return false;
  4240. }
  4241. // If the fill function returns 0, the data is not available yet. We
  4242. // return false to stop parsing the current node.
  4243. if (read == 0) {
  4244. mpack_log("not enough data.\n");
  4245. return false;
  4246. }
  4247. mpack_log("read %" PRIu32 " more bytes\n", (uint32_t)read);
  4248. tree->data_length += read;
  4249. tree->parser.possible_nodes_left += read;
  4250. } while (tree->parser.possible_nodes_left < bytes);
  4251. return true;
  4252. }
  4253. #endif
  4254. /*
  4255. * Ensures there are enough additional bytes in the tree for the current node
  4256. * (including reserved bytes for the children of this node, and in addition to
  4257. * the reserved bytes for children of previous compound nodes), reading more
  4258. * data if needed.
  4259. *
  4260. * extra_bytes is the number of additional bytes to reserve for the current
  4261. * node beyond the type byte (since one byte is already reserved for each node
  4262. * by its parent array or map.)
  4263. *
  4264. * This may reallocate the tree, which means the tree->data pointer may change!
  4265. *
  4266. * Returns false if not enough bytes could be read.
  4267. */
  4268. MPACK_STATIC_INLINE bool mpack_tree_reserve_bytes(mpack_tree_t* tree, size_t extra_bytes) {
  4269. mpack_assert(tree->parser.state == mpack_tree_parse_state_in_progress);
  4270. // We guard against overflow here. A compound type could declare more than
  4271. // MPACK_UINT32_MAX contents which overflows SIZE_MAX on 32-bit platforms. We
  4272. // flag mpack_error_invalid instead of mpack_error_too_big since it's far
  4273. // more likely that the message is corrupt than that the data is valid but
  4274. // not parseable on this architecture (see test_read_node_possible() in
  4275. // test-node.c .)
  4276. if ((uint64_t)tree->parser.current_node_reserved + (uint64_t)extra_bytes > SIZE_MAX) {
  4277. mpack_tree_flag_error(tree, mpack_error_invalid);
  4278. return false;
  4279. }
  4280. tree->parser.current_node_reserved += extra_bytes;
  4281. // Note that possible_nodes_left already accounts for reserved bytes for
  4282. // children of previous compound nodes. So even if there are hundreds of
  4283. // bytes left in the buffer, we might need to read anyway.
  4284. if (tree->parser.current_node_reserved <= tree->parser.possible_nodes_left)
  4285. return true;
  4286. #ifdef MPACK_MALLOC
  4287. return mpack_tree_reserve_fill(tree);
  4288. #else
  4289. return false;
  4290. #endif
  4291. }
  4292. MPACK_STATIC_INLINE size_t mpack_tree_parser_stack_capacity(mpack_tree_t* tree) {
  4293. #ifdef MPACK_MALLOC
  4294. return tree->parser.stack_capacity;
  4295. #else
  4296. return sizeof(tree->parser.stack) / sizeof(tree->parser.stack[0]);
  4297. #endif
  4298. }
  4299. static bool mpack_tree_push_stack(mpack_tree_t* tree, mpack_node_data_t* first_child, size_t total) {
  4300. mpack_tree_parser_t* parser = &tree->parser;
  4301. mpack_assert(parser->state == mpack_tree_parse_state_in_progress);
  4302. // No need to push empty containers
  4303. if (total == 0)
  4304. return true;
  4305. // Make sure we have enough room in the stack
  4306. if (parser->level + 1 == mpack_tree_parser_stack_capacity(tree)) {
  4307. #ifdef MPACK_MALLOC
  4308. size_t new_capacity = parser->stack_capacity * 2;
  4309. mpack_log("growing parse stack to capacity %i\n", (int)new_capacity);
  4310. // Replace the stack-allocated parsing stack
  4311. if (!parser->stack_owned) {
  4312. mpack_level_t* new_stack = (mpack_level_t*)MPACK_MALLOC(sizeof(mpack_level_t) * new_capacity);
  4313. if (!new_stack) {
  4314. mpack_tree_flag_error(tree, mpack_error_memory);
  4315. return false;
  4316. }
  4317. mpack_memcpy(new_stack, parser->stack, sizeof(mpack_level_t) * parser->stack_capacity);
  4318. parser->stack = new_stack;
  4319. parser->stack_owned = true;
  4320. // Realloc the allocated parsing stack
  4321. } else {
  4322. mpack_level_t* new_stack = (mpack_level_t*)mpack_realloc(parser->stack,
  4323. sizeof(mpack_level_t) * parser->stack_capacity, sizeof(mpack_level_t) * new_capacity);
  4324. if (!new_stack) {
  4325. mpack_tree_flag_error(tree, mpack_error_memory);
  4326. return false;
  4327. }
  4328. parser->stack = new_stack;
  4329. }
  4330. parser->stack_capacity = new_capacity;
  4331. #else
  4332. mpack_tree_flag_error(tree, mpack_error_too_big);
  4333. return false;
  4334. #endif
  4335. }
  4336. // Push the contents of this node onto the parsing stack
  4337. ++parser->level;
  4338. parser->stack[parser->level].child = first_child;
  4339. parser->stack[parser->level].left = total;
  4340. return true;
  4341. }
  4342. static bool mpack_tree_parse_children(mpack_tree_t* tree, mpack_node_data_t* node) {
  4343. mpack_tree_parser_t* parser = &tree->parser;
  4344. mpack_assert(parser->state == mpack_tree_parse_state_in_progress);
  4345. mpack_type_t type = node->type;
  4346. size_t total = node->len;
  4347. // Calculate total elements to read
  4348. if (type == mpack_type_map) {
  4349. if ((uint64_t)total * 2 > SIZE_MAX) {
  4350. mpack_tree_flag_error(tree, mpack_error_too_big);
  4351. return false;
  4352. }
  4353. total *= 2;
  4354. }
  4355. // Make sure we are under our total node limit (TODO can this overflow?)
  4356. tree->node_count += total;
  4357. if (tree->node_count > tree->max_nodes) {
  4358. mpack_tree_flag_error(tree, mpack_error_too_big);
  4359. return false;
  4360. }
  4361. // Each node is at least one byte. Count these bytes now to make
  4362. // sure there is enough data left.
  4363. if (!mpack_tree_reserve_bytes(tree, total))
  4364. return false;
  4365. // If there are enough nodes left in the current page, no need to grow
  4366. if (total <= parser->nodes_left) {
  4367. node->value.children = parser->nodes;
  4368. parser->nodes += total;
  4369. parser->nodes_left -= total;
  4370. } else {
  4371. #ifdef MPACK_MALLOC
  4372. // We can't grow if we're using a fixed pool (i.e. we didn't start with a page)
  4373. if (!tree->next) {
  4374. mpack_tree_flag_error(tree, mpack_error_too_big);
  4375. return false;
  4376. }
  4377. // Otherwise we need to grow, and the node's children need to be contiguous.
  4378. // This is a heuristic to decide whether we should waste the remaining space
  4379. // in the current page and start a new one, or give the children their
  4380. // own page. With a fraction of 1/8, this causes at most 12% additional
  4381. // waste. Note that reducing this too much causes less cache coherence and
  4382. // more malloc() overhead due to smaller allocations, so there's a tradeoff
  4383. // here. This heuristic could use some improvement, especially with custom
  4384. // page sizes.
  4385. mpack_tree_page_t* page;
  4386. if (total > MPACK_NODES_PER_PAGE || parser->nodes_left > MPACK_NODES_PER_PAGE / 8) {
  4387. // TODO: this should check for overflow
  4388. page = (mpack_tree_page_t*)MPACK_MALLOC(
  4389. sizeof(mpack_tree_page_t) + sizeof(mpack_node_data_t) * (total - 1));
  4390. if (page == NULL) {
  4391. mpack_tree_flag_error(tree, mpack_error_memory);
  4392. return false;
  4393. }
  4394. mpack_log("allocated seperate page %p for %i children, %i left in page of %i total\n",
  4395. (void*)page, (int)total, (int)parser->nodes_left, (int)MPACK_NODES_PER_PAGE);
  4396. node->value.children = page->nodes;
  4397. } else {
  4398. page = (mpack_tree_page_t*)MPACK_MALLOC(MPACK_PAGE_ALLOC_SIZE);
  4399. if (page == NULL) {
  4400. mpack_tree_flag_error(tree, mpack_error_memory);
  4401. return false;
  4402. }
  4403. mpack_log("allocated new page %p for %i children, wasting %i in page of %i total\n",
  4404. (void*)page, (int)total, (int)parser->nodes_left, (int)MPACK_NODES_PER_PAGE);
  4405. node->value.children = page->nodes;
  4406. parser->nodes = page->nodes + total;
  4407. parser->nodes_left = MPACK_NODES_PER_PAGE - total;
  4408. }
  4409. page->next = tree->next;
  4410. tree->next = page;
  4411. #else
  4412. // We can't grow if we don't have an allocator
  4413. mpack_tree_flag_error(tree, mpack_error_too_big);
  4414. return false;
  4415. #endif
  4416. }
  4417. return mpack_tree_push_stack(tree, node->value.children, total);
  4418. }
  4419. static bool mpack_tree_parse_bytes(mpack_tree_t* tree, mpack_node_data_t* node) {
  4420. node->value.offset = tree->size + tree->parser.current_node_reserved + 1;
  4421. return mpack_tree_reserve_bytes(tree, node->len);
  4422. }
  4423. #if MPACK_EXTENSIONS
  4424. static bool mpack_tree_parse_ext(mpack_tree_t* tree, mpack_node_data_t* node) {
  4425. // reserve space for exttype
  4426. tree->parser.current_node_reserved += sizeof(int8_t);
  4427. node->type = mpack_type_ext;
  4428. return mpack_tree_parse_bytes(tree, node);
  4429. }
  4430. #endif
  4431. static bool mpack_tree_parse_node_contents(mpack_tree_t* tree, mpack_node_data_t* node) {
  4432. mpack_assert(tree->parser.state == mpack_tree_parse_state_in_progress);
  4433. mpack_assert(node != NULL, "null node?");
  4434. // read the type. we've already accounted for this byte in
  4435. // possible_nodes_left, so we already know it is in bounds, and we don't
  4436. // need to reserve it for this node.
  4437. mpack_assert(tree->data_length > tree->size);
  4438. uint8_t type = mpack_load_u8(tree->data + tree->size);
  4439. mpack_log("node type %x\n", type);
  4440. tree->parser.current_node_reserved = 0;
  4441. // as with mpack_read_tag(), the fastest way to parse a node is to switch
  4442. // on the first byte, and to explicitly list every possible byte. we switch
  4443. // on the first four bits in size-optimized builds.
  4444. #if MPACK_OPTIMIZE_FOR_SIZE
  4445. switch (type >> 4) {
  4446. // positive fixnum
  4447. case 0x0: case 0x1: case 0x2: case 0x3:
  4448. case 0x4: case 0x5: case 0x6: case 0x7:
  4449. node->type = mpack_type_uint;
  4450. node->value.u = type;
  4451. return true;
  4452. // negative fixnum
  4453. case 0xe: case 0xf:
  4454. node->type = mpack_type_int;
  4455. node->value.i = (int8_t)type;
  4456. return true;
  4457. // fixmap
  4458. case 0x8:
  4459. node->type = mpack_type_map;
  4460. node->len = (uint32_t)(type & ~0xf0);
  4461. return mpack_tree_parse_children(tree, node);
  4462. // fixarray
  4463. case 0x9:
  4464. node->type = mpack_type_array;
  4465. node->len = (uint32_t)(type & ~0xf0);
  4466. return mpack_tree_parse_children(tree, node);
  4467. // fixstr
  4468. case 0xa: case 0xb:
  4469. node->type = mpack_type_str;
  4470. node->len = (uint32_t)(type & ~0xe0);
  4471. return mpack_tree_parse_bytes(tree, node);
  4472. // not one of the common infix types
  4473. default:
  4474. break;
  4475. }
  4476. #endif
  4477. switch (type) {
  4478. #if !MPACK_OPTIMIZE_FOR_SIZE
  4479. // positive fixnum
  4480. case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
  4481. case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  4482. case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
  4483. case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
  4484. case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
  4485. case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
  4486. case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
  4487. case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
  4488. case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
  4489. case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  4490. case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
  4491. case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  4492. case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
  4493. case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  4494. case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
  4495. case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
  4496. node->type = mpack_type_uint;
  4497. node->value.u = type;
  4498. return true;
  4499. // negative fixnum
  4500. case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  4501. case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
  4502. case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  4503. case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
  4504. node->type = mpack_type_int;
  4505. node->value.i = (int8_t)type;
  4506. return true;
  4507. // fixmap
  4508. case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
  4509. case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  4510. node->type = mpack_type_map;
  4511. node->len = (uint32_t)(type & ~0xf0);
  4512. return mpack_tree_parse_children(tree, node);
  4513. // fixarray
  4514. case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
  4515. case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  4516. node->type = mpack_type_array;
  4517. node->len = (uint32_t)(type & ~0xf0);
  4518. return mpack_tree_parse_children(tree, node);
  4519. // fixstr
  4520. case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  4521. case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
  4522. case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  4523. case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  4524. node->type = mpack_type_str;
  4525. node->len = (uint32_t)(type & ~0xe0);
  4526. return mpack_tree_parse_bytes(tree, node);
  4527. #endif
  4528. // nil
  4529. case 0xc0:
  4530. node->type = mpack_type_nil;
  4531. return true;
  4532. // bool
  4533. case 0xc2: case 0xc3:
  4534. node->type = mpack_type_bool;
  4535. node->value.b = type & 1;
  4536. return true;
  4537. // bin8
  4538. case 0xc4:
  4539. node->type = mpack_type_bin;
  4540. if (!mpack_tree_reserve_bytes(tree, sizeof(uint8_t)))
  4541. return false;
  4542. node->len = mpack_load_u8(tree->data + tree->size + 1);
  4543. return mpack_tree_parse_bytes(tree, node);
  4544. // bin16
  4545. case 0xc5:
  4546. node->type = mpack_type_bin;
  4547. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4548. return false;
  4549. node->len = mpack_load_u16(tree->data + tree->size + 1);
  4550. return mpack_tree_parse_bytes(tree, node);
  4551. // bin32
  4552. case 0xc6:
  4553. node->type = mpack_type_bin;
  4554. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4555. return false;
  4556. node->len = mpack_load_u32(tree->data + tree->size + 1);
  4557. return mpack_tree_parse_bytes(tree, node);
  4558. #if MPACK_EXTENSIONS
  4559. // ext8
  4560. case 0xc7:
  4561. if (!mpack_tree_reserve_bytes(tree, sizeof(uint8_t)))
  4562. return false;
  4563. node->len = mpack_load_u8(tree->data + tree->size + 1);
  4564. return mpack_tree_parse_ext(tree, node);
  4565. // ext16
  4566. case 0xc8:
  4567. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4568. return false;
  4569. node->len = mpack_load_u16(tree->data + tree->size + 1);
  4570. return mpack_tree_parse_ext(tree, node);
  4571. // ext32
  4572. case 0xc9:
  4573. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4574. return false;
  4575. node->len = mpack_load_u32(tree->data + tree->size + 1);
  4576. return mpack_tree_parse_ext(tree, node);
  4577. #endif
  4578. // float
  4579. case 0xca:
  4580. #if MPACK_FLOAT
  4581. if (!mpack_tree_reserve_bytes(tree, sizeof(float)))
  4582. return false;
  4583. node->value.f = mpack_load_float(tree->data + tree->size + 1);
  4584. #else
  4585. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4586. return false;
  4587. node->value.f = mpack_load_u32(tree->data + tree->size + 1);
  4588. #endif
  4589. node->type = mpack_type_float;
  4590. return true;
  4591. // double
  4592. case 0xcb:
  4593. #if MPACK_DOUBLE
  4594. if (!mpack_tree_reserve_bytes(tree, sizeof(double)))
  4595. return false;
  4596. node->value.d = mpack_load_double(tree->data + tree->size + 1);
  4597. #else
  4598. if (!mpack_tree_reserve_bytes(tree, sizeof(uint64_t)))
  4599. return false;
  4600. node->value.d = mpack_load_u64(tree->data + tree->size + 1);
  4601. #endif
  4602. node->type = mpack_type_double;
  4603. return true;
  4604. // uint8
  4605. case 0xcc:
  4606. node->type = mpack_type_uint;
  4607. if (!mpack_tree_reserve_bytes(tree, sizeof(uint8_t)))
  4608. return false;
  4609. node->value.u = mpack_load_u8(tree->data + tree->size + 1);
  4610. return true;
  4611. // uint16
  4612. case 0xcd:
  4613. node->type = mpack_type_uint;
  4614. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4615. return false;
  4616. node->value.u = mpack_load_u16(tree->data + tree->size + 1);
  4617. return true;
  4618. // uint32
  4619. case 0xce:
  4620. node->type = mpack_type_uint;
  4621. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4622. return false;
  4623. node->value.u = mpack_load_u32(tree->data + tree->size + 1);
  4624. return true;
  4625. // uint64
  4626. case 0xcf:
  4627. node->type = mpack_type_uint;
  4628. if (!mpack_tree_reserve_bytes(tree, sizeof(uint64_t)))
  4629. return false;
  4630. node->value.u = mpack_load_u64(tree->data + tree->size + 1);
  4631. return true;
  4632. // int8
  4633. case 0xd0:
  4634. node->type = mpack_type_int;
  4635. if (!mpack_tree_reserve_bytes(tree, sizeof(int8_t)))
  4636. return false;
  4637. node->value.i = mpack_load_i8(tree->data + tree->size + 1);
  4638. return true;
  4639. // int16
  4640. case 0xd1:
  4641. node->type = mpack_type_int;
  4642. if (!mpack_tree_reserve_bytes(tree, sizeof(int16_t)))
  4643. return false;
  4644. node->value.i = mpack_load_i16(tree->data + tree->size + 1);
  4645. return true;
  4646. // int32
  4647. case 0xd2:
  4648. node->type = mpack_type_int;
  4649. if (!mpack_tree_reserve_bytes(tree, sizeof(int32_t)))
  4650. return false;
  4651. node->value.i = mpack_load_i32(tree->data + tree->size + 1);
  4652. return true;
  4653. // int64
  4654. case 0xd3:
  4655. node->type = mpack_type_int;
  4656. if (!mpack_tree_reserve_bytes(tree, sizeof(int64_t)))
  4657. return false;
  4658. node->value.i = mpack_load_i64(tree->data + tree->size + 1);
  4659. return true;
  4660. #if MPACK_EXTENSIONS
  4661. // fixext1
  4662. case 0xd4:
  4663. node->len = 1;
  4664. return mpack_tree_parse_ext(tree, node);
  4665. // fixext2
  4666. case 0xd5:
  4667. node->len = 2;
  4668. return mpack_tree_parse_ext(tree, node);
  4669. // fixext4
  4670. case 0xd6:
  4671. node->len = 4;
  4672. return mpack_tree_parse_ext(tree, node);
  4673. // fixext8
  4674. case 0xd7:
  4675. node->len = 8;
  4676. return mpack_tree_parse_ext(tree, node);
  4677. // fixext16
  4678. case 0xd8:
  4679. node->len = 16;
  4680. return mpack_tree_parse_ext(tree, node);
  4681. #endif
  4682. // str8
  4683. case 0xd9:
  4684. if (!mpack_tree_reserve_bytes(tree, sizeof(uint8_t)))
  4685. return false;
  4686. node->len = mpack_load_u8(tree->data + tree->size + 1);
  4687. node->type = mpack_type_str;
  4688. return mpack_tree_parse_bytes(tree, node);
  4689. // str16
  4690. case 0xda:
  4691. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4692. return false;
  4693. node->len = mpack_load_u16(tree->data + tree->size + 1);
  4694. node->type = mpack_type_str;
  4695. return mpack_tree_parse_bytes(tree, node);
  4696. // str32
  4697. case 0xdb:
  4698. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4699. return false;
  4700. node->len = mpack_load_u32(tree->data + tree->size + 1);
  4701. node->type = mpack_type_str;
  4702. return mpack_tree_parse_bytes(tree, node);
  4703. // array16
  4704. case 0xdc:
  4705. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4706. return false;
  4707. node->len = mpack_load_u16(tree->data + tree->size + 1);
  4708. node->type = mpack_type_array;
  4709. return mpack_tree_parse_children(tree, node);
  4710. // array32
  4711. case 0xdd:
  4712. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4713. return false;
  4714. node->len = mpack_load_u32(tree->data + tree->size + 1);
  4715. node->type = mpack_type_array;
  4716. return mpack_tree_parse_children(tree, node);
  4717. // map16
  4718. case 0xde:
  4719. if (!mpack_tree_reserve_bytes(tree, sizeof(uint16_t)))
  4720. return false;
  4721. node->len = mpack_load_u16(tree->data + tree->size + 1);
  4722. node->type = mpack_type_map;
  4723. return mpack_tree_parse_children(tree, node);
  4724. // map32
  4725. case 0xdf:
  4726. if (!mpack_tree_reserve_bytes(tree, sizeof(uint32_t)))
  4727. return false;
  4728. node->len = mpack_load_u32(tree->data + tree->size + 1);
  4729. node->type = mpack_type_map;
  4730. return mpack_tree_parse_children(tree, node);
  4731. // reserved
  4732. case 0xc1:
  4733. mpack_tree_flag_error(tree, mpack_error_invalid);
  4734. return false;
  4735. #if !MPACK_EXTENSIONS
  4736. // ext
  4737. case 0xc7: // fallthrough
  4738. case 0xc8: // fallthrough
  4739. case 0xc9: // fallthrough
  4740. // fixext
  4741. case 0xd4: // fallthrough
  4742. case 0xd5: // fallthrough
  4743. case 0xd6: // fallthrough
  4744. case 0xd7: // fallthrough
  4745. case 0xd8:
  4746. mpack_tree_flag_error(tree, mpack_error_unsupported);
  4747. return false;
  4748. #endif
  4749. #if MPACK_OPTIMIZE_FOR_SIZE
  4750. // any other bytes should have been handled by the infix switch
  4751. default:
  4752. break;
  4753. #endif
  4754. }
  4755. mpack_assert(0, "unreachable");
  4756. return false;
  4757. }
  4758. static bool mpack_tree_parse_node(mpack_tree_t* tree, mpack_node_data_t* node) {
  4759. mpack_log("parsing a node at position %i in level %i\n",
  4760. (int)tree->size, (int)tree->parser.level);
  4761. if (!mpack_tree_parse_node_contents(tree, node)) {
  4762. mpack_log("node parsing returned false\n");
  4763. return false;
  4764. }
  4765. tree->parser.possible_nodes_left -= tree->parser.current_node_reserved;
  4766. // The reserve for the current node does not include the initial byte
  4767. // previously reserved as part of its parent.
  4768. size_t node_size = tree->parser.current_node_reserved + 1;
  4769. // If the parsed type is a map or array, the reserve includes one byte for
  4770. // each child. We want to subtract these out of possible_nodes_left, but
  4771. // not out of the current size of the tree.
  4772. if (node->type == mpack_type_array)
  4773. node_size -= node->len;
  4774. else if (node->type == mpack_type_map)
  4775. node_size -= node->len * 2;
  4776. tree->size += node_size;
  4777. mpack_log("parsed a node of type %s of %i bytes and "
  4778. "%i additional bytes reserved for children.\n",
  4779. mpack_type_to_string(node->type), (int)node_size,
  4780. (int)tree->parser.current_node_reserved + 1 - (int)node_size);
  4781. return true;
  4782. }
  4783. /*
  4784. * We read nodes in a loop instead of recursively for maximum performance. The
  4785. * stack holds the amount of children left to read in each level of the tree.
  4786. * Parsing can pause and resume when more data becomes available.
  4787. */
  4788. static bool mpack_tree_continue_parsing(mpack_tree_t* tree) {
  4789. if (mpack_tree_error(tree) != mpack_ok)
  4790. return false;
  4791. mpack_tree_parser_t* parser = &tree->parser;
  4792. mpack_assert(parser->state == mpack_tree_parse_state_in_progress);
  4793. mpack_log("parsing tree elements, %i bytes in buffer\n", (int)tree->data_length);
  4794. // we loop parsing nodes until the parse stack is empty. we break
  4795. // by returning out of the function.
  4796. while (true) {
  4797. mpack_node_data_t* node = parser->stack[parser->level].child;
  4798. size_t level = parser->level;
  4799. if (!mpack_tree_parse_node(tree, node))
  4800. return false;
  4801. --parser->stack[level].left;
  4802. ++parser->stack[level].child;
  4803. mpack_assert(mpack_tree_error(tree) == mpack_ok,
  4804. "mpack_tree_parse_node() should have returned false due to error!");
  4805. // pop empty stack levels, exiting the outer loop when the stack is empty.
  4806. // (we could tail-optimize containers by pre-emptively popping empty
  4807. // stack levels before reading the new element, this way we wouldn't
  4808. // have to loop. but we eventually want to use the parse stack to give
  4809. // better error messages that contain the location of the error, so
  4810. // it needs to be complete.)
  4811. while (parser->stack[parser->level].left == 0) {
  4812. if (parser->level == 0)
  4813. return true;
  4814. --parser->level;
  4815. }
  4816. }
  4817. }
  4818. static void mpack_tree_cleanup(mpack_tree_t* tree) {
  4819. MPACK_UNUSED(tree);
  4820. #ifdef MPACK_MALLOC
  4821. if (tree->parser.stack_owned) {
  4822. MPACK_FREE(tree->parser.stack);
  4823. tree->parser.stack = NULL;
  4824. tree->parser.stack_owned = false;
  4825. }
  4826. mpack_tree_page_t* page = tree->next;
  4827. while (page != NULL) {
  4828. mpack_tree_page_t* next = page->next;
  4829. mpack_log("freeing page %p\n", (void*)page);
  4830. MPACK_FREE(page);
  4831. page = next;
  4832. }
  4833. tree->next = NULL;
  4834. #endif
  4835. }
  4836. static bool mpack_tree_parse_start(mpack_tree_t* tree) {
  4837. if (mpack_tree_error(tree) != mpack_ok)
  4838. return false;
  4839. mpack_tree_parser_t* parser = &tree->parser;
  4840. mpack_assert(parser->state != mpack_tree_parse_state_in_progress,
  4841. "previous parsing was not finished!");
  4842. if (parser->state == mpack_tree_parse_state_parsed)
  4843. mpack_tree_cleanup(tree);
  4844. mpack_log("starting parse\n");
  4845. tree->parser.state = mpack_tree_parse_state_in_progress;
  4846. tree->parser.current_node_reserved = 0;
  4847. // check if we previously parsed a tree
  4848. if (tree->size > 0) {
  4849. #ifdef MPACK_MALLOC
  4850. // if we're buffered, move the remaining data back to the
  4851. // start of the buffer
  4852. // TODO: This is not ideal performance-wise. We should only move data
  4853. // when we need to call the fill function.
  4854. // TODO: We could consider shrinking the buffer here, especially if we
  4855. // determine that the fill function is providing less than a quarter of
  4856. // the buffer size or if messages take up less than a quarter of the
  4857. // buffer size. Maybe this should be configurable.
  4858. if (tree->buffer != NULL) {
  4859. mpack_memmove(tree->buffer, tree->buffer + tree->size, tree->data_length - tree->size);
  4860. }
  4861. else
  4862. #endif
  4863. // otherwise advance past the parsed data
  4864. {
  4865. tree->data += tree->size;
  4866. }
  4867. tree->data_length -= tree->size;
  4868. tree->size = 0;
  4869. tree->node_count = 0;
  4870. }
  4871. // make sure we have at least one byte available before allocating anything
  4872. parser->possible_nodes_left = tree->data_length;
  4873. if (!mpack_tree_reserve_bytes(tree, sizeof(uint8_t))) {
  4874. tree->parser.state = mpack_tree_parse_state_not_started;
  4875. return false;
  4876. }
  4877. mpack_log("parsing tree at %p starting with byte %x\n", tree->data, (uint8_t)tree->data[0]);
  4878. parser->possible_nodes_left -= 1;
  4879. tree->node_count = 1;
  4880. #ifdef MPACK_MALLOC
  4881. parser->stack = parser->stack_local;
  4882. parser->stack_owned = false;
  4883. parser->stack_capacity = sizeof(parser->stack_local) / sizeof(*parser->stack_local);
  4884. if (tree->pool == NULL) {
  4885. // allocate first page
  4886. mpack_tree_page_t* page = (mpack_tree_page_t*)MPACK_MALLOC(MPACK_PAGE_ALLOC_SIZE);
  4887. mpack_log("allocated initial page %p of size %i count %i\n",
  4888. (void*)page, (int)MPACK_PAGE_ALLOC_SIZE, (int)MPACK_NODES_PER_PAGE);
  4889. if (page == NULL) {
  4890. tree->error = mpack_error_memory;
  4891. return false;
  4892. }
  4893. page->next = NULL;
  4894. tree->next = page;
  4895. parser->nodes = page->nodes;
  4896. parser->nodes_left = MPACK_NODES_PER_PAGE;
  4897. }
  4898. else
  4899. #endif
  4900. {
  4901. // otherwise use the provided pool
  4902. mpack_assert(tree->pool != NULL, "no pool provided?");
  4903. parser->nodes = tree->pool;
  4904. parser->nodes_left = tree->pool_count;
  4905. }
  4906. tree->root = parser->nodes;
  4907. ++parser->nodes;
  4908. --parser->nodes_left;
  4909. parser->level = 0;
  4910. parser->stack[0].child = tree->root;
  4911. parser->stack[0].left = 1;
  4912. return true;
  4913. }
  4914. void mpack_tree_parse(mpack_tree_t* tree) {
  4915. if (mpack_tree_error(tree) != mpack_ok)
  4916. return;
  4917. if (tree->parser.state != mpack_tree_parse_state_in_progress) {
  4918. if (!mpack_tree_parse_start(tree)) {
  4919. mpack_tree_flag_error(tree, (tree->read_fn == NULL) ?
  4920. mpack_error_invalid : mpack_error_io);
  4921. return;
  4922. }
  4923. }
  4924. if (!mpack_tree_continue_parsing(tree)) {
  4925. if (mpack_tree_error(tree) != mpack_ok)
  4926. return;
  4927. // We're parsing synchronously on a blocking fill function. If we
  4928. // didn't completely finish parsing the tree, it's an error.
  4929. mpack_log("tree parsing incomplete. flagging error.\n");
  4930. mpack_tree_flag_error(tree, (tree->read_fn == NULL) ?
  4931. mpack_error_invalid : mpack_error_io);
  4932. return;
  4933. }
  4934. mpack_assert(mpack_tree_error(tree) == mpack_ok);
  4935. mpack_assert(tree->parser.level == 0);
  4936. tree->parser.state = mpack_tree_parse_state_parsed;
  4937. mpack_log("parsed tree of %i bytes, %i bytes left\n", (int)tree->size, (int)tree->parser.possible_nodes_left);
  4938. mpack_log("%i nodes in final page\n", (int)tree->parser.nodes_left);
  4939. }
  4940. bool mpack_tree_try_parse(mpack_tree_t* tree) {
  4941. if (mpack_tree_error(tree) != mpack_ok)
  4942. return false;
  4943. if (tree->parser.state != mpack_tree_parse_state_in_progress)
  4944. if (!mpack_tree_parse_start(tree))
  4945. return false;
  4946. if (!mpack_tree_continue_parsing(tree))
  4947. return false;
  4948. mpack_assert(mpack_tree_error(tree) == mpack_ok);
  4949. mpack_assert(tree->parser.level == 0);
  4950. tree->parser.state = mpack_tree_parse_state_parsed;
  4951. return true;
  4952. }
  4953. /*
  4954. * Tree functions
  4955. */
  4956. mpack_node_t mpack_tree_root(mpack_tree_t* tree) {
  4957. if (mpack_tree_error(tree) != mpack_ok)
  4958. return mpack_tree_nil_node(tree);
  4959. // We check that a tree was parsed successfully and assert if not. You must
  4960. // call mpack_tree_parse() (or mpack_tree_try_parse() with a success
  4961. // result) in order to access the root node.
  4962. if (tree->parser.state != mpack_tree_parse_state_parsed) {
  4963. mpack_break("Tree has not been parsed! "
  4964. "Did you call mpack_tree_parse() or mpack_tree_try_parse()?");
  4965. mpack_tree_flag_error(tree, mpack_error_bug);
  4966. return mpack_tree_nil_node(tree);
  4967. }
  4968. return mpack_node(tree, tree->root);
  4969. }
  4970. static void mpack_tree_init_clear(mpack_tree_t* tree) {
  4971. mpack_memset(tree, 0, sizeof(*tree));
  4972. tree->nil_node.type = mpack_type_nil;
  4973. tree->missing_node.type = mpack_type_missing;
  4974. tree->max_size = SIZE_MAX;
  4975. tree->max_nodes = SIZE_MAX;
  4976. }
  4977. #ifdef MPACK_MALLOC
  4978. void mpack_tree_init_data(mpack_tree_t* tree, const char* data, size_t length) {
  4979. mpack_tree_init_clear(tree);
  4980. MPACK_STATIC_ASSERT(MPACK_NODE_PAGE_SIZE >= sizeof(mpack_tree_page_t),
  4981. "MPACK_NODE_PAGE_SIZE is too small");
  4982. MPACK_STATIC_ASSERT(MPACK_PAGE_ALLOC_SIZE <= MPACK_NODE_PAGE_SIZE,
  4983. "incorrect page rounding?");
  4984. tree->data = data;
  4985. tree->data_length = length;
  4986. tree->pool = NULL;
  4987. tree->pool_count = 0;
  4988. tree->next = NULL;
  4989. mpack_log("===========================\n");
  4990. mpack_log("initializing tree with data of size %i\n", (int)length);
  4991. }
  4992. #endif
  4993. void mpack_tree_init_pool(mpack_tree_t* tree, const char* data, size_t length,
  4994. mpack_node_data_t* node_pool, size_t node_pool_count)
  4995. {
  4996. mpack_tree_init_clear(tree);
  4997. #ifdef MPACK_MALLOC
  4998. tree->next = NULL;
  4999. #endif
  5000. if (node_pool_count == 0) {
  5001. mpack_break("initial page has no nodes!");
  5002. mpack_tree_flag_error(tree, mpack_error_bug);
  5003. return;
  5004. }
  5005. tree->data = data;
  5006. tree->data_length = length;
  5007. tree->pool = node_pool;
  5008. tree->pool_count = node_pool_count;
  5009. mpack_log("===========================\n");
  5010. mpack_log("initializing tree with data of size %i and pool of count %i\n",
  5011. (int)length, (int)node_pool_count);
  5012. }
  5013. void mpack_tree_init_error(mpack_tree_t* tree, mpack_error_t error) {
  5014. mpack_tree_init_clear(tree);
  5015. tree->error = error;
  5016. mpack_log("===========================\n");
  5017. mpack_log("initializing tree error state %i\n", (int)error);
  5018. }
  5019. #ifdef MPACK_MALLOC
  5020. void mpack_tree_init_stream(mpack_tree_t* tree, mpack_tree_read_t read_fn, void* context,
  5021. size_t max_message_size, size_t max_message_nodes) {
  5022. mpack_tree_init_clear(tree);
  5023. tree->read_fn = read_fn;
  5024. tree->context = context;
  5025. mpack_tree_set_limits(tree, max_message_size, max_message_nodes);
  5026. tree->max_size = max_message_size;
  5027. tree->max_nodes = max_message_nodes;
  5028. mpack_log("===========================\n");
  5029. mpack_log("initializing tree with stream, max size %i max nodes %i\n",
  5030. (int)max_message_size, (int)max_message_nodes);
  5031. }
  5032. #endif
  5033. void mpack_tree_set_limits(mpack_tree_t* tree, size_t max_message_size, size_t max_message_nodes) {
  5034. mpack_assert(max_message_size > 0);
  5035. mpack_assert(max_message_nodes > 0);
  5036. tree->max_size = max_message_size;
  5037. tree->max_nodes = max_message_nodes;
  5038. }
  5039. #if MPACK_STDIO
  5040. typedef struct mpack_file_tree_t {
  5041. char* data;
  5042. size_t size;
  5043. char buffer[MPACK_BUFFER_SIZE];
  5044. } mpack_file_tree_t;
  5045. static void mpack_file_tree_teardown(mpack_tree_t* tree) {
  5046. mpack_file_tree_t* file_tree = (mpack_file_tree_t*)tree->context;
  5047. MPACK_FREE(file_tree->data);
  5048. MPACK_FREE(file_tree);
  5049. }
  5050. static bool mpack_file_tree_read(mpack_tree_t* tree, mpack_file_tree_t* file_tree, FILE* file, size_t max_bytes) {
  5051. // get the file size
  5052. errno = 0;
  5053. int error = 0;
  5054. fseek(file, 0, SEEK_END);
  5055. error |= errno;
  5056. long size = ftell(file);
  5057. error |= errno;
  5058. fseek(file, 0, SEEK_SET);
  5059. error |= errno;
  5060. // check for errors
  5061. if (error != 0 || size < 0) {
  5062. mpack_tree_init_error(tree, mpack_error_io);
  5063. return false;
  5064. }
  5065. if (size == 0) {
  5066. mpack_tree_init_error(tree, mpack_error_invalid);
  5067. return false;
  5068. }
  5069. // make sure the size is less than max_bytes
  5070. // (this mess exists to safely convert between long and size_t regardless of their widths)
  5071. if (max_bytes != 0 && (((uint64_t)LONG_MAX > (uint64_t)SIZE_MAX && size > (long)SIZE_MAX) || (size_t)size > max_bytes)) {
  5072. mpack_tree_init_error(tree, mpack_error_too_big);
  5073. return false;
  5074. }
  5075. // allocate data
  5076. file_tree->data = (char*)MPACK_MALLOC((size_t)size);
  5077. if (file_tree->data == NULL) {
  5078. mpack_tree_init_error(tree, mpack_error_memory);
  5079. return false;
  5080. }
  5081. // read the file
  5082. long total = 0;
  5083. while (total < size) {
  5084. size_t read = fread(file_tree->data + total, 1, (size_t)(size - total), file);
  5085. if (read <= 0) {
  5086. mpack_tree_init_error(tree, mpack_error_io);
  5087. MPACK_FREE(file_tree->data);
  5088. return false;
  5089. }
  5090. total += (long)read;
  5091. }
  5092. file_tree->size = (size_t)size;
  5093. return true;
  5094. }
  5095. static bool mpack_tree_file_check_max_bytes(mpack_tree_t* tree, size_t max_bytes) {
  5096. // the C STDIO family of file functions use long (e.g. ftell)
  5097. if (max_bytes > LONG_MAX) {
  5098. mpack_break("max_bytes of %" PRIu64 " is invalid, maximum is LONG_MAX", (uint64_t)max_bytes);
  5099. mpack_tree_init_error(tree, mpack_error_bug);
  5100. return false;
  5101. }
  5102. return true;
  5103. }
  5104. static void mpack_tree_init_stdfile_noclose(mpack_tree_t* tree, FILE* stdfile, size_t max_bytes) {
  5105. // allocate file tree
  5106. mpack_file_tree_t* file_tree = (mpack_file_tree_t*) MPACK_MALLOC(sizeof(mpack_file_tree_t));
  5107. if (file_tree == NULL) {
  5108. mpack_tree_init_error(tree, mpack_error_memory);
  5109. return;
  5110. }
  5111. // read all data
  5112. if (!mpack_file_tree_read(tree, file_tree, stdfile, max_bytes)) {
  5113. MPACK_FREE(file_tree);
  5114. return;
  5115. }
  5116. mpack_tree_init_data(tree, file_tree->data, file_tree->size);
  5117. mpack_tree_set_context(tree, file_tree);
  5118. mpack_tree_set_teardown(tree, mpack_file_tree_teardown);
  5119. }
  5120. void mpack_tree_init_stdfile(mpack_tree_t* tree, FILE* stdfile, size_t max_bytes, bool close_when_done) {
  5121. if (!mpack_tree_file_check_max_bytes(tree, max_bytes))
  5122. return;
  5123. mpack_tree_init_stdfile_noclose(tree, stdfile, max_bytes);
  5124. if (close_when_done)
  5125. fclose(stdfile);
  5126. }
  5127. void mpack_tree_init_filename(mpack_tree_t* tree, const char* filename, size_t max_bytes) {
  5128. if (!mpack_tree_file_check_max_bytes(tree, max_bytes))
  5129. return;
  5130. // open the file
  5131. FILE* file = fopen(filename, "rb");
  5132. if (!file) {
  5133. mpack_tree_init_error(tree, mpack_error_io);
  5134. return;
  5135. }
  5136. mpack_tree_init_stdfile(tree, file, max_bytes, true);
  5137. }
  5138. #endif
  5139. mpack_error_t mpack_tree_destroy(mpack_tree_t* tree) {
  5140. mpack_tree_cleanup(tree);
  5141. #ifdef MPACK_MALLOC
  5142. if (tree->buffer)
  5143. MPACK_FREE(tree->buffer);
  5144. #endif
  5145. if (tree->teardown)
  5146. tree->teardown(tree);
  5147. tree->teardown = NULL;
  5148. return tree->error;
  5149. }
  5150. void mpack_tree_flag_error(mpack_tree_t* tree, mpack_error_t error) {
  5151. if (tree->error == mpack_ok) {
  5152. mpack_log("tree %p setting error %i: %s\n", (void*)tree, (int)error, mpack_error_to_string(error));
  5153. tree->error = error;
  5154. if (tree->error_fn)
  5155. tree->error_fn(tree, error);
  5156. }
  5157. }
  5158. /*
  5159. * Node misc functions
  5160. */
  5161. void mpack_node_flag_error(mpack_node_t node, mpack_error_t error) {
  5162. mpack_tree_flag_error(node.tree, error);
  5163. }
  5164. mpack_tag_t mpack_node_tag(mpack_node_t node) {
  5165. if (mpack_node_error(node) != mpack_ok)
  5166. return mpack_tag_nil();
  5167. mpack_tag_t tag = MPACK_TAG_ZERO;
  5168. tag.type = node.data->type;
  5169. switch (node.data->type) {
  5170. case mpack_type_missing:
  5171. // If a node is missing, I don't know if it makes sense to ask for
  5172. // a tag for it. We'll return a missing tag to match the missing
  5173. // node I guess, but attempting to use the tag for anything (like
  5174. // writing it for example) will flag mpack_error_bug.
  5175. break;
  5176. case mpack_type_nil: break;
  5177. case mpack_type_bool: tag.v.b = node.data->value.b; break;
  5178. case mpack_type_float: tag.v.f = node.data->value.f; break;
  5179. case mpack_type_double: tag.v.d = node.data->value.d; break;
  5180. case mpack_type_int: tag.v.i = node.data->value.i; break;
  5181. case mpack_type_uint: tag.v.u = node.data->value.u; break;
  5182. case mpack_type_str: tag.v.l = node.data->len; break;
  5183. case mpack_type_bin: tag.v.l = node.data->len; break;
  5184. #if MPACK_EXTENSIONS
  5185. case mpack_type_ext:
  5186. tag.v.l = node.data->len;
  5187. tag.exttype = mpack_node_exttype_unchecked(node);
  5188. break;
  5189. #endif
  5190. case mpack_type_array: tag.v.n = node.data->len; break;
  5191. case mpack_type_map: tag.v.n = node.data->len; break;
  5192. default:
  5193. mpack_assert(0, "unrecognized type %i", (int)node.data->type);
  5194. break;
  5195. }
  5196. return tag;
  5197. }
  5198. #if MPACK_DEBUG && MPACK_STDIO
  5199. static void mpack_node_print_element(mpack_node_t node, mpack_print_t* print, size_t depth) {
  5200. mpack_node_data_t* data = node.data;
  5201. size_t i,j;
  5202. switch (data->type) {
  5203. case mpack_type_str:
  5204. {
  5205. mpack_print_append_cstr(print, "\"");
  5206. const char* bytes = mpack_node_data_unchecked(node);
  5207. for (i = 0; i < data->len; ++i) {
  5208. char c = bytes[i];
  5209. switch (c) {
  5210. case '\n': mpack_print_append_cstr(print, "\\n"); break;
  5211. case '\\': mpack_print_append_cstr(print, "\\\\"); break;
  5212. case '"': mpack_print_append_cstr(print, "\\\""); break;
  5213. default: mpack_print_append(print, &c, 1); break;
  5214. }
  5215. }
  5216. mpack_print_append_cstr(print, "\"");
  5217. }
  5218. break;
  5219. case mpack_type_array:
  5220. mpack_print_append_cstr(print, "[\n");
  5221. for (i = 0; i < data->len; ++i) {
  5222. for (j = 0; j < depth + 1; ++j)
  5223. mpack_print_append_cstr(print, " ");
  5224. mpack_node_print_element(mpack_node_array_at(node, i), print, depth + 1);
  5225. if (i != data->len - 1)
  5226. mpack_print_append_cstr(print, ",");
  5227. mpack_print_append_cstr(print, "\n");
  5228. }
  5229. for (i = 0; i < depth; ++i)
  5230. mpack_print_append_cstr(print, " ");
  5231. mpack_print_append_cstr(print, "]");
  5232. break;
  5233. case mpack_type_map:
  5234. mpack_print_append_cstr(print, "{\n");
  5235. for (i = 0; i < data->len; ++i) {
  5236. for (j = 0; j < depth + 1; ++j)
  5237. mpack_print_append_cstr(print, " ");
  5238. mpack_node_print_element(mpack_node_map_key_at(node, i), print, depth + 1);
  5239. mpack_print_append_cstr(print, ": ");
  5240. mpack_node_print_element(mpack_node_map_value_at(node, i), print, depth + 1);
  5241. if (i != data->len - 1)
  5242. mpack_print_append_cstr(print, ",");
  5243. mpack_print_append_cstr(print, "\n");
  5244. }
  5245. for (i = 0; i < depth; ++i)
  5246. mpack_print_append_cstr(print, " ");
  5247. mpack_print_append_cstr(print, "}");
  5248. break;
  5249. default:
  5250. {
  5251. const char* prefix = NULL;
  5252. size_t prefix_length = 0;
  5253. if (mpack_node_type(node) == mpack_type_bin
  5254. #if MPACK_EXTENSIONS
  5255. || mpack_node_type(node) == mpack_type_ext
  5256. #endif
  5257. ) {
  5258. prefix = mpack_node_data(node);
  5259. prefix_length = mpack_node_data_len(node);
  5260. }
  5261. char buf[256];
  5262. mpack_tag_t tag = mpack_node_tag(node);
  5263. mpack_tag_debug_pseudo_json(tag, buf, sizeof(buf), prefix, prefix_length);
  5264. mpack_print_append_cstr(print, buf);
  5265. }
  5266. break;
  5267. }
  5268. }
  5269. void mpack_node_print_to_buffer(mpack_node_t node, char* buffer, size_t buffer_size) {
  5270. if (buffer_size == 0) {
  5271. mpack_assert(false, "buffer size is zero!");
  5272. return;
  5273. }
  5274. mpack_print_t print;
  5275. mpack_memset(&print, 0, sizeof(print));
  5276. print.buffer = buffer;
  5277. print.size = buffer_size;
  5278. mpack_node_print_element(node, &print, 0);
  5279. mpack_print_append(&print, "", 1); // null-terminator
  5280. mpack_print_flush(&print);
  5281. // we always make sure there's a null-terminator at the end of the buffer
  5282. // in case we ran out of space.
  5283. print.buffer[print.size - 1] = '\0';
  5284. }
  5285. void mpack_node_print_to_callback(mpack_node_t node, mpack_print_callback_t callback, void* context) {
  5286. char buffer[1024];
  5287. mpack_print_t print;
  5288. mpack_memset(&print, 0, sizeof(print));
  5289. print.buffer = buffer;
  5290. print.size = sizeof(buffer);
  5291. print.callback = callback;
  5292. print.context = context;
  5293. mpack_node_print_element(node, &print, 0);
  5294. mpack_print_flush(&print);
  5295. }
  5296. void mpack_node_print_to_file(mpack_node_t node, FILE* file) {
  5297. mpack_assert(file != NULL, "file is NULL");
  5298. char buffer[1024];
  5299. mpack_print_t print;
  5300. mpack_memset(&print, 0, sizeof(print));
  5301. print.buffer = buffer;
  5302. print.size = sizeof(buffer);
  5303. print.callback = &mpack_print_file_callback;
  5304. print.context = file;
  5305. size_t depth = 2;
  5306. size_t i;
  5307. for (i = 0; i < depth; ++i)
  5308. mpack_print_append_cstr(&print, " ");
  5309. mpack_node_print_element(node, &print, depth);
  5310. mpack_print_append_cstr(&print, "\n");
  5311. mpack_print_flush(&print);
  5312. }
  5313. #endif
  5314. /*
  5315. * Node Value Functions
  5316. */
  5317. #if MPACK_EXTENSIONS
  5318. mpack_timestamp_t mpack_node_timestamp(mpack_node_t node) {
  5319. mpack_timestamp_t timestamp = {0, 0};
  5320. // we'll let mpack_node_exttype() do most checks
  5321. if (mpack_node_exttype(node) != MPACK_EXTTYPE_TIMESTAMP) {
  5322. mpack_log("exttype %i\n", mpack_node_exttype(node));
  5323. mpack_node_flag_error(node, mpack_error_type);
  5324. return timestamp;
  5325. }
  5326. const char* p = mpack_node_data_unchecked(node);
  5327. switch (node.data->len) {
  5328. case 4:
  5329. timestamp.nanoseconds = 0;
  5330. timestamp.seconds = mpack_load_u32(p);
  5331. break;
  5332. case 8: {
  5333. uint64_t value = mpack_load_u64(p);
  5334. timestamp.nanoseconds = (uint32_t)(value >> 34);
  5335. timestamp.seconds = value & ((MPACK_UINT64_C(1) << 34) - 1);
  5336. break;
  5337. }
  5338. case 12:
  5339. timestamp.nanoseconds = mpack_load_u32(p);
  5340. timestamp.seconds = mpack_load_i64(p + 4);
  5341. break;
  5342. default:
  5343. mpack_tree_flag_error(node.tree, mpack_error_invalid);
  5344. return timestamp;
  5345. }
  5346. if (timestamp.nanoseconds > MPACK_TIMESTAMP_NANOSECONDS_MAX) {
  5347. mpack_tree_flag_error(node.tree, mpack_error_invalid);
  5348. mpack_timestamp_t zero = {0, 0};
  5349. return zero;
  5350. }
  5351. return timestamp;
  5352. }
  5353. int64_t mpack_node_timestamp_seconds(mpack_node_t node) {
  5354. return mpack_node_timestamp(node).seconds;
  5355. }
  5356. uint32_t mpack_node_timestamp_nanoseconds(mpack_node_t node) {
  5357. return mpack_node_timestamp(node).nanoseconds;
  5358. }
  5359. #endif
  5360. /*
  5361. * Node Data Functions
  5362. */
  5363. void mpack_node_check_utf8(mpack_node_t node) {
  5364. if (mpack_node_error(node) != mpack_ok)
  5365. return;
  5366. mpack_node_data_t* data = node.data;
  5367. if (data->type != mpack_type_str || !mpack_utf8_check(mpack_node_data_unchecked(node), data->len))
  5368. mpack_node_flag_error(node, mpack_error_type);
  5369. }
  5370. void mpack_node_check_utf8_cstr(mpack_node_t node) {
  5371. if (mpack_node_error(node) != mpack_ok)
  5372. return;
  5373. mpack_node_data_t* data = node.data;
  5374. if (data->type != mpack_type_str || !mpack_utf8_check_no_null(mpack_node_data_unchecked(node), data->len))
  5375. mpack_node_flag_error(node, mpack_error_type);
  5376. }
  5377. size_t mpack_node_copy_data(mpack_node_t node, char* buffer, size_t bufsize) {
  5378. if (mpack_node_error(node) != mpack_ok)
  5379. return 0;
  5380. mpack_assert(bufsize == 0 || buffer != NULL, "buffer is NULL for maximum of %i bytes", (int)bufsize);
  5381. mpack_type_t type = node.data->type;
  5382. if (type != mpack_type_str && type != mpack_type_bin
  5383. #if MPACK_EXTENSIONS
  5384. && type != mpack_type_ext
  5385. #endif
  5386. ) {
  5387. mpack_node_flag_error(node, mpack_error_type);
  5388. return 0;
  5389. }
  5390. if (node.data->len > bufsize) {
  5391. mpack_node_flag_error(node, mpack_error_too_big);
  5392. return 0;
  5393. }
  5394. mpack_memcpy(buffer, mpack_node_data_unchecked(node), node.data->len);
  5395. return (size_t)node.data->len;
  5396. }
  5397. size_t mpack_node_copy_utf8(mpack_node_t node, char* buffer, size_t bufsize) {
  5398. if (mpack_node_error(node) != mpack_ok)
  5399. return 0;
  5400. mpack_assert(bufsize == 0 || buffer != NULL, "buffer is NULL for maximum of %i bytes", (int)bufsize);
  5401. mpack_type_t type = node.data->type;
  5402. if (type != mpack_type_str) {
  5403. mpack_node_flag_error(node, mpack_error_type);
  5404. return 0;
  5405. }
  5406. if (node.data->len > bufsize) {
  5407. mpack_node_flag_error(node, mpack_error_too_big);
  5408. return 0;
  5409. }
  5410. if (!mpack_utf8_check(mpack_node_data_unchecked(node), node.data->len)) {
  5411. mpack_node_flag_error(node, mpack_error_type);
  5412. return 0;
  5413. }
  5414. mpack_memcpy(buffer, mpack_node_data_unchecked(node), node.data->len);
  5415. return (size_t)node.data->len;
  5416. }
  5417. void mpack_node_copy_cstr(mpack_node_t node, char* buffer, size_t bufsize) {
  5418. // we can't break here because the error isn't recoverable; we
  5419. // have to add a null-terminator.
  5420. mpack_assert(buffer != NULL, "buffer is NULL");
  5421. mpack_assert(bufsize >= 1, "buffer size is zero; you must have room for at least a null-terminator");
  5422. if (mpack_node_error(node) != mpack_ok) {
  5423. buffer[0] = '\0';
  5424. return;
  5425. }
  5426. if (node.data->type != mpack_type_str) {
  5427. buffer[0] = '\0';
  5428. mpack_node_flag_error(node, mpack_error_type);
  5429. return;
  5430. }
  5431. if (node.data->len > bufsize - 1) {
  5432. buffer[0] = '\0';
  5433. mpack_node_flag_error(node, mpack_error_too_big);
  5434. return;
  5435. }
  5436. if (!mpack_str_check_no_null(mpack_node_data_unchecked(node), node.data->len)) {
  5437. buffer[0] = '\0';
  5438. mpack_node_flag_error(node, mpack_error_type);
  5439. return;
  5440. }
  5441. mpack_memcpy(buffer, mpack_node_data_unchecked(node), node.data->len);
  5442. buffer[node.data->len] = '\0';
  5443. }
  5444. void mpack_node_copy_utf8_cstr(mpack_node_t node, char* buffer, size_t bufsize) {
  5445. // we can't break here because the error isn't recoverable; we
  5446. // have to add a null-terminator.
  5447. mpack_assert(buffer != NULL, "buffer is NULL");
  5448. mpack_assert(bufsize >= 1, "buffer size is zero; you must have room for at least a null-terminator");
  5449. if (mpack_node_error(node) != mpack_ok) {
  5450. buffer[0] = '\0';
  5451. return;
  5452. }
  5453. if (node.data->type != mpack_type_str) {
  5454. buffer[0] = '\0';
  5455. mpack_node_flag_error(node, mpack_error_type);
  5456. return;
  5457. }
  5458. if (node.data->len > bufsize - 1) {
  5459. buffer[0] = '\0';
  5460. mpack_node_flag_error(node, mpack_error_too_big);
  5461. return;
  5462. }
  5463. if (!mpack_utf8_check_no_null(mpack_node_data_unchecked(node), node.data->len)) {
  5464. buffer[0] = '\0';
  5465. mpack_node_flag_error(node, mpack_error_type);
  5466. return;
  5467. }
  5468. mpack_memcpy(buffer, mpack_node_data_unchecked(node), node.data->len);
  5469. buffer[node.data->len] = '\0';
  5470. }
  5471. #ifdef MPACK_MALLOC
  5472. char* mpack_node_data_alloc(mpack_node_t node, size_t maxlen) {
  5473. if (mpack_node_error(node) != mpack_ok)
  5474. return NULL;
  5475. // make sure this is a valid data type
  5476. mpack_type_t type = node.data->type;
  5477. if (type != mpack_type_str && type != mpack_type_bin
  5478. #if MPACK_EXTENSIONS
  5479. && type != mpack_type_ext
  5480. #endif
  5481. ) {
  5482. mpack_node_flag_error(node, mpack_error_type);
  5483. return NULL;
  5484. }
  5485. if (node.data->len > maxlen) {
  5486. mpack_node_flag_error(node, mpack_error_too_big);
  5487. return NULL;
  5488. }
  5489. char* ret = (char*) MPACK_MALLOC((size_t)node.data->len);
  5490. if (ret == NULL) {
  5491. mpack_node_flag_error(node, mpack_error_memory);
  5492. return NULL;
  5493. }
  5494. mpack_memcpy(ret, mpack_node_data_unchecked(node), node.data->len);
  5495. return ret;
  5496. }
  5497. char* mpack_node_cstr_alloc(mpack_node_t node, size_t maxlen) {
  5498. if (mpack_node_error(node) != mpack_ok)
  5499. return NULL;
  5500. // make sure maxlen makes sense
  5501. if (maxlen < 1) {
  5502. mpack_break("maxlen is zero; you must have room for at least a null-terminator");
  5503. mpack_node_flag_error(node, mpack_error_bug);
  5504. return NULL;
  5505. }
  5506. if (node.data->type != mpack_type_str) {
  5507. mpack_node_flag_error(node, mpack_error_type);
  5508. return NULL;
  5509. }
  5510. if (node.data->len > maxlen - 1) {
  5511. mpack_node_flag_error(node, mpack_error_too_big);
  5512. return NULL;
  5513. }
  5514. if (!mpack_str_check_no_null(mpack_node_data_unchecked(node), node.data->len)) {
  5515. mpack_node_flag_error(node, mpack_error_type);
  5516. return NULL;
  5517. }
  5518. char* ret = (char*) MPACK_MALLOC((size_t)(node.data->len + 1));
  5519. if (ret == NULL) {
  5520. mpack_node_flag_error(node, mpack_error_memory);
  5521. return NULL;
  5522. }
  5523. mpack_memcpy(ret, mpack_node_data_unchecked(node), node.data->len);
  5524. ret[node.data->len] = '\0';
  5525. return ret;
  5526. }
  5527. char* mpack_node_utf8_cstr_alloc(mpack_node_t node, size_t maxlen) {
  5528. if (mpack_node_error(node) != mpack_ok)
  5529. return NULL;
  5530. // make sure maxlen makes sense
  5531. if (maxlen < 1) {
  5532. mpack_break("maxlen is zero; you must have room for at least a null-terminator");
  5533. mpack_node_flag_error(node, mpack_error_bug);
  5534. return NULL;
  5535. }
  5536. if (node.data->type != mpack_type_str) {
  5537. mpack_node_flag_error(node, mpack_error_type);
  5538. return NULL;
  5539. }
  5540. if (node.data->len > maxlen - 1) {
  5541. mpack_node_flag_error(node, mpack_error_too_big);
  5542. return NULL;
  5543. }
  5544. if (!mpack_utf8_check_no_null(mpack_node_data_unchecked(node), node.data->len)) {
  5545. mpack_node_flag_error(node, mpack_error_type);
  5546. return NULL;
  5547. }
  5548. char* ret = (char*) MPACK_MALLOC((size_t)(node.data->len + 1));
  5549. if (ret == NULL) {
  5550. mpack_node_flag_error(node, mpack_error_memory);
  5551. return NULL;
  5552. }
  5553. mpack_memcpy(ret, mpack_node_data_unchecked(node), node.data->len);
  5554. ret[node.data->len] = '\0';
  5555. return ret;
  5556. }
  5557. #endif
  5558. /*
  5559. * Compound Node Functions
  5560. */
  5561. static mpack_node_data_t* mpack_node_map_int_impl(mpack_node_t node, int64_t num) {
  5562. if (mpack_node_error(node) != mpack_ok)
  5563. return NULL;
  5564. if (node.data->type != mpack_type_map) {
  5565. mpack_node_flag_error(node, mpack_error_type);
  5566. return NULL;
  5567. }
  5568. mpack_node_data_t* found = NULL;
  5569. size_t i;
  5570. for (i = 0; i < node.data->len; ++i) {
  5571. mpack_node_data_t* key = mpack_node_child(node, i * 2);
  5572. if ((key->type == mpack_type_int && key->value.i == num) ||
  5573. (key->type == mpack_type_uint && num >= 0 && key->value.u == (uint64_t)num))
  5574. {
  5575. if (found) {
  5576. mpack_node_flag_error(node, mpack_error_data);
  5577. return NULL;
  5578. }
  5579. found = mpack_node_child(node, i * 2 + 1);
  5580. }
  5581. }
  5582. if (found)
  5583. return found;
  5584. return NULL;
  5585. }
  5586. static mpack_node_data_t* mpack_node_map_uint_impl(mpack_node_t node, uint64_t num) {
  5587. if (mpack_node_error(node) != mpack_ok)
  5588. return NULL;
  5589. if (node.data->type != mpack_type_map) {
  5590. mpack_node_flag_error(node, mpack_error_type);
  5591. return NULL;
  5592. }
  5593. mpack_node_data_t* found = NULL;
  5594. size_t i;
  5595. for (i = 0; i < node.data->len; ++i) {
  5596. mpack_node_data_t* key = mpack_node_child(node, i * 2);
  5597. if ((key->type == mpack_type_uint && key->value.u == num) ||
  5598. (key->type == mpack_type_int && key->value.i >= 0 && (uint64_t)key->value.i == num))
  5599. {
  5600. if (found) {
  5601. mpack_node_flag_error(node, mpack_error_data);
  5602. return NULL;
  5603. }
  5604. found = mpack_node_child(node, i * 2 + 1);
  5605. }
  5606. }
  5607. if (found)
  5608. return found;
  5609. return NULL;
  5610. }
  5611. static mpack_node_data_t* mpack_node_map_str_impl(mpack_node_t node, const char* str, size_t length) {
  5612. if (mpack_node_error(node) != mpack_ok)
  5613. return NULL;
  5614. mpack_assert(length == 0 || str != NULL, "str of length %i is NULL", (int)length);
  5615. if (node.data->type != mpack_type_map) {
  5616. mpack_node_flag_error(node, mpack_error_type);
  5617. return NULL;
  5618. }
  5619. mpack_tree_t* tree = node.tree;
  5620. mpack_node_data_t* found = NULL;
  5621. size_t i;
  5622. for (i = 0; i < node.data->len; ++i) {
  5623. mpack_node_data_t* key = mpack_node_child(node, i * 2);
  5624. if (key->type == mpack_type_str && key->len == length &&
  5625. mpack_memcmp(str, mpack_node_data_unchecked(mpack_node(tree, key)), length) == 0) {
  5626. if (found) {
  5627. mpack_node_flag_error(node, mpack_error_data);
  5628. return NULL;
  5629. }
  5630. found = mpack_node_child(node, i * 2 + 1);
  5631. }
  5632. }
  5633. if (found)
  5634. return found;
  5635. return NULL;
  5636. }
  5637. static mpack_node_t mpack_node_wrap_lookup(mpack_tree_t* tree, mpack_node_data_t* data) {
  5638. if (!data) {
  5639. if (tree->error == mpack_ok)
  5640. mpack_tree_flag_error(tree, mpack_error_data);
  5641. return mpack_tree_nil_node(tree);
  5642. }
  5643. return mpack_node(tree, data);
  5644. }
  5645. static mpack_node_t mpack_node_wrap_lookup_optional(mpack_tree_t* tree, mpack_node_data_t* data) {
  5646. if (!data) {
  5647. if (tree->error == mpack_ok)
  5648. return mpack_tree_missing_node(tree);
  5649. return mpack_tree_nil_node(tree);
  5650. }
  5651. return mpack_node(tree, data);
  5652. }
  5653. mpack_node_t mpack_node_map_int(mpack_node_t node, int64_t num) {
  5654. return mpack_node_wrap_lookup(node.tree, mpack_node_map_int_impl(node, num));
  5655. }
  5656. mpack_node_t mpack_node_map_int_optional(mpack_node_t node, int64_t num) {
  5657. return mpack_node_wrap_lookup_optional(node.tree, mpack_node_map_int_impl(node, num));
  5658. }
  5659. mpack_node_t mpack_node_map_uint(mpack_node_t node, uint64_t num) {
  5660. return mpack_node_wrap_lookup(node.tree, mpack_node_map_uint_impl(node, num));
  5661. }
  5662. mpack_node_t mpack_node_map_uint_optional(mpack_node_t node, uint64_t num) {
  5663. return mpack_node_wrap_lookup_optional(node.tree, mpack_node_map_uint_impl(node, num));
  5664. }
  5665. mpack_node_t mpack_node_map_str(mpack_node_t node, const char* str, size_t length) {
  5666. return mpack_node_wrap_lookup(node.tree, mpack_node_map_str_impl(node, str, length));
  5667. }
  5668. mpack_node_t mpack_node_map_str_optional(mpack_node_t node, const char* str, size_t length) {
  5669. return mpack_node_wrap_lookup_optional(node.tree, mpack_node_map_str_impl(node, str, length));
  5670. }
  5671. mpack_node_t mpack_node_map_cstr(mpack_node_t node, const char* cstr) {
  5672. mpack_assert(cstr != NULL, "cstr is NULL");
  5673. return mpack_node_map_str(node, cstr, mpack_strlen(cstr));
  5674. }
  5675. mpack_node_t mpack_node_map_cstr_optional(mpack_node_t node, const char* cstr) {
  5676. mpack_assert(cstr != NULL, "cstr is NULL");
  5677. return mpack_node_map_str_optional(node, cstr, mpack_strlen(cstr));
  5678. }
  5679. bool mpack_node_map_contains_int(mpack_node_t node, int64_t num) {
  5680. return mpack_node_map_int_impl(node, num) != NULL;
  5681. }
  5682. bool mpack_node_map_contains_uint(mpack_node_t node, uint64_t num) {
  5683. return mpack_node_map_uint_impl(node, num) != NULL;
  5684. }
  5685. bool mpack_node_map_contains_str(mpack_node_t node, const char* str, size_t length) {
  5686. return mpack_node_map_str_impl(node, str, length) != NULL;
  5687. }
  5688. bool mpack_node_map_contains_cstr(mpack_node_t node, const char* cstr) {
  5689. mpack_assert(cstr != NULL, "cstr is NULL");
  5690. return mpack_node_map_contains_str(node, cstr, mpack_strlen(cstr));
  5691. }
  5692. size_t mpack_node_enum_optional(mpack_node_t node, const char* strings[], size_t count) {
  5693. if (mpack_node_error(node) != mpack_ok)
  5694. return count;
  5695. // the value is only recognized if it is a string
  5696. if (mpack_node_type(node) != mpack_type_str)
  5697. return count;
  5698. // fetch the string
  5699. const char* key = mpack_node_str(node);
  5700. size_t keylen = mpack_node_strlen(node);
  5701. mpack_assert(mpack_node_error(node) == mpack_ok, "these should not fail");
  5702. // find what key it matches
  5703. size_t i;
  5704. for (i = 0; i < count; ++i) {
  5705. const char* other = strings[i];
  5706. size_t otherlen = mpack_strlen(other);
  5707. if (keylen == otherlen && mpack_memcmp(key, other, keylen) == 0)
  5708. return i;
  5709. }
  5710. // no matches
  5711. return count;
  5712. }
  5713. size_t mpack_node_enum(mpack_node_t node, const char* strings[], size_t count) {
  5714. size_t value = mpack_node_enum_optional(node, strings, count);
  5715. if (value == count)
  5716. mpack_node_flag_error(node, mpack_error_type);
  5717. return value;
  5718. }
  5719. mpack_type_t mpack_node_type(mpack_node_t node) {
  5720. if (mpack_node_error(node) != mpack_ok)
  5721. return mpack_type_nil;
  5722. return node.data->type;
  5723. }
  5724. bool mpack_node_is_nil(mpack_node_t node) {
  5725. if (mpack_node_error(node) != mpack_ok) {
  5726. // All nodes are treated as nil nodes when we are in error.
  5727. return true;
  5728. }
  5729. return node.data->type == mpack_type_nil;
  5730. }
  5731. bool mpack_node_is_missing(mpack_node_t node) {
  5732. if (mpack_node_error(node) != mpack_ok) {
  5733. // errors still return nil nodes, not missing nodes.
  5734. return false;
  5735. }
  5736. return node.data->type == mpack_type_missing;
  5737. }
  5738. void mpack_node_nil(mpack_node_t node) {
  5739. if (mpack_node_error(node) != mpack_ok)
  5740. return;
  5741. if (node.data->type != mpack_type_nil)
  5742. mpack_node_flag_error(node, mpack_error_type);
  5743. }
  5744. void mpack_node_missing(mpack_node_t node) {
  5745. if (mpack_node_error(node) != mpack_ok)
  5746. return;
  5747. if (node.data->type != mpack_type_missing)
  5748. mpack_node_flag_error(node, mpack_error_type);
  5749. }
  5750. bool mpack_node_bool(mpack_node_t node) {
  5751. if (mpack_node_error(node) != mpack_ok)
  5752. return false;
  5753. if (node.data->type == mpack_type_bool)
  5754. return node.data->value.b;
  5755. mpack_node_flag_error(node, mpack_error_type);
  5756. return false;
  5757. }
  5758. void mpack_node_true(mpack_node_t node) {
  5759. if (mpack_node_bool(node) != true)
  5760. mpack_node_flag_error(node, mpack_error_type);
  5761. }
  5762. void mpack_node_false(mpack_node_t node) {
  5763. if (mpack_node_bool(node) != false)
  5764. mpack_node_flag_error(node, mpack_error_type);
  5765. }
  5766. uint8_t mpack_node_u8(mpack_node_t node) {
  5767. if (mpack_node_error(node) != mpack_ok)
  5768. return 0;
  5769. if (node.data->type == mpack_type_uint) {
  5770. if (node.data->value.u <= MPACK_UINT8_MAX)
  5771. return (uint8_t)node.data->value.u;
  5772. } else if (node.data->type == mpack_type_int) {
  5773. if (node.data->value.i >= 0 && node.data->value.i <= MPACK_UINT8_MAX)
  5774. return (uint8_t)node.data->value.i;
  5775. }
  5776. mpack_node_flag_error(node, mpack_error_type);
  5777. return 0;
  5778. }
  5779. int8_t mpack_node_i8(mpack_node_t node) {
  5780. if (mpack_node_error(node) != mpack_ok)
  5781. return 0;
  5782. if (node.data->type == mpack_type_uint) {
  5783. if (node.data->value.u <= MPACK_INT8_MAX)
  5784. return (int8_t)node.data->value.u;
  5785. } else if (node.data->type == mpack_type_int) {
  5786. if (node.data->value.i >= MPACK_INT8_MIN && node.data->value.i <= MPACK_INT8_MAX)
  5787. return (int8_t)node.data->value.i;
  5788. }
  5789. mpack_node_flag_error(node, mpack_error_type);
  5790. return 0;
  5791. }
  5792. uint16_t mpack_node_u16(mpack_node_t node) {
  5793. if (mpack_node_error(node) != mpack_ok)
  5794. return 0;
  5795. if (node.data->type == mpack_type_uint) {
  5796. if (node.data->value.u <= MPACK_UINT16_MAX)
  5797. return (uint16_t)node.data->value.u;
  5798. } else if (node.data->type == mpack_type_int) {
  5799. if (node.data->value.i >= 0 && node.data->value.i <= MPACK_UINT16_MAX)
  5800. return (uint16_t)node.data->value.i;
  5801. }
  5802. mpack_node_flag_error(node, mpack_error_type);
  5803. return 0;
  5804. }
  5805. int16_t mpack_node_i16(mpack_node_t node) {
  5806. if (mpack_node_error(node) != mpack_ok)
  5807. return 0;
  5808. if (node.data->type == mpack_type_uint) {
  5809. if (node.data->value.u <= MPACK_INT16_MAX)
  5810. return (int16_t)node.data->value.u;
  5811. } else if (node.data->type == mpack_type_int) {
  5812. if (node.data->value.i >= MPACK_INT16_MIN && node.data->value.i <= MPACK_INT16_MAX)
  5813. return (int16_t)node.data->value.i;
  5814. }
  5815. mpack_node_flag_error(node, mpack_error_type);
  5816. return 0;
  5817. }
  5818. uint32_t mpack_node_u32(mpack_node_t node) {
  5819. if (mpack_node_error(node) != mpack_ok)
  5820. return 0;
  5821. if (node.data->type == mpack_type_uint) {
  5822. if (node.data->value.u <= MPACK_UINT32_MAX)
  5823. return (uint32_t)node.data->value.u;
  5824. } else if (node.data->type == mpack_type_int) {
  5825. if (node.data->value.i >= 0 && node.data->value.i <= MPACK_UINT32_MAX)
  5826. return (uint32_t)node.data->value.i;
  5827. }
  5828. mpack_node_flag_error(node, mpack_error_type);
  5829. return 0;
  5830. }
  5831. int32_t mpack_node_i32(mpack_node_t node) {
  5832. if (mpack_node_error(node) != mpack_ok)
  5833. return 0;
  5834. if (node.data->type == mpack_type_uint) {
  5835. if (node.data->value.u <= MPACK_INT32_MAX)
  5836. return (int32_t)node.data->value.u;
  5837. } else if (node.data->type == mpack_type_int) {
  5838. if (node.data->value.i >= MPACK_INT32_MIN && node.data->value.i <= MPACK_INT32_MAX)
  5839. return (int32_t)node.data->value.i;
  5840. }
  5841. mpack_node_flag_error(node, mpack_error_type);
  5842. return 0;
  5843. }
  5844. uint64_t mpack_node_u64(mpack_node_t node) {
  5845. if (mpack_node_error(node) != mpack_ok)
  5846. return 0;
  5847. if (node.data->type == mpack_type_uint) {
  5848. return node.data->value.u;
  5849. } else if (node.data->type == mpack_type_int) {
  5850. if (node.data->value.i >= 0)
  5851. return (uint64_t)node.data->value.i;
  5852. }
  5853. mpack_node_flag_error(node, mpack_error_type);
  5854. return 0;
  5855. }
  5856. int64_t mpack_node_i64(mpack_node_t node) {
  5857. if (mpack_node_error(node) != mpack_ok)
  5858. return 0;
  5859. if (node.data->type == mpack_type_uint) {
  5860. if (node.data->value.u <= (uint64_t)MPACK_INT64_MAX)
  5861. return (int64_t)node.data->value.u;
  5862. } else if (node.data->type == mpack_type_int) {
  5863. return node.data->value.i;
  5864. }
  5865. mpack_node_flag_error(node, mpack_error_type);
  5866. return 0;
  5867. }
  5868. unsigned int mpack_node_uint(mpack_node_t node) {
  5869. // This should be true at compile-time, so this just wraps the 32-bit function.
  5870. if (sizeof(unsigned int) == 4)
  5871. return (unsigned int)mpack_node_u32(node);
  5872. // Otherwise we use u64 and check the range.
  5873. uint64_t val = mpack_node_u64(node);
  5874. if (val <= MPACK_UINT_MAX)
  5875. return (unsigned int)val;
  5876. mpack_node_flag_error(node, mpack_error_type);
  5877. return 0;
  5878. }
  5879. int mpack_node_int(mpack_node_t node) {
  5880. // This should be true at compile-time, so this just wraps the 32-bit function.
  5881. if (sizeof(int) == 4)
  5882. return (int)mpack_node_i32(node);
  5883. // Otherwise we use i64 and check the range.
  5884. int64_t val = mpack_node_i64(node);
  5885. if (val >= MPACK_INT_MIN && val <= MPACK_INT_MAX)
  5886. return (int)val;
  5887. mpack_node_flag_error(node, mpack_error_type);
  5888. return 0;
  5889. }
  5890. #if MPACK_FLOAT
  5891. float mpack_node_float(mpack_node_t node) {
  5892. if (mpack_node_error(node) != mpack_ok)
  5893. return 0.0f;
  5894. if (node.data->type == mpack_type_uint)
  5895. return (float)node.data->value.u;
  5896. if (node.data->type == mpack_type_int)
  5897. return (float)node.data->value.i;
  5898. if (node.data->type == mpack_type_float)
  5899. return node.data->value.f;
  5900. if (node.data->type == mpack_type_double) {
  5901. #if MPACK_DOUBLE
  5902. return (float)node.data->value.d;
  5903. #else
  5904. return mpack_shorten_raw_double_to_float(node.data->value.d);
  5905. #endif
  5906. }
  5907. mpack_node_flag_error(node, mpack_error_type);
  5908. return 0.0f;
  5909. }
  5910. #endif
  5911. #if MPACK_DOUBLE
  5912. double mpack_node_double(mpack_node_t node) {
  5913. if (mpack_node_error(node) != mpack_ok)
  5914. return 0.0;
  5915. if (node.data->type == mpack_type_uint)
  5916. return (double)node.data->value.u;
  5917. else if (node.data->type == mpack_type_int)
  5918. return (double)node.data->value.i;
  5919. else if (node.data->type == mpack_type_float)
  5920. return (double)node.data->value.f;
  5921. else if (node.data->type == mpack_type_double)
  5922. return node.data->value.d;
  5923. mpack_node_flag_error(node, mpack_error_type);
  5924. return 0.0;
  5925. }
  5926. #endif
  5927. #if MPACK_FLOAT
  5928. float mpack_node_float_strict(mpack_node_t node) {
  5929. if (mpack_node_error(node) != mpack_ok)
  5930. return 0.0f;
  5931. if (node.data->type == mpack_type_float)
  5932. return node.data->value.f;
  5933. mpack_node_flag_error(node, mpack_error_type);
  5934. return 0.0f;
  5935. }
  5936. #endif
  5937. #if MPACK_DOUBLE
  5938. double mpack_node_double_strict(mpack_node_t node) {
  5939. if (mpack_node_error(node) != mpack_ok)
  5940. return 0.0;
  5941. if (node.data->type == mpack_type_float)
  5942. return (double)node.data->value.f;
  5943. else if (node.data->type == mpack_type_double)
  5944. return node.data->value.d;
  5945. mpack_node_flag_error(node, mpack_error_type);
  5946. return 0.0;
  5947. }
  5948. #endif
  5949. #if !MPACK_FLOAT
  5950. uint32_t mpack_node_raw_float(mpack_node_t node) {
  5951. if (mpack_node_error(node) != mpack_ok)
  5952. return 0;
  5953. if (node.data->type == mpack_type_float)
  5954. return node.data->value.f;
  5955. mpack_node_flag_error(node, mpack_error_type);
  5956. return 0;
  5957. }
  5958. #endif
  5959. #if !MPACK_DOUBLE
  5960. uint64_t mpack_node_raw_double(mpack_node_t node) {
  5961. if (mpack_node_error(node) != mpack_ok)
  5962. return 0;
  5963. if (node.data->type == mpack_type_double)
  5964. return node.data->value.d;
  5965. mpack_node_flag_error(node, mpack_error_type);
  5966. return 0;
  5967. }
  5968. #endif
  5969. #if MPACK_EXTENSIONS
  5970. int8_t mpack_node_exttype(mpack_node_t node) {
  5971. if (mpack_node_error(node) != mpack_ok)
  5972. return 0;
  5973. if (node.data->type == mpack_type_ext)
  5974. return mpack_node_exttype_unchecked(node);
  5975. mpack_node_flag_error(node, mpack_error_type);
  5976. return 0;
  5977. }
  5978. #endif
  5979. uint32_t mpack_node_data_len(mpack_node_t node) {
  5980. if (mpack_node_error(node) != mpack_ok)
  5981. return 0;
  5982. mpack_type_t type = node.data->type;
  5983. if (type == mpack_type_str || type == mpack_type_bin
  5984. #if MPACK_EXTENSIONS
  5985. || type == mpack_type_ext
  5986. #endif
  5987. )
  5988. return (uint32_t)node.data->len;
  5989. mpack_node_flag_error(node, mpack_error_type);
  5990. return 0;
  5991. }
  5992. size_t mpack_node_strlen(mpack_node_t node) {
  5993. if (mpack_node_error(node) != mpack_ok)
  5994. return 0;
  5995. if (node.data->type == mpack_type_str)
  5996. return (size_t)node.data->len;
  5997. mpack_node_flag_error(node, mpack_error_type);
  5998. return 0;
  5999. }
  6000. const char* mpack_node_str(mpack_node_t node) {
  6001. if (mpack_node_error(node) != mpack_ok)
  6002. return NULL;
  6003. mpack_type_t type = node.data->type;
  6004. if (type == mpack_type_str)
  6005. return mpack_node_data_unchecked(node);
  6006. mpack_node_flag_error(node, mpack_error_type);
  6007. return NULL;
  6008. }
  6009. const char* mpack_node_data(mpack_node_t node) {
  6010. if (mpack_node_error(node) != mpack_ok)
  6011. return NULL;
  6012. mpack_type_t type = node.data->type;
  6013. if (type == mpack_type_str || type == mpack_type_bin
  6014. #if MPACK_EXTENSIONS
  6015. || type == mpack_type_ext
  6016. #endif
  6017. )
  6018. return mpack_node_data_unchecked(node);
  6019. mpack_node_flag_error(node, mpack_error_type);
  6020. return NULL;
  6021. }
  6022. const char* mpack_node_bin_data(mpack_node_t node) {
  6023. if (mpack_node_error(node) != mpack_ok)
  6024. return NULL;
  6025. if (node.data->type == mpack_type_bin)
  6026. return mpack_node_data_unchecked(node);
  6027. mpack_node_flag_error(node, mpack_error_type);
  6028. return NULL;
  6029. }
  6030. size_t mpack_node_bin_size(mpack_node_t node) {
  6031. if (mpack_node_error(node) != mpack_ok)
  6032. return 0;
  6033. if (node.data->type == mpack_type_bin)
  6034. return (size_t)node.data->len;
  6035. mpack_node_flag_error(node, mpack_error_type);
  6036. return 0;
  6037. }
  6038. size_t mpack_node_array_length(mpack_node_t node) {
  6039. if (mpack_node_error(node) != mpack_ok)
  6040. return 0;
  6041. if (node.data->type != mpack_type_array) {
  6042. mpack_node_flag_error(node, mpack_error_type);
  6043. return 0;
  6044. }
  6045. return (size_t)node.data->len;
  6046. }
  6047. mpack_node_t mpack_node_array_at(mpack_node_t node, size_t index) {
  6048. if (mpack_node_error(node) != mpack_ok)
  6049. return mpack_tree_nil_node(node.tree);
  6050. if (node.data->type != mpack_type_array) {
  6051. mpack_node_flag_error(node, mpack_error_type);
  6052. return mpack_tree_nil_node(node.tree);
  6053. }
  6054. if (index >= node.data->len) {
  6055. mpack_node_flag_error(node, mpack_error_data);
  6056. return mpack_tree_nil_node(node.tree);
  6057. }
  6058. return mpack_node(node.tree, mpack_node_child(node, index));
  6059. }
  6060. size_t mpack_node_map_count(mpack_node_t node) {
  6061. if (mpack_node_error(node) != mpack_ok)
  6062. return 0;
  6063. if (node.data->type != mpack_type_map) {
  6064. mpack_node_flag_error(node, mpack_error_type);
  6065. return 0;
  6066. }
  6067. return node.data->len;
  6068. }
  6069. // internal node map lookup
  6070. static mpack_node_t mpack_node_map_at(mpack_node_t node, size_t index, size_t offset) {
  6071. if (mpack_node_error(node) != mpack_ok)
  6072. return mpack_tree_nil_node(node.tree);
  6073. if (node.data->type != mpack_type_map) {
  6074. mpack_node_flag_error(node, mpack_error_type);
  6075. return mpack_tree_nil_node(node.tree);
  6076. }
  6077. if (index >= node.data->len) {
  6078. mpack_node_flag_error(node, mpack_error_data);
  6079. return mpack_tree_nil_node(node.tree);
  6080. }
  6081. return mpack_node(node.tree, mpack_node_child(node, index * 2 + offset));
  6082. }
  6083. mpack_node_t mpack_node_map_key_at(mpack_node_t node, size_t index) {
  6084. return mpack_node_map_at(node, index, 0);
  6085. }
  6086. mpack_node_t mpack_node_map_value_at(mpack_node_t node, size_t index) {
  6087. return mpack_node_map_at(node, index, 1);
  6088. }
  6089. #endif
  6090. MPACK_SILENCE_WARNINGS_END