gl3d.cpp 1.3 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136
  1. ////////////////////////////////////////////////
  2. //gl3D --Vlad Luta --
  3. //built on 2024-01-16
  4. ////////////////////////////////////////////////
  5. #include "gl3d.h"
  6. #define TINYGLTF_IMPLEMENTATION
  7. #define STB_IMAGE_WRITE_IMPLEMENTATION
  8. #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
  9. #define TINYGLTF_NO_INCLUDE_JSON
  10. #define TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE
  11. /*
  12. __ _____ _____ _____
  13. __| | __| | | | JSON for Modern C++
  14. | | |__ | | | | | | version 3.5.0
  15. |_____|_____|_____|_|___| https://github.com/nlohmann/json
  16. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
  17. SPDX-License-Identifier: MIT
  18. Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
  19. Permission is hereby granted, free of charge, to any person obtaining a copy
  20. of this software and associated documentation files (the "Software"), to deal
  21. in the Software without restriction, including without limitation the rights
  22. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  23. copies of the Software, and to permit persons to whom the Software is
  24. furnished to do so, subject to the following conditions:
  25. The above copyright notice and this permission notice shall be included in all
  26. copies or substantial portions of the Software.
  27. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  33. SOFTWARE.
  34. */
  35. #ifndef NLOHMANN_JSON_HPP
  36. #define NLOHMANN_JSON_HPP
  37. #define NLOHMANN_JSON_VERSION_MAJOR 3
  38. #define NLOHMANN_JSON_VERSION_MINOR 5
  39. #define NLOHMANN_JSON_VERSION_PATCH 0
  40. #include <algorithm> // all_of, find, for_each
  41. #include <cassert> // assert
  42. #include <ciso646> // and, not, or
  43. #include <cstddef> // nullptr_t, ptrdiff_t, size_t
  44. #include <functional> // hash, less
  45. #include <initializer_list> // initializer_list
  46. #include <iosfwd> // istream, ostream
  47. #include <iterator> // random_access_iterator_tag
  48. #include <numeric> // accumulate
  49. #include <string> // string, stoi, to_string
  50. #include <utility> // declval, forward, move, pair, swap
  51. // #include <nlohmann/json_fwd.hpp>
  52. #ifndef NLOHMANN_JSON_FWD_HPP
  53. #define NLOHMANN_JSON_FWD_HPP
  54. #include <cstdint> // int64_t, uint64_t
  55. #include <map> // map
  56. #include <memory> // allocator
  57. #include <string> // string
  58. #include <vector> // vector
  59. /*!
  60. @brief namespace for Niels Lohmann
  61. @see https://github.com/nlohmann
  62. @since version 1.0.0
  63. */
  64. namespace nlohmann
  65. {
  66. /*!
  67. @brief default JSONSerializer template argument
  68. This serializer ignores the template arguments and uses ADL
  69. ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
  70. for serialization.
  71. */
  72. template<typename T = void, typename SFINAE = void>
  73. struct adl_serializer;
  74. template<template<typename U, typename V, typename... Args> class ObjectType =
  75. std::map,
  76. template<typename U, typename... Args> class ArrayType = std::vector,
  77. class StringType = std::string, class BooleanType = bool,
  78. class NumberIntegerType = std::int64_t,
  79. class NumberUnsignedType = std::uint64_t,
  80. class NumberFloatType = double,
  81. template<typename U> class AllocatorType = std::allocator,
  82. template<typename T, typename SFINAE = void> class JSONSerializer =
  83. adl_serializer>
  84. class basic_json;
  85. /*!
  86. @brief JSON Pointer
  87. A JSON pointer defines a string syntax for identifying a specific value
  88. within a JSON document. It can be used with functions `at` and
  89. `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
  90. @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
  91. @since version 2.0.0
  92. */
  93. template<typename BasicJsonType>
  94. class json_pointer;
  95. /*!
  96. @brief default JSON class
  97. This type is the default specialization of the @ref basic_json class which
  98. uses the standard template types.
  99. @since version 1.0.0
  100. */
  101. using json = basic_json<>;
  102. } // namespace nlohmann
  103. #endif
  104. // #include <nlohmann/detail/macro_scope.hpp>
  105. // This file contains all internal macro definitions
  106. // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
  107. // exclude unsupported compilers
  108. #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
  109. #if defined(__clang__)
  110. #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
  111. #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
  112. #endif
  113. #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
  114. #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
  115. #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
  116. #endif
  117. #endif
  118. #endif
  119. // disable float-equal warnings on GCC/clang
  120. #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
  121. #pragma GCC diagnostic push
  122. #pragma GCC diagnostic ignored "-Wfloat-equal"
  123. #endif
  124. // disable documentation warnings on clang
  125. #if defined(__clang__)
  126. #pragma GCC diagnostic push
  127. #pragma GCC diagnostic ignored "-Wdocumentation"
  128. #endif
  129. // allow for portable deprecation warnings
  130. #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
  131. #define JSON_DEPRECATED __attribute__((deprecated))
  132. #elif defined(_MSC_VER)
  133. #define JSON_DEPRECATED __declspec(deprecated)
  134. #else
  135. #define JSON_DEPRECATED
  136. #endif
  137. // allow to disable exceptions
  138. #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
  139. #define JSON_THROW(exception) throw exception
  140. #define JSON_TRY try
  141. #define JSON_CATCH(exception) catch(exception)
  142. #define JSON_INTERNAL_CATCH(exception) catch(exception)
  143. #else
  144. #define JSON_THROW(exception) std::abort()
  145. #define JSON_TRY if(true)
  146. #define JSON_CATCH(exception) if(false)
  147. #define JSON_INTERNAL_CATCH(exception) if(false)
  148. #endif
  149. // override exception macros
  150. #if defined(JSON_THROW_USER)
  151. #undef JSON_THROW
  152. #define JSON_THROW JSON_THROW_USER
  153. #endif
  154. #if defined(JSON_TRY_USER)
  155. #undef JSON_TRY
  156. #define JSON_TRY JSON_TRY_USER
  157. #endif
  158. #if defined(JSON_CATCH_USER)
  159. #undef JSON_CATCH
  160. #define JSON_CATCH JSON_CATCH_USER
  161. #undef JSON_INTERNAL_CATCH
  162. #define JSON_INTERNAL_CATCH JSON_CATCH_USER
  163. #endif
  164. #if defined(JSON_INTERNAL_CATCH_USER)
  165. #undef JSON_INTERNAL_CATCH
  166. #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
  167. #endif
  168. // manual branch prediction
  169. #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
  170. #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
  171. #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  172. #else
  173. #define JSON_LIKELY(x) x
  174. #define JSON_UNLIKELY(x) x
  175. #endif
  176. // C++ language standard detection
  177. #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
  178. #define JSON_HAS_CPP_17
  179. #define JSON_HAS_CPP_14
  180. #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
  181. #define JSON_HAS_CPP_14
  182. #endif
  183. /*!
  184. @brief macro to briefly define a mapping between an enum and JSON
  185. @def NLOHMANN_JSON_SERIALIZE_ENUM
  186. @since version 3.4.0
  187. */
  188. #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
  189. template<typename BasicJsonType> \
  190. inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
  191. { \
  192. static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
  193. static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
  194. auto it = std::find_if(std::begin(m), std::end(m), \
  195. [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
  196. { \
  197. return ej_pair.first == e; \
  198. }); \
  199. j = ((it != std::end(m)) ? it : std::begin(m))->second; \
  200. } \
  201. template<typename BasicJsonType> \
  202. inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
  203. { \
  204. static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
  205. static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
  206. auto it = std::find_if(std::begin(m), std::end(m), \
  207. [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
  208. { \
  209. return ej_pair.second == j; \
  210. }); \
  211. e = ((it != std::end(m)) ? it : std::begin(m))->first; \
  212. }
  213. // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
  214. // may be removed in the future once the class is split.
  215. #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
  216. template<template<typename, typename, typename...> class ObjectType, \
  217. template<typename, typename...> class ArrayType, \
  218. class StringType, class BooleanType, class NumberIntegerType, \
  219. class NumberUnsignedType, class NumberFloatType, \
  220. template<typename> class AllocatorType, \
  221. template<typename, typename = void> class JSONSerializer>
  222. #define NLOHMANN_BASIC_JSON_TPL \
  223. basic_json<ObjectType, ArrayType, StringType, BooleanType, \
  224. NumberIntegerType, NumberUnsignedType, NumberFloatType, \
  225. AllocatorType, JSONSerializer>
  226. // #include <nlohmann/detail/meta/cpp_future.hpp>
  227. #include <ciso646> // not
  228. #include <cstddef> // size_t
  229. #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
  230. namespace nlohmann
  231. {
  232. namespace detail
  233. {
  234. // alias templates to reduce boilerplate
  235. template<bool B, typename T = void>
  236. using enable_if_t = typename std::enable_if<B, T>::type;
  237. template<typename T>
  238. using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
  239. // implementation of C++14 index_sequence and affiliates
  240. // source: https://stackoverflow.com/a/32223343
  241. template<std::size_t... Ints>
  242. struct index_sequence
  243. {
  244. using type = index_sequence;
  245. using value_type = std::size_t;
  246. static constexpr std::size_t size() noexcept
  247. {
  248. return sizeof...(Ints);
  249. }
  250. };
  251. template<class Sequence1, class Sequence2>
  252. struct merge_and_renumber;
  253. template<std::size_t... I1, std::size_t... I2>
  254. struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
  255. : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
  256. template<std::size_t N>
  257. struct make_index_sequence
  258. : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
  259. typename make_index_sequence < N - N / 2 >::type > {};
  260. template<> struct make_index_sequence<0> : index_sequence<> {};
  261. template<> struct make_index_sequence<1> : index_sequence<0> {};
  262. template<typename... Ts>
  263. using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
  264. // dispatch utility (taken from ranges-v3)
  265. template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
  266. template<> struct priority_tag<0> {};
  267. // taken from ranges-v3
  268. template<typename T>
  269. struct static_const
  270. {
  271. static constexpr T value{};
  272. };
  273. template<typename T>
  274. constexpr T static_const<T>::value;
  275. } // namespace detail
  276. } // namespace nlohmann
  277. // #include <nlohmann/detail/meta/type_traits.hpp>
  278. #include <ciso646> // not
  279. #include <limits> // numeric_limits
  280. #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
  281. #include <utility> // declval
  282. // #include <nlohmann/json_fwd.hpp>
  283. // #include <nlohmann/detail/iterators/iterator_traits.hpp>
  284. #include <iterator> // random_access_iterator_tag
  285. // #include <nlohmann/detail/meta/void_t.hpp>
  286. namespace nlohmann
  287. {
  288. namespace detail
  289. {
  290. template <typename ...Ts> struct make_void
  291. {
  292. using type = void;
  293. };
  294. template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
  295. } // namespace detail
  296. } // namespace nlohmann
  297. // #include <nlohmann/detail/meta/cpp_future.hpp>
  298. namespace nlohmann
  299. {
  300. namespace detail
  301. {
  302. template <typename It, typename = void>
  303. struct iterator_types {};
  304. template <typename It>
  305. struct iterator_types <
  306. It,
  307. void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
  308. typename It::reference, typename It::iterator_category >>
  309. {
  310. using difference_type = typename It::difference_type;
  311. using value_type = typename It::value_type;
  312. using pointer = typename It::pointer;
  313. using reference = typename It::reference;
  314. using iterator_category = typename It::iterator_category;
  315. };
  316. // This is required as some compilers implement std::iterator_traits in a way that
  317. // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
  318. template <typename T, typename = void>
  319. struct iterator_traits
  320. {
  321. };
  322. template <typename T>
  323. struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
  324. : iterator_types<T>
  325. {
  326. };
  327. template <typename T>
  328. struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
  329. {
  330. using iterator_category = std::random_access_iterator_tag;
  331. using value_type = T;
  332. using difference_type = ptrdiff_t;
  333. using pointer = T*;
  334. using reference = T&;
  335. };
  336. }
  337. }
  338. // #include <nlohmann/detail/meta/cpp_future.hpp>
  339. // #include <nlohmann/detail/meta/detected.hpp>
  340. #include <type_traits>
  341. // #include <nlohmann/detail/meta/void_t.hpp>
  342. // http://en.cppreference.com/w/cpp/experimental/is_detected
  343. namespace nlohmann
  344. {
  345. namespace detail
  346. {
  347. struct nonesuch
  348. {
  349. nonesuch() = delete;
  350. ~nonesuch() = delete;
  351. nonesuch(nonesuch const&) = delete;
  352. void operator=(nonesuch const&) = delete;
  353. };
  354. template <class Default,
  355. class AlwaysVoid,
  356. template <class...> class Op,
  357. class... Args>
  358. struct detector
  359. {
  360. using value_t = std::false_type;
  361. using type = Default;
  362. };
  363. template <class Default, template <class...> class Op, class... Args>
  364. struct detector<Default, void_t<Op<Args...>>, Op, Args...>
  365. {
  366. using value_t = std::true_type;
  367. using type = Op<Args...>;
  368. };
  369. template <template <class...> class Op, class... Args>
  370. using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
  371. template <template <class...> class Op, class... Args>
  372. using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
  373. template <class Default, template <class...> class Op, class... Args>
  374. using detected_or = detector<Default, void, Op, Args...>;
  375. template <class Default, template <class...> class Op, class... Args>
  376. using detected_or_t = typename detected_or<Default, Op, Args...>::type;
  377. template <class Expected, template <class...> class Op, class... Args>
  378. using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
  379. template <class To, template <class...> class Op, class... Args>
  380. using is_detected_convertible =
  381. std::is_convertible<detected_t<Op, Args...>, To>;
  382. } // namespace detail
  383. } // namespace nlohmann
  384. // #include <nlohmann/detail/macro_scope.hpp>
  385. namespace nlohmann
  386. {
  387. /*!
  388. @brief detail namespace with internal helper functions
  389. This namespace collects functions that should not be exposed,
  390. implementations of some @ref basic_json methods, and meta-programming helpers.
  391. @since version 2.1.0
  392. */
  393. namespace detail
  394. {
  395. /////////////
  396. // helpers //
  397. /////////////
  398. // Note to maintainers:
  399. //
  400. // Every trait in this file expects a non CV-qualified type.
  401. // The only exceptions are in the 'aliases for detected' section
  402. // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
  403. //
  404. // In this case, T has to be properly CV-qualified to constraint the function arguments
  405. // (e.g. to_json(BasicJsonType&, const T&))
  406. template<typename> struct is_basic_json : std::false_type {};
  407. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  408. struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
  409. //////////////////////////
  410. // aliases for detected //
  411. //////////////////////////
  412. template <typename T>
  413. using mapped_type_t = typename T::mapped_type;
  414. template <typename T>
  415. using key_type_t = typename T::key_type;
  416. template <typename T>
  417. using value_type_t = typename T::value_type;
  418. template <typename T>
  419. using difference_type_t = typename T::difference_type;
  420. template <typename T>
  421. using pointer_t = typename T::pointer;
  422. template <typename T>
  423. using reference_t = typename T::reference;
  424. template <typename T>
  425. using iterator_category_t = typename T::iterator_category;
  426. template <typename T>
  427. using iterator_t = typename T::iterator;
  428. template <typename T, typename... Args>
  429. using to_json_function = decltype(T::to_json(std::declval<Args>()...));
  430. template <typename T, typename... Args>
  431. using from_json_function = decltype(T::from_json(std::declval<Args>()...));
  432. template <typename T, typename U>
  433. using get_template_function = decltype(std::declval<T>().template get<U>());
  434. // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
  435. template <typename BasicJsonType, typename T, typename = void>
  436. struct has_from_json : std::false_type {};
  437. template <typename BasicJsonType, typename T>
  438. struct has_from_json<BasicJsonType, T,
  439. enable_if_t<not is_basic_json<T>::value>>
  440. {
  441. using serializer = typename BasicJsonType::template json_serializer<T, void>;
  442. static constexpr bool value =
  443. is_detected_exact<void, from_json_function, serializer,
  444. const BasicJsonType&, T&>::value;
  445. };
  446. // This trait checks if JSONSerializer<T>::from_json(json const&) exists
  447. // this overload is used for non-default-constructible user-defined-types
  448. template <typename BasicJsonType, typename T, typename = void>
  449. struct has_non_default_from_json : std::false_type {};
  450. template<typename BasicJsonType, typename T>
  451. struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
  452. {
  453. using serializer = typename BasicJsonType::template json_serializer<T, void>;
  454. static constexpr bool value =
  455. is_detected_exact<T, from_json_function, serializer,
  456. const BasicJsonType&>::value;
  457. };
  458. // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
  459. // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
  460. template <typename BasicJsonType, typename T, typename = void>
  461. struct has_to_json : std::false_type {};
  462. template <typename BasicJsonType, typename T>
  463. struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
  464. {
  465. using serializer = typename BasicJsonType::template json_serializer<T, void>;
  466. static constexpr bool value =
  467. is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
  468. T>::value;
  469. };
  470. ///////////////////
  471. // is_ functions //
  472. ///////////////////
  473. template <typename T, typename = void>
  474. struct is_iterator_traits : std::false_type {};
  475. template <typename T>
  476. struct is_iterator_traits<iterator_traits<T>>
  477. {
  478. private:
  479. using traits = iterator_traits<T>;
  480. public:
  481. static constexpr auto value =
  482. is_detected<value_type_t, traits>::value &&
  483. is_detected<difference_type_t, traits>::value &&
  484. is_detected<pointer_t, traits>::value &&
  485. is_detected<iterator_category_t, traits>::value &&
  486. is_detected<reference_t, traits>::value;
  487. };
  488. // source: https://stackoverflow.com/a/37193089/4116453
  489. template <typename T, typename = void>
  490. struct is_complete_type : std::false_type {};
  491. template <typename T>
  492. struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
  493. template <typename BasicJsonType, typename CompatibleObjectType,
  494. typename = void>
  495. struct is_compatible_object_type_impl : std::false_type {};
  496. template <typename BasicJsonType, typename CompatibleObjectType>
  497. struct is_compatible_object_type_impl <
  498. BasicJsonType, CompatibleObjectType,
  499. enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
  500. is_detected<key_type_t, CompatibleObjectType>::value >>
  501. {
  502. using object_t = typename BasicJsonType::object_t;
  503. // macOS's is_constructible does not play well with nonesuch...
  504. static constexpr bool value =
  505. std::is_constructible<typename object_t::key_type,
  506. typename CompatibleObjectType::key_type>::value and
  507. std::is_constructible<typename object_t::mapped_type,
  508. typename CompatibleObjectType::mapped_type>::value;
  509. };
  510. template <typename BasicJsonType, typename CompatibleObjectType>
  511. struct is_compatible_object_type
  512. : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
  513. template <typename BasicJsonType, typename ConstructibleObjectType,
  514. typename = void>
  515. struct is_constructible_object_type_impl : std::false_type {};
  516. template <typename BasicJsonType, typename ConstructibleObjectType>
  517. struct is_constructible_object_type_impl <
  518. BasicJsonType, ConstructibleObjectType,
  519. enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
  520. is_detected<key_type_t, ConstructibleObjectType>::value >>
  521. {
  522. using object_t = typename BasicJsonType::object_t;
  523. static constexpr bool value =
  524. (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
  525. std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
  526. (has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
  527. has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
  528. };
  529. template <typename BasicJsonType, typename ConstructibleObjectType>
  530. struct is_constructible_object_type
  531. : is_constructible_object_type_impl<BasicJsonType,
  532. ConstructibleObjectType> {};
  533. template <typename BasicJsonType, typename CompatibleStringType,
  534. typename = void>
  535. struct is_compatible_string_type_impl : std::false_type {};
  536. template <typename BasicJsonType, typename CompatibleStringType>
  537. struct is_compatible_string_type_impl <
  538. BasicJsonType, CompatibleStringType,
  539. enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
  540. value_type_t, CompatibleStringType>::value >>
  541. {
  542. static constexpr auto value =
  543. std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
  544. };
  545. template <typename BasicJsonType, typename ConstructibleStringType>
  546. struct is_compatible_string_type
  547. : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
  548. template <typename BasicJsonType, typename ConstructibleStringType,
  549. typename = void>
  550. struct is_constructible_string_type_impl : std::false_type {};
  551. template <typename BasicJsonType, typename ConstructibleStringType>
  552. struct is_constructible_string_type_impl <
  553. BasicJsonType, ConstructibleStringType,
  554. enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
  555. value_type_t, ConstructibleStringType>::value >>
  556. {
  557. static constexpr auto value =
  558. std::is_constructible<ConstructibleStringType,
  559. typename BasicJsonType::string_t>::value;
  560. };
  561. template <typename BasicJsonType, typename ConstructibleStringType>
  562. struct is_constructible_string_type
  563. : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
  564. template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
  565. struct is_compatible_array_type_impl : std::false_type {};
  566. template <typename BasicJsonType, typename CompatibleArrayType>
  567. struct is_compatible_array_type_impl <
  568. BasicJsonType, CompatibleArrayType,
  569. enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
  570. is_detected<iterator_t, CompatibleArrayType>::value and
  571. // This is needed because json_reverse_iterator has a ::iterator type...
  572. // Therefore it is detected as a CompatibleArrayType.
  573. // The real fix would be to have an Iterable concept.
  574. not is_iterator_traits<
  575. iterator_traits<CompatibleArrayType>>::value >>
  576. {
  577. static constexpr bool value =
  578. std::is_constructible<BasicJsonType,
  579. typename CompatibleArrayType::value_type>::value;
  580. };
  581. template <typename BasicJsonType, typename CompatibleArrayType>
  582. struct is_compatible_array_type
  583. : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
  584. template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
  585. struct is_constructible_array_type_impl : std::false_type {};
  586. template <typename BasicJsonType, typename ConstructibleArrayType>
  587. struct is_constructible_array_type_impl <
  588. BasicJsonType, ConstructibleArrayType,
  589. enable_if_t<std::is_same<ConstructibleArrayType,
  590. typename BasicJsonType::value_type>::value >>
  591. : std::true_type {};
  592. template <typename BasicJsonType, typename ConstructibleArrayType>
  593. struct is_constructible_array_type_impl <
  594. BasicJsonType, ConstructibleArrayType,
  595. enable_if_t<not std::is_same<ConstructibleArrayType,
  596. typename BasicJsonType::value_type>::value and
  597. is_detected<value_type_t, ConstructibleArrayType>::value and
  598. is_detected<iterator_t, ConstructibleArrayType>::value and
  599. is_complete_type<
  600. detected_t<value_type_t, ConstructibleArrayType>>::value >>
  601. {
  602. static constexpr bool value =
  603. // This is needed because json_reverse_iterator has a ::iterator type,
  604. // furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
  605. // Therefore it is detected as a ConstructibleArrayType.
  606. // The real fix would be to have an Iterable concept.
  607. not is_iterator_traits <
  608. iterator_traits<ConstructibleArrayType >>::value and
  609. (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
  610. has_from_json<BasicJsonType,
  611. typename ConstructibleArrayType::value_type>::value or
  612. has_non_default_from_json <
  613. BasicJsonType, typename ConstructibleArrayType::value_type >::value);
  614. };
  615. template <typename BasicJsonType, typename ConstructibleArrayType>
  616. struct is_constructible_array_type
  617. : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
  618. template <typename RealIntegerType, typename CompatibleNumberIntegerType,
  619. typename = void>
  620. struct is_compatible_integer_type_impl : std::false_type {};
  621. template <typename RealIntegerType, typename CompatibleNumberIntegerType>
  622. struct is_compatible_integer_type_impl <
  623. RealIntegerType, CompatibleNumberIntegerType,
  624. enable_if_t<std::is_integral<RealIntegerType>::value and
  625. std::is_integral<CompatibleNumberIntegerType>::value and
  626. not std::is_same<bool, CompatibleNumberIntegerType>::value >>
  627. {
  628. // is there an assert somewhere on overflows?
  629. using RealLimits = std::numeric_limits<RealIntegerType>;
  630. using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
  631. static constexpr auto value =
  632. std::is_constructible<RealIntegerType,
  633. CompatibleNumberIntegerType>::value and
  634. CompatibleLimits::is_integer and
  635. RealLimits::is_signed == CompatibleLimits::is_signed;
  636. };
  637. template <typename RealIntegerType, typename CompatibleNumberIntegerType>
  638. struct is_compatible_integer_type
  639. : is_compatible_integer_type_impl<RealIntegerType,
  640. CompatibleNumberIntegerType> {};
  641. template <typename BasicJsonType, typename CompatibleType, typename = void>
  642. struct is_compatible_type_impl: std::false_type {};
  643. template <typename BasicJsonType, typename CompatibleType>
  644. struct is_compatible_type_impl <
  645. BasicJsonType, CompatibleType,
  646. enable_if_t<is_complete_type<CompatibleType>::value >>
  647. {
  648. static constexpr bool value =
  649. has_to_json<BasicJsonType, CompatibleType>::value;
  650. };
  651. template <typename BasicJsonType, typename CompatibleType>
  652. struct is_compatible_type
  653. : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
  654. } // namespace detail
  655. } // namespace nlohmann
  656. // #include <nlohmann/detail/exceptions.hpp>
  657. #include <exception> // exception
  658. #include <stdexcept> // runtime_error
  659. #include <string> // to_string
  660. // #include <nlohmann/detail/input/position_t.hpp>
  661. #include <cstddef> // size_t
  662. namespace nlohmann
  663. {
  664. namespace detail
  665. {
  666. /// struct to capture the start position of the current token
  667. struct position_t
  668. {
  669. /// the total number of characters read
  670. std::size_t chars_read_total = 0;
  671. /// the number of characters read in the current line
  672. std::size_t chars_read_current_line = 0;
  673. /// the number of lines read
  674. std::size_t lines_read = 0;
  675. /// conversion to size_t to preserve SAX interface
  676. constexpr operator size_t() const
  677. {
  678. return chars_read_total;
  679. }
  680. };
  681. }
  682. }
  683. namespace nlohmann
  684. {
  685. namespace detail
  686. {
  687. ////////////////
  688. // exceptions //
  689. ////////////////
  690. /*!
  691. @brief general exception of the @ref basic_json class
  692. This class is an extension of `std::exception` objects with a member @a id for
  693. exception ids. It is used as the base class for all exceptions thrown by the
  694. @ref basic_json class. This class can hence be used as "wildcard" to catch
  695. exceptions.
  696. Subclasses:
  697. - @ref parse_error for exceptions indicating a parse error
  698. - @ref invalid_iterator for exceptions indicating errors with iterators
  699. - @ref type_error for exceptions indicating executing a member function with
  700. a wrong type
  701. - @ref out_of_range for exceptions indicating access out of the defined range
  702. - @ref other_error for exceptions indicating other library errors
  703. @internal
  704. @note To have nothrow-copy-constructible exceptions, we internally use
  705. `std::runtime_error` which can cope with arbitrary-length error messages.
  706. Intermediate strings are built with static functions and then passed to
  707. the actual constructor.
  708. @endinternal
  709. @liveexample{The following code shows how arbitrary library exceptions can be
  710. caught.,exception}
  711. @since version 3.0.0
  712. */
  713. class exception : public std::exception
  714. {
  715. public:
  716. /// returns the explanatory string
  717. const char* what() const noexcept override
  718. {
  719. return m.what();
  720. }
  721. /// the id of the exception
  722. const int id;
  723. protected:
  724. exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
  725. static std::string name(const std::string& ename, int id_)
  726. {
  727. return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
  728. }
  729. private:
  730. /// an exception object as storage for error messages
  731. std::runtime_error m;
  732. };
  733. /*!
  734. @brief exception indicating a parse error
  735. This exception is thrown by the library when a parse error occurs. Parse errors
  736. can occur during the deserialization of JSON text, CBOR, MessagePack, as well
  737. as when using JSON Patch.
  738. Member @a byte holds the byte index of the last read character in the input
  739. file.
  740. Exceptions have ids 1xx.
  741. name / id | example message | description
  742. ------------------------------ | --------------- | -------------------------
  743. json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
  744. json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
  745. json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
  746. json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
  747. json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
  748. json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
  749. json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
  750. json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
  751. json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
  752. json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
  753. json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
  754. json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
  755. json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
  756. @note For an input with n bytes, 1 is the index of the first character and n+1
  757. is the index of the terminating null byte or the end of file. This also
  758. holds true when reading a byte vector (CBOR or MessagePack).
  759. @liveexample{The following code shows how a `parse_error` exception can be
  760. caught.,parse_error}
  761. @sa @ref exception for the base class of the library exceptions
  762. @sa @ref invalid_iterator for exceptions indicating errors with iterators
  763. @sa @ref type_error for exceptions indicating executing a member function with
  764. a wrong type
  765. @sa @ref out_of_range for exceptions indicating access out of the defined range
  766. @sa @ref other_error for exceptions indicating other library errors
  767. @since version 3.0.0
  768. */
  769. class parse_error : public exception
  770. {
  771. public:
  772. /*!
  773. @brief create a parse error exception
  774. @param[in] id_ the id of the exception
  775. @param[in] position the position where the error occurred (or with
  776. chars_read_total=0 if the position cannot be
  777. determined)
  778. @param[in] what_arg the explanatory string
  779. @return parse_error object
  780. */
  781. static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
  782. {
  783. std::string w = exception::name("parse_error", id_) + "parse error" +
  784. position_string(pos) + ": " + what_arg;
  785. return parse_error(id_, pos.chars_read_total, w.c_str());
  786. }
  787. static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
  788. {
  789. std::string w = exception::name("parse_error", id_) + "parse error" +
  790. (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
  791. ": " + what_arg;
  792. return parse_error(id_, byte_, w.c_str());
  793. }
  794. /*!
  795. @brief byte index of the parse error
  796. The byte index of the last read character in the input file.
  797. @note For an input with n bytes, 1 is the index of the first character and
  798. n+1 is the index of the terminating null byte or the end of file.
  799. This also holds true when reading a byte vector (CBOR or MessagePack).
  800. */
  801. const std::size_t byte;
  802. private:
  803. parse_error(int id_, std::size_t byte_, const char* what_arg)
  804. : exception(id_, what_arg), byte(byte_) {}
  805. static std::string position_string(const position_t& pos)
  806. {
  807. return " at line " + std::to_string(pos.lines_read + 1) +
  808. ", column " + std::to_string(pos.chars_read_current_line);
  809. }
  810. };
  811. /*!
  812. @brief exception indicating errors with iterators
  813. This exception is thrown if iterators passed to a library function do not match
  814. the expected semantics.
  815. Exceptions have ids 2xx.
  816. name / id | example message | description
  817. ----------------------------------- | --------------- | -------------------------
  818. json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
  819. json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
  820. json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
  821. json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
  822. json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
  823. json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
  824. json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
  825. json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
  826. json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
  827. json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
  828. json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
  829. json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
  830. json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
  831. json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
  832. @liveexample{The following code shows how an `invalid_iterator` exception can be
  833. caught.,invalid_iterator}
  834. @sa @ref exception for the base class of the library exceptions
  835. @sa @ref parse_error for exceptions indicating a parse error
  836. @sa @ref type_error for exceptions indicating executing a member function with
  837. a wrong type
  838. @sa @ref out_of_range for exceptions indicating access out of the defined range
  839. @sa @ref other_error for exceptions indicating other library errors
  840. @since version 3.0.0
  841. */
  842. class invalid_iterator : public exception
  843. {
  844. public:
  845. static invalid_iterator create(int id_, const std::string& what_arg)
  846. {
  847. std::string w = exception::name("invalid_iterator", id_) + what_arg;
  848. return invalid_iterator(id_, w.c_str());
  849. }
  850. private:
  851. invalid_iterator(int id_, const char* what_arg)
  852. : exception(id_, what_arg) {}
  853. };
  854. /*!
  855. @brief exception indicating executing a member function with a wrong type
  856. This exception is thrown in case of a type error; that is, a library function is
  857. executed on a JSON value whose type does not match the expected semantics.
  858. Exceptions have ids 3xx.
  859. name / id | example message | description
  860. ----------------------------- | --------------- | -------------------------
  861. json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
  862. json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
  863. json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
  864. json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
  865. json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
  866. json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
  867. json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
  868. json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
  869. json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
  870. json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
  871. json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
  872. json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
  873. json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
  874. json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
  875. json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
  876. json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
  877. json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
  878. @liveexample{The following code shows how a `type_error` exception can be
  879. caught.,type_error}
  880. @sa @ref exception for the base class of the library exceptions
  881. @sa @ref parse_error for exceptions indicating a parse error
  882. @sa @ref invalid_iterator for exceptions indicating errors with iterators
  883. @sa @ref out_of_range for exceptions indicating access out of the defined range
  884. @sa @ref other_error for exceptions indicating other library errors
  885. @since version 3.0.0
  886. */
  887. class type_error : public exception
  888. {
  889. public:
  890. static type_error create(int id_, const std::string& what_arg)
  891. {
  892. std::string w = exception::name("type_error", id_) + what_arg;
  893. return type_error(id_, w.c_str());
  894. }
  895. private:
  896. type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
  897. };
  898. /*!
  899. @brief exception indicating access out of the defined range
  900. This exception is thrown in case a library function is called on an input
  901. parameter that exceeds the expected range, for instance in case of array
  902. indices or nonexisting object keys.
  903. Exceptions have ids 4xx.
  904. name / id | example message | description
  905. ------------------------------- | --------------- | -------------------------
  906. json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
  907. json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
  908. json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
  909. json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
  910. json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
  911. json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
  912. json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
  913. json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
  914. json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
  915. @liveexample{The following code shows how an `out_of_range` exception can be
  916. caught.,out_of_range}
  917. @sa @ref exception for the base class of the library exceptions
  918. @sa @ref parse_error for exceptions indicating a parse error
  919. @sa @ref invalid_iterator for exceptions indicating errors with iterators
  920. @sa @ref type_error for exceptions indicating executing a member function with
  921. a wrong type
  922. @sa @ref other_error for exceptions indicating other library errors
  923. @since version 3.0.0
  924. */
  925. class out_of_range : public exception
  926. {
  927. public:
  928. static out_of_range create(int id_, const std::string& what_arg)
  929. {
  930. std::string w = exception::name("out_of_range", id_) + what_arg;
  931. return out_of_range(id_, w.c_str());
  932. }
  933. private:
  934. out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
  935. };
  936. /*!
  937. @brief exception indicating other library errors
  938. This exception is thrown in case of errors that cannot be classified with the
  939. other exception types.
  940. Exceptions have ids 5xx.
  941. name / id | example message | description
  942. ------------------------------ | --------------- | -------------------------
  943. json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
  944. @sa @ref exception for the base class of the library exceptions
  945. @sa @ref parse_error for exceptions indicating a parse error
  946. @sa @ref invalid_iterator for exceptions indicating errors with iterators
  947. @sa @ref type_error for exceptions indicating executing a member function with
  948. a wrong type
  949. @sa @ref out_of_range for exceptions indicating access out of the defined range
  950. @liveexample{The following code shows how an `other_error` exception can be
  951. caught.,other_error}
  952. @since version 3.0.0
  953. */
  954. class other_error : public exception
  955. {
  956. public:
  957. static other_error create(int id_, const std::string& what_arg)
  958. {
  959. std::string w = exception::name("other_error", id_) + what_arg;
  960. return other_error(id_, w.c_str());
  961. }
  962. private:
  963. other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
  964. };
  965. } // namespace detail
  966. } // namespace nlohmann
  967. // #include <nlohmann/detail/value_t.hpp>
  968. #include <array> // array
  969. #include <ciso646> // and
  970. #include <cstddef> // size_t
  971. #include <cstdint> // uint8_t
  972. namespace nlohmann
  973. {
  974. namespace detail
  975. {
  976. ///////////////////////////
  977. // JSON type enumeration //
  978. ///////////////////////////
  979. /*!
  980. @brief the JSON type enumeration
  981. This enumeration collects the different JSON types. It is internally used to
  982. distinguish the stored values, and the functions @ref basic_json::is_null(),
  983. @ref basic_json::is_object(), @ref basic_json::is_array(),
  984. @ref basic_json::is_string(), @ref basic_json::is_boolean(),
  985. @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
  986. @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
  987. @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
  988. @ref basic_json::is_structured() rely on it.
  989. @note There are three enumeration entries (number_integer, number_unsigned, and
  990. number_float), because the library distinguishes these three types for numbers:
  991. @ref basic_json::number_unsigned_t is used for unsigned integers,
  992. @ref basic_json::number_integer_t is used for signed integers, and
  993. @ref basic_json::number_float_t is used for floating-point numbers or to
  994. approximate integers which do not fit in the limits of their respective type.
  995. @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
  996. value with the default value for a given type
  997. @since version 1.0.0
  998. */
  999. enum class value_t : std::uint8_t
  1000. {
  1001. null, ///< null value
  1002. object, ///< object (unordered set of name/value pairs)
  1003. array, ///< array (ordered collection of values)
  1004. string, ///< string value
  1005. boolean, ///< boolean value
  1006. number_integer, ///< number value (signed integer)
  1007. number_unsigned, ///< number value (unsigned integer)
  1008. number_float, ///< number value (floating-point)
  1009. discarded ///< discarded by the the parser callback function
  1010. };
  1011. /*!
  1012. @brief comparison operator for JSON types
  1013. Returns an ordering that is similar to Python:
  1014. - order: null < boolean < number < object < array < string
  1015. - furthermore, each type is not smaller than itself
  1016. - discarded values are not comparable
  1017. @since version 1.0.0
  1018. */
  1019. inline bool operator<(const value_t lhs, const value_t rhs) noexcept
  1020. {
  1021. static constexpr std::array<std::uint8_t, 8> order = {{
  1022. 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
  1023. 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
  1024. }
  1025. };
  1026. const auto l_index = static_cast<std::size_t>(lhs);
  1027. const auto r_index = static_cast<std::size_t>(rhs);
  1028. return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
  1029. }
  1030. } // namespace detail
  1031. } // namespace nlohmann
  1032. // #include <nlohmann/detail/conversions/from_json.hpp>
  1033. #include <algorithm> // transform
  1034. #include <array> // array
  1035. #include <ciso646> // and, not
  1036. #include <forward_list> // forward_list
  1037. #include <iterator> // inserter, front_inserter, end
  1038. #include <map> // map
  1039. #include <string> // string
  1040. #include <tuple> // tuple, make_tuple
  1041. #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
  1042. #include <unordered_map> // unordered_map
  1043. #include <utility> // pair, declval
  1044. #include <valarray> // valarray
  1045. // #include <nlohmann/detail/exceptions.hpp>
  1046. // #include <nlohmann/detail/macro_scope.hpp>
  1047. // #include <nlohmann/detail/meta/cpp_future.hpp>
  1048. // #include <nlohmann/detail/meta/type_traits.hpp>
  1049. // #include <nlohmann/detail/value_t.hpp>
  1050. namespace nlohmann
  1051. {
  1052. namespace detail
  1053. {
  1054. template<typename BasicJsonType>
  1055. void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
  1056. {
  1057. if (JSON_UNLIKELY(not j.is_null()))
  1058. {
  1059. JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
  1060. }
  1061. n = nullptr;
  1062. }
  1063. // overloads for basic_json template parameters
  1064. template<typename BasicJsonType, typename ArithmeticType,
  1065. enable_if_t<std::is_arithmetic<ArithmeticType>::value and
  1066. not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
  1067. int> = 0>
  1068. void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
  1069. {
  1070. switch (static_cast<value_t>(j))
  1071. {
  1072. case value_t::number_unsigned:
  1073. {
  1074. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
  1075. break;
  1076. }
  1077. case value_t::number_integer:
  1078. {
  1079. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
  1080. break;
  1081. }
  1082. case value_t::number_float:
  1083. {
  1084. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
  1085. break;
  1086. }
  1087. default:
  1088. JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
  1089. }
  1090. }
  1091. template<typename BasicJsonType>
  1092. void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
  1093. {
  1094. if (JSON_UNLIKELY(not j.is_boolean()))
  1095. {
  1096. JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
  1097. }
  1098. b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
  1099. }
  1100. template<typename BasicJsonType>
  1101. void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
  1102. {
  1103. if (JSON_UNLIKELY(not j.is_string()))
  1104. {
  1105. JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
  1106. }
  1107. s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
  1108. }
  1109. template <
  1110. typename BasicJsonType, typename ConstructibleStringType,
  1111. enable_if_t <
  1112. is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
  1113. not std::is_same<typename BasicJsonType::string_t,
  1114. ConstructibleStringType>::value,
  1115. int > = 0 >
  1116. void from_json(const BasicJsonType& j, ConstructibleStringType& s)
  1117. {
  1118. if (JSON_UNLIKELY(not j.is_string()))
  1119. {
  1120. JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
  1121. }
  1122. s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
  1123. }
  1124. template<typename BasicJsonType>
  1125. void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
  1126. {
  1127. get_arithmetic_value(j, val);
  1128. }
  1129. template<typename BasicJsonType>
  1130. void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
  1131. {
  1132. get_arithmetic_value(j, val);
  1133. }
  1134. template<typename BasicJsonType>
  1135. void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
  1136. {
  1137. get_arithmetic_value(j, val);
  1138. }
  1139. template<typename BasicJsonType, typename EnumType,
  1140. enable_if_t<std::is_enum<EnumType>::value, int> = 0>
  1141. void from_json(const BasicJsonType& j, EnumType& e)
  1142. {
  1143. typename std::underlying_type<EnumType>::type val;
  1144. get_arithmetic_value(j, val);
  1145. e = static_cast<EnumType>(val);
  1146. }
  1147. // forward_list doesn't have an insert method
  1148. template<typename BasicJsonType, typename T, typename Allocator,
  1149. enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
  1150. void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
  1151. {
  1152. if (JSON_UNLIKELY(not j.is_array()))
  1153. {
  1154. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
  1155. }
  1156. std::transform(j.rbegin(), j.rend(),
  1157. std::front_inserter(l), [](const BasicJsonType & i)
  1158. {
  1159. return i.template get<T>();
  1160. });
  1161. }
  1162. // valarray doesn't have an insert method
  1163. template<typename BasicJsonType, typename T,
  1164. enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
  1165. void from_json(const BasicJsonType& j, std::valarray<T>& l)
  1166. {
  1167. if (JSON_UNLIKELY(not j.is_array()))
  1168. {
  1169. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
  1170. }
  1171. l.resize(j.size());
  1172. std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
  1173. }
  1174. template<typename BasicJsonType>
  1175. void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
  1176. {
  1177. arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
  1178. }
  1179. template <typename BasicJsonType, typename T, std::size_t N>
  1180. auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
  1181. priority_tag<2> /*unused*/)
  1182. -> decltype(j.template get<T>(), void())
  1183. {
  1184. for (std::size_t i = 0; i < N; ++i)
  1185. {
  1186. arr[i] = j.at(i).template get<T>();
  1187. }
  1188. }
  1189. template<typename BasicJsonType, typename ConstructibleArrayType>
  1190. auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
  1191. -> decltype(
  1192. arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
  1193. j.template get<typename ConstructibleArrayType::value_type>(),
  1194. void())
  1195. {
  1196. using std::end;
  1197. arr.reserve(j.size());
  1198. std::transform(j.begin(), j.end(),
  1199. std::inserter(arr, end(arr)), [](const BasicJsonType & i)
  1200. {
  1201. // get<BasicJsonType>() returns *this, this won't call a from_json
  1202. // method when value_type is BasicJsonType
  1203. return i.template get<typename ConstructibleArrayType::value_type>();
  1204. });
  1205. }
  1206. template <typename BasicJsonType, typename ConstructibleArrayType>
  1207. void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
  1208. priority_tag<0> /*unused*/)
  1209. {
  1210. using std::end;
  1211. std::transform(
  1212. j.begin(), j.end(), std::inserter(arr, end(arr)),
  1213. [](const BasicJsonType & i)
  1214. {
  1215. // get<BasicJsonType>() returns *this, this won't call a from_json
  1216. // method when value_type is BasicJsonType
  1217. return i.template get<typename ConstructibleArrayType::value_type>();
  1218. });
  1219. }
  1220. template <typename BasicJsonType, typename ConstructibleArrayType,
  1221. enable_if_t <
  1222. is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
  1223. not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
  1224. not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
  1225. not is_basic_json<ConstructibleArrayType>::value,
  1226. int > = 0 >
  1227. auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
  1228. -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
  1229. j.template get<typename ConstructibleArrayType::value_type>(),
  1230. void())
  1231. {
  1232. if (JSON_UNLIKELY(not j.is_array()))
  1233. {
  1234. JSON_THROW(type_error::create(302, "type must be array, but is " +
  1235. std::string(j.type_name())));
  1236. }
  1237. from_json_array_impl(j, arr, priority_tag<3> {});
  1238. }
  1239. template<typename BasicJsonType, typename ConstructibleObjectType,
  1240. enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
  1241. void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
  1242. {
  1243. if (JSON_UNLIKELY(not j.is_object()))
  1244. {
  1245. JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
  1246. }
  1247. auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
  1248. using value_type = typename ConstructibleObjectType::value_type;
  1249. std::transform(
  1250. inner_object->begin(), inner_object->end(),
  1251. std::inserter(obj, obj.begin()),
  1252. [](typename BasicJsonType::object_t::value_type const & p)
  1253. {
  1254. return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
  1255. });
  1256. }
  1257. // overload for arithmetic types, not chosen for basic_json template arguments
  1258. // (BooleanType, etc..); note: Is it really necessary to provide explicit
  1259. // overloads for boolean_t etc. in case of a custom BooleanType which is not
  1260. // an arithmetic type?
  1261. template<typename BasicJsonType, typename ArithmeticType,
  1262. enable_if_t <
  1263. std::is_arithmetic<ArithmeticType>::value and
  1264. not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
  1265. not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
  1266. not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
  1267. not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
  1268. int> = 0>
  1269. void from_json(const BasicJsonType& j, ArithmeticType& val)
  1270. {
  1271. switch (static_cast<value_t>(j))
  1272. {
  1273. case value_t::number_unsigned:
  1274. {
  1275. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
  1276. break;
  1277. }
  1278. case value_t::number_integer:
  1279. {
  1280. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
  1281. break;
  1282. }
  1283. case value_t::number_float:
  1284. {
  1285. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
  1286. break;
  1287. }
  1288. case value_t::boolean:
  1289. {
  1290. val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
  1291. break;
  1292. }
  1293. default:
  1294. JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
  1295. }
  1296. }
  1297. template<typename BasicJsonType, typename A1, typename A2>
  1298. void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
  1299. {
  1300. p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
  1301. }
  1302. template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
  1303. void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
  1304. {
  1305. t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
  1306. }
  1307. template<typename BasicJsonType, typename... Args>
  1308. void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
  1309. {
  1310. from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
  1311. }
  1312. template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
  1313. typename = enable_if_t<not std::is_constructible<
  1314. typename BasicJsonType::string_t, Key>::value>>
  1315. void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
  1316. {
  1317. if (JSON_UNLIKELY(not j.is_array()))
  1318. {
  1319. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
  1320. }
  1321. for (const auto& p : j)
  1322. {
  1323. if (JSON_UNLIKELY(not p.is_array()))
  1324. {
  1325. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
  1326. }
  1327. m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
  1328. }
  1329. }
  1330. template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
  1331. typename = enable_if_t<not std::is_constructible<
  1332. typename BasicJsonType::string_t, Key>::value>>
  1333. void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
  1334. {
  1335. if (JSON_UNLIKELY(not j.is_array()))
  1336. {
  1337. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
  1338. }
  1339. for (const auto& p : j)
  1340. {
  1341. if (JSON_UNLIKELY(not p.is_array()))
  1342. {
  1343. JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
  1344. }
  1345. m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
  1346. }
  1347. }
  1348. struct from_json_fn
  1349. {
  1350. template<typename BasicJsonType, typename T>
  1351. auto operator()(const BasicJsonType& j, T& val) const
  1352. noexcept(noexcept(from_json(j, val)))
  1353. -> decltype(from_json(j, val), void())
  1354. {
  1355. return from_json(j, val);
  1356. }
  1357. };
  1358. } // namespace detail
  1359. /// namespace to hold default `from_json` function
  1360. /// to see why this is required:
  1361. /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
  1362. namespace
  1363. {
  1364. constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
  1365. } // namespace
  1366. } // namespace nlohmann
  1367. // #include <nlohmann/detail/conversions/to_json.hpp>
  1368. #include <ciso646> // or, and, not
  1369. #include <iterator> // begin, end
  1370. #include <tuple> // tuple, get
  1371. #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
  1372. #include <utility> // move, forward, declval, pair
  1373. #include <valarray> // valarray
  1374. #include <vector> // vector
  1375. // #include <nlohmann/detail/meta/cpp_future.hpp>
  1376. // #include <nlohmann/detail/meta/type_traits.hpp>
  1377. // #include <nlohmann/detail/value_t.hpp>
  1378. // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
  1379. #include <cstddef> // size_t
  1380. #include <string> // string, to_string
  1381. #include <iterator> // input_iterator_tag
  1382. #include <tuple> // tuple_size, get, tuple_element
  1383. // #include <nlohmann/detail/value_t.hpp>
  1384. // #include <nlohmann/detail/meta/type_traits.hpp>
  1385. namespace nlohmann
  1386. {
  1387. namespace detail
  1388. {
  1389. template <typename IteratorType> class iteration_proxy_value
  1390. {
  1391. public:
  1392. using difference_type = std::ptrdiff_t;
  1393. using value_type = iteration_proxy_value;
  1394. using pointer = value_type * ;
  1395. using reference = value_type & ;
  1396. using iterator_category = std::input_iterator_tag;
  1397. private:
  1398. /// the iterator
  1399. IteratorType anchor;
  1400. /// an index for arrays (used to create key names)
  1401. std::size_t array_index = 0;
  1402. /// last stringified array index
  1403. mutable std::size_t array_index_last = 0;
  1404. /// a string representation of the array index
  1405. mutable std::string array_index_str = "0";
  1406. /// an empty string (to return a reference for primitive values)
  1407. const std::string empty_str = "";
  1408. public:
  1409. explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
  1410. /// dereference operator (needed for range-based for)
  1411. iteration_proxy_value& operator*()
  1412. {
  1413. return *this;
  1414. }
  1415. /// increment operator (needed for range-based for)
  1416. iteration_proxy_value& operator++()
  1417. {
  1418. ++anchor;
  1419. ++array_index;
  1420. return *this;
  1421. }
  1422. /// equality operator (needed for InputIterator)
  1423. bool operator==(const iteration_proxy_value& o) const noexcept
  1424. {
  1425. return anchor == o.anchor;
  1426. }
  1427. /// inequality operator (needed for range-based for)
  1428. bool operator!=(const iteration_proxy_value& o) const noexcept
  1429. {
  1430. return anchor != o.anchor;
  1431. }
  1432. /// return key of the iterator
  1433. const std::string& key() const
  1434. {
  1435. assert(anchor.m_object != nullptr);
  1436. switch (anchor.m_object->type())
  1437. {
  1438. // use integer array index as key
  1439. case value_t::array:
  1440. {
  1441. if (array_index != array_index_last)
  1442. {
  1443. array_index_str = std::to_string(array_index);
  1444. array_index_last = array_index;
  1445. }
  1446. return array_index_str;
  1447. }
  1448. // use key from the object
  1449. case value_t::object:
  1450. return anchor.key();
  1451. // use an empty key for all primitive types
  1452. default:
  1453. return empty_str;
  1454. }
  1455. }
  1456. /// return value of the iterator
  1457. typename IteratorType::reference value() const
  1458. {
  1459. return anchor.value();
  1460. }
  1461. };
  1462. /// proxy class for the items() function
  1463. template<typename IteratorType> class iteration_proxy
  1464. {
  1465. private:
  1466. /// the container to iterate
  1467. typename IteratorType::reference container;
  1468. public:
  1469. /// construct iteration proxy from a container
  1470. explicit iteration_proxy(typename IteratorType::reference cont) noexcept
  1471. : container(cont) {}
  1472. /// return iterator begin (needed for range-based for)
  1473. iteration_proxy_value<IteratorType> begin() noexcept
  1474. {
  1475. return iteration_proxy_value<IteratorType>(container.begin());
  1476. }
  1477. /// return iterator end (needed for range-based for)
  1478. iteration_proxy_value<IteratorType> end() noexcept
  1479. {
  1480. return iteration_proxy_value<IteratorType>(container.end());
  1481. }
  1482. };
  1483. // Structured Bindings Support
  1484. // For further reference see https://blog.tartanllama.xyz/structured-bindings/
  1485. // And see https://github.com/nlohmann/json/pull/1391
  1486. template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
  1487. auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
  1488. {
  1489. return i.key();
  1490. }
  1491. // Structured Bindings Support
  1492. // For further reference see https://blog.tartanllama.xyz/structured-bindings/
  1493. // And see https://github.com/nlohmann/json/pull/1391
  1494. template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
  1495. auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
  1496. {
  1497. return i.value();
  1498. }
  1499. } // namespace detail
  1500. } // namespace nlohmann
  1501. // The Addition to the STD Namespace is required to add
  1502. // Structured Bindings Support to the iteration_proxy_value class
  1503. // For further reference see https://blog.tartanllama.xyz/structured-bindings/
  1504. // And see https://github.com/nlohmann/json/pull/1391
  1505. namespace std
  1506. {
  1507. template <typename IteratorType>
  1508. class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
  1509. : public std::integral_constant<std::size_t, 2> {};
  1510. template <std::size_t N, typename IteratorType>
  1511. class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
  1512. {
  1513. public:
  1514. using type = decltype(
  1515. get<N>(std::declval <
  1516. ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
  1517. };
  1518. }
  1519. namespace nlohmann
  1520. {
  1521. namespace detail
  1522. {
  1523. //////////////////
  1524. // constructors //
  1525. //////////////////
  1526. template<value_t> struct external_constructor;
  1527. template<>
  1528. struct external_constructor<value_t::boolean>
  1529. {
  1530. template<typename BasicJsonType>
  1531. static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
  1532. {
  1533. j.m_type = value_t::boolean;
  1534. j.m_value = b;
  1535. j.assert_invariant();
  1536. }
  1537. };
  1538. template<>
  1539. struct external_constructor<value_t::string>
  1540. {
  1541. template<typename BasicJsonType>
  1542. static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
  1543. {
  1544. j.m_type = value_t::string;
  1545. j.m_value = s;
  1546. j.assert_invariant();
  1547. }
  1548. template<typename BasicJsonType>
  1549. static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
  1550. {
  1551. j.m_type = value_t::string;
  1552. j.m_value = std::move(s);
  1553. j.assert_invariant();
  1554. }
  1555. template<typename BasicJsonType, typename CompatibleStringType,
  1556. enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
  1557. int> = 0>
  1558. static void construct(BasicJsonType& j, const CompatibleStringType& str)
  1559. {
  1560. j.m_type = value_t::string;
  1561. j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
  1562. j.assert_invariant();
  1563. }
  1564. };
  1565. template<>
  1566. struct external_constructor<value_t::number_float>
  1567. {
  1568. template<typename BasicJsonType>
  1569. static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
  1570. {
  1571. j.m_type = value_t::number_float;
  1572. j.m_value = val;
  1573. j.assert_invariant();
  1574. }
  1575. };
  1576. template<>
  1577. struct external_constructor<value_t::number_unsigned>
  1578. {
  1579. template<typename BasicJsonType>
  1580. static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
  1581. {
  1582. j.m_type = value_t::number_unsigned;
  1583. j.m_value = val;
  1584. j.assert_invariant();
  1585. }
  1586. };
  1587. template<>
  1588. struct external_constructor<value_t::number_integer>
  1589. {
  1590. template<typename BasicJsonType>
  1591. static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
  1592. {
  1593. j.m_type = value_t::number_integer;
  1594. j.m_value = val;
  1595. j.assert_invariant();
  1596. }
  1597. };
  1598. template<>
  1599. struct external_constructor<value_t::array>
  1600. {
  1601. template<typename BasicJsonType>
  1602. static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
  1603. {
  1604. j.m_type = value_t::array;
  1605. j.m_value = arr;
  1606. j.assert_invariant();
  1607. }
  1608. template<typename BasicJsonType>
  1609. static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
  1610. {
  1611. j.m_type = value_t::array;
  1612. j.m_value = std::move(arr);
  1613. j.assert_invariant();
  1614. }
  1615. template<typename BasicJsonType, typename CompatibleArrayType,
  1616. enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
  1617. int> = 0>
  1618. static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
  1619. {
  1620. using std::begin;
  1621. using std::end;
  1622. j.m_type = value_t::array;
  1623. j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
  1624. j.assert_invariant();
  1625. }
  1626. template<typename BasicJsonType>
  1627. static void construct(BasicJsonType& j, const std::vector<bool>& arr)
  1628. {
  1629. j.m_type = value_t::array;
  1630. j.m_value = value_t::array;
  1631. j.m_value.array->reserve(arr.size());
  1632. for (const bool x : arr)
  1633. {
  1634. j.m_value.array->push_back(x);
  1635. }
  1636. j.assert_invariant();
  1637. }
  1638. template<typename BasicJsonType, typename T,
  1639. enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
  1640. static void construct(BasicJsonType& j, const std::valarray<T>& arr)
  1641. {
  1642. j.m_type = value_t::array;
  1643. j.m_value = value_t::array;
  1644. j.m_value.array->resize(arr.size());
  1645. std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
  1646. j.assert_invariant();
  1647. }
  1648. };
  1649. template<>
  1650. struct external_constructor<value_t::object>
  1651. {
  1652. template<typename BasicJsonType>
  1653. static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
  1654. {
  1655. j.m_type = value_t::object;
  1656. j.m_value = obj;
  1657. j.assert_invariant();
  1658. }
  1659. template<typename BasicJsonType>
  1660. static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
  1661. {
  1662. j.m_type = value_t::object;
  1663. j.m_value = std::move(obj);
  1664. j.assert_invariant();
  1665. }
  1666. template<typename BasicJsonType, typename CompatibleObjectType,
  1667. enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
  1668. static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
  1669. {
  1670. using std::begin;
  1671. using std::end;
  1672. j.m_type = value_t::object;
  1673. j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
  1674. j.assert_invariant();
  1675. }
  1676. };
  1677. /////////////
  1678. // to_json //
  1679. /////////////
  1680. template<typename BasicJsonType, typename T,
  1681. enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
  1682. void to_json(BasicJsonType& j, T b) noexcept
  1683. {
  1684. external_constructor<value_t::boolean>::construct(j, b);
  1685. }
  1686. template<typename BasicJsonType, typename CompatibleString,
  1687. enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
  1688. void to_json(BasicJsonType& j, const CompatibleString& s)
  1689. {
  1690. external_constructor<value_t::string>::construct(j, s);
  1691. }
  1692. template<typename BasicJsonType>
  1693. void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
  1694. {
  1695. external_constructor<value_t::string>::construct(j, std::move(s));
  1696. }
  1697. template<typename BasicJsonType, typename FloatType,
  1698. enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
  1699. void to_json(BasicJsonType& j, FloatType val) noexcept
  1700. {
  1701. external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
  1702. }
  1703. template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
  1704. enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
  1705. void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
  1706. {
  1707. external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
  1708. }
  1709. template<typename BasicJsonType, typename CompatibleNumberIntegerType,
  1710. enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
  1711. void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
  1712. {
  1713. external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
  1714. }
  1715. template<typename BasicJsonType, typename EnumType,
  1716. enable_if_t<std::is_enum<EnumType>::value, int> = 0>
  1717. void to_json(BasicJsonType& j, EnumType e) noexcept
  1718. {
  1719. using underlying_type = typename std::underlying_type<EnumType>::type;
  1720. external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
  1721. }
  1722. template<typename BasicJsonType>
  1723. void to_json(BasicJsonType& j, const std::vector<bool>& e)
  1724. {
  1725. external_constructor<value_t::array>::construct(j, e);
  1726. }
  1727. template <typename BasicJsonType, typename CompatibleArrayType,
  1728. enable_if_t<is_compatible_array_type<BasicJsonType,
  1729. CompatibleArrayType>::value and
  1730. not is_compatible_object_type<
  1731. BasicJsonType, CompatibleArrayType>::value and
  1732. not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
  1733. not is_basic_json<CompatibleArrayType>::value,
  1734. int> = 0>
  1735. void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
  1736. {
  1737. external_constructor<value_t::array>::construct(j, arr);
  1738. }
  1739. template<typename BasicJsonType, typename T,
  1740. enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
  1741. void to_json(BasicJsonType& j, const std::valarray<T>& arr)
  1742. {
  1743. external_constructor<value_t::array>::construct(j, std::move(arr));
  1744. }
  1745. template<typename BasicJsonType>
  1746. void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
  1747. {
  1748. external_constructor<value_t::array>::construct(j, std::move(arr));
  1749. }
  1750. template<typename BasicJsonType, typename CompatibleObjectType,
  1751. enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
  1752. void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
  1753. {
  1754. external_constructor<value_t::object>::construct(j, obj);
  1755. }
  1756. template<typename BasicJsonType>
  1757. void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
  1758. {
  1759. external_constructor<value_t::object>::construct(j, std::move(obj));
  1760. }
  1761. template <
  1762. typename BasicJsonType, typename T, std::size_t N,
  1763. enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
  1764. const T(&)[N]>::value,
  1765. int> = 0 >
  1766. void to_json(BasicJsonType& j, const T(&arr)[N])
  1767. {
  1768. external_constructor<value_t::array>::construct(j, arr);
  1769. }
  1770. template<typename BasicJsonType, typename... Args>
  1771. void to_json(BasicJsonType& j, const std::pair<Args...>& p)
  1772. {
  1773. j = { p.first, p.second };
  1774. }
  1775. // for https://github.com/nlohmann/json/pull/1134
  1776. template < typename BasicJsonType, typename T,
  1777. enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
  1778. void to_json(BasicJsonType& j, const T& b)
  1779. {
  1780. j = { {b.key(), b.value()} };
  1781. }
  1782. template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
  1783. void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
  1784. {
  1785. j = { std::get<Idx>(t)... };
  1786. }
  1787. template<typename BasicJsonType, typename... Args>
  1788. void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
  1789. {
  1790. to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
  1791. }
  1792. struct to_json_fn
  1793. {
  1794. template<typename BasicJsonType, typename T>
  1795. auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
  1796. -> decltype(to_json(j, std::forward<T>(val)), void())
  1797. {
  1798. return to_json(j, std::forward<T>(val));
  1799. }
  1800. };
  1801. } // namespace detail
  1802. /// namespace to hold default `to_json` function
  1803. namespace
  1804. {
  1805. constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
  1806. } // namespace
  1807. } // namespace nlohmann
  1808. // #include <nlohmann/detail/input/input_adapters.hpp>
  1809. #include <cassert> // assert
  1810. #include <cstddef> // size_t
  1811. #include <cstring> // strlen
  1812. #include <istream> // istream
  1813. #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
  1814. #include <memory> // shared_ptr, make_shared, addressof
  1815. #include <numeric> // accumulate
  1816. #include <string> // string, char_traits
  1817. #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
  1818. #include <utility> // pair, declval
  1819. #include <cstdio> //FILE *
  1820. // #include <nlohmann/detail/macro_scope.hpp>
  1821. namespace nlohmann
  1822. {
  1823. namespace detail
  1824. {
  1825. /// the supported input formats
  1826. enum class input_format_t { json, cbor, msgpack, ubjson, bson };
  1827. ////////////////////
  1828. // input adapters //
  1829. ////////////////////
  1830. /*!
  1831. @brief abstract input adapter interface
  1832. Produces a stream of std::char_traits<char>::int_type characters from a
  1833. std::istream, a buffer, or some other input type. Accepts the return of
  1834. exactly one non-EOF character for future input. The int_type characters
  1835. returned consist of all valid char values as positive values (typically
  1836. unsigned char), plus an EOF value outside that range, specified by the value
  1837. of the function std::char_traits<char>::eof(). This value is typically -1, but
  1838. could be any arbitrary value which is not a valid char value.
  1839. */
  1840. struct input_adapter_protocol
  1841. {
  1842. /// get a character [0,255] or std::char_traits<char>::eof().
  1843. virtual std::char_traits<char>::int_type get_character() = 0;
  1844. virtual ~input_adapter_protocol() = default;
  1845. };
  1846. /// a type to simplify interfaces
  1847. using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
  1848. /*!
  1849. Input adapter for stdio file access. This adapter read only 1 byte and do not use any
  1850. buffer. This adapter is a very low level adapter.
  1851. */
  1852. class file_input_adapter : public input_adapter_protocol
  1853. {
  1854. public:
  1855. explicit file_input_adapter(std::FILE* f) noexcept
  1856. : m_file(f)
  1857. {}
  1858. std::char_traits<char>::int_type get_character() noexcept override
  1859. {
  1860. return std::fgetc(m_file);
  1861. }
  1862. private:
  1863. /// the file pointer to read from
  1864. std::FILE* m_file;
  1865. };
  1866. /*!
  1867. Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
  1868. beginning of input. Does not support changing the underlying std::streambuf
  1869. in mid-input. Maintains underlying std::istream and std::streambuf to support
  1870. subsequent use of standard std::istream operations to process any input
  1871. characters following those used in parsing the JSON input. Clears the
  1872. std::istream flags; any input errors (e.g., EOF) will be detected by the first
  1873. subsequent call for input from the std::istream.
  1874. */
  1875. class input_stream_adapter : public input_adapter_protocol
  1876. {
  1877. public:
  1878. ~input_stream_adapter() override
  1879. {
  1880. // clear stream flags; we use underlying streambuf I/O, do not
  1881. // maintain ifstream flags, except eof
  1882. is.clear(is.rdstate() & std::ios::eofbit);
  1883. }
  1884. explicit input_stream_adapter(std::istream& i)
  1885. : is(i), sb(*i.rdbuf())
  1886. {}
  1887. // delete because of pointer members
  1888. input_stream_adapter(const input_stream_adapter&) = delete;
  1889. input_stream_adapter& operator=(input_stream_adapter&) = delete;
  1890. input_stream_adapter(input_stream_adapter&&) = delete;
  1891. input_stream_adapter& operator=(input_stream_adapter&&) = delete;
  1892. // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
  1893. // ensure that std::char_traits<char>::eof() and the character 0xFF do not
  1894. // end up as the same value, eg. 0xFFFFFFFF.
  1895. std::char_traits<char>::int_type get_character() override
  1896. {
  1897. auto res = sb.sbumpc();
  1898. // set eof manually, as we don't use the istream interface.
  1899. if (res == EOF)
  1900. {
  1901. is.clear(is.rdstate() | std::ios::eofbit);
  1902. }
  1903. return res;
  1904. }
  1905. private:
  1906. /// the associated input stream
  1907. std::istream& is;
  1908. std::streambuf& sb;
  1909. };
  1910. /// input adapter for buffer input
  1911. class input_buffer_adapter : public input_adapter_protocol
  1912. {
  1913. public:
  1914. input_buffer_adapter(const char* b, const std::size_t l) noexcept
  1915. : cursor(b), limit(b + l)
  1916. {}
  1917. // delete because of pointer members
  1918. input_buffer_adapter(const input_buffer_adapter&) = delete;
  1919. input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
  1920. input_buffer_adapter(input_buffer_adapter&&) = delete;
  1921. input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
  1922. ~input_buffer_adapter() override = default;
  1923. std::char_traits<char>::int_type get_character() noexcept override
  1924. {
  1925. if (JSON_LIKELY(cursor < limit))
  1926. {
  1927. return std::char_traits<char>::to_int_type(*(cursor++));
  1928. }
  1929. return std::char_traits<char>::eof();
  1930. }
  1931. private:
  1932. /// pointer to the current character
  1933. const char* cursor;
  1934. /// pointer past the last character
  1935. const char* const limit;
  1936. };
  1937. template<typename WideStringType, size_t T>
  1938. struct wide_string_input_helper
  1939. {
  1940. // UTF-32
  1941. static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
  1942. {
  1943. utf8_bytes_index = 0;
  1944. if (current_wchar == str.size())
  1945. {
  1946. utf8_bytes[0] = std::char_traits<char>::eof();
  1947. utf8_bytes_filled = 1;
  1948. }
  1949. else
  1950. {
  1951. // get the current character
  1952. const auto wc = static_cast<int>(str[current_wchar++]);
  1953. // UTF-32 to UTF-8 encoding
  1954. if (wc < 0x80)
  1955. {
  1956. utf8_bytes[0] = wc;
  1957. utf8_bytes_filled = 1;
  1958. }
  1959. else if (wc <= 0x7FF)
  1960. {
  1961. utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
  1962. utf8_bytes[1] = 0x80 | (wc & 0x3F);
  1963. utf8_bytes_filled = 2;
  1964. }
  1965. else if (wc <= 0xFFFF)
  1966. {
  1967. utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
  1968. utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
  1969. utf8_bytes[2] = 0x80 | (wc & 0x3F);
  1970. utf8_bytes_filled = 3;
  1971. }
  1972. else if (wc <= 0x10FFFF)
  1973. {
  1974. utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
  1975. utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
  1976. utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
  1977. utf8_bytes[3] = 0x80 | (wc & 0x3F);
  1978. utf8_bytes_filled = 4;
  1979. }
  1980. else
  1981. {
  1982. // unknown character
  1983. utf8_bytes[0] = wc;
  1984. utf8_bytes_filled = 1;
  1985. }
  1986. }
  1987. }
  1988. };
  1989. template<typename WideStringType>
  1990. struct wide_string_input_helper<WideStringType, 2>
  1991. {
  1992. // UTF-16
  1993. static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
  1994. {
  1995. utf8_bytes_index = 0;
  1996. if (current_wchar == str.size())
  1997. {
  1998. utf8_bytes[0] = std::char_traits<char>::eof();
  1999. utf8_bytes_filled = 1;
  2000. }
  2001. else
  2002. {
  2003. // get the current character
  2004. const auto wc = static_cast<int>(str[current_wchar++]);
  2005. // UTF-16 to UTF-8 encoding
  2006. if (wc < 0x80)
  2007. {
  2008. utf8_bytes[0] = wc;
  2009. utf8_bytes_filled = 1;
  2010. }
  2011. else if (wc <= 0x7FF)
  2012. {
  2013. utf8_bytes[0] = 0xC0 | ((wc >> 6));
  2014. utf8_bytes[1] = 0x80 | (wc & 0x3F);
  2015. utf8_bytes_filled = 2;
  2016. }
  2017. else if (0xD800 > wc or wc >= 0xE000)
  2018. {
  2019. utf8_bytes[0] = 0xE0 | ((wc >> 12));
  2020. utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
  2021. utf8_bytes[2] = 0x80 | (wc & 0x3F);
  2022. utf8_bytes_filled = 3;
  2023. }
  2024. else
  2025. {
  2026. if (current_wchar < str.size())
  2027. {
  2028. const auto wc2 = static_cast<int>(str[current_wchar++]);
  2029. const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
  2030. utf8_bytes[0] = 0xf0 | (charcode >> 18);
  2031. utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
  2032. utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
  2033. utf8_bytes[3] = 0x80 | (charcode & 0x3F);
  2034. utf8_bytes_filled = 4;
  2035. }
  2036. else
  2037. {
  2038. // unknown character
  2039. ++current_wchar;
  2040. utf8_bytes[0] = wc;
  2041. utf8_bytes_filled = 1;
  2042. }
  2043. }
  2044. }
  2045. }
  2046. };
  2047. template<typename WideStringType>
  2048. class wide_string_input_adapter : public input_adapter_protocol
  2049. {
  2050. public:
  2051. explicit wide_string_input_adapter(const WideStringType& w) noexcept
  2052. : str(w)
  2053. {}
  2054. std::char_traits<char>::int_type get_character() noexcept override
  2055. {
  2056. // check if buffer needs to be filled
  2057. if (utf8_bytes_index == utf8_bytes_filled)
  2058. {
  2059. fill_buffer<sizeof(typename WideStringType::value_type)>();
  2060. assert(utf8_bytes_filled > 0);
  2061. assert(utf8_bytes_index == 0);
  2062. }
  2063. // use buffer
  2064. assert(utf8_bytes_filled > 0);
  2065. assert(utf8_bytes_index < utf8_bytes_filled);
  2066. return utf8_bytes[utf8_bytes_index++];
  2067. }
  2068. private:
  2069. template<size_t T>
  2070. void fill_buffer()
  2071. {
  2072. wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
  2073. }
  2074. /// the wstring to process
  2075. const WideStringType& str;
  2076. /// index of the current wchar in str
  2077. std::size_t current_wchar = 0;
  2078. /// a buffer for UTF-8 bytes
  2079. std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
  2080. /// index to the utf8_codes array for the next valid byte
  2081. std::size_t utf8_bytes_index = 0;
  2082. /// number of valid bytes in the utf8_codes array
  2083. std::size_t utf8_bytes_filled = 0;
  2084. };
  2085. class input_adapter
  2086. {
  2087. public:
  2088. // native support
  2089. input_adapter(std::FILE* file)
  2090. : ia(std::make_shared<file_input_adapter>(file)) {}
  2091. /// input adapter for input stream
  2092. input_adapter(std::istream& i)
  2093. : ia(std::make_shared<input_stream_adapter>(i)) {}
  2094. /// input adapter for input stream
  2095. input_adapter(std::istream&& i)
  2096. : ia(std::make_shared<input_stream_adapter>(i)) {}
  2097. input_adapter(const std::wstring& ws)
  2098. : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
  2099. input_adapter(const std::u16string& ws)
  2100. : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
  2101. input_adapter(const std::u32string& ws)
  2102. : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
  2103. /// input adapter for buffer
  2104. template<typename CharT,
  2105. typename std::enable_if<
  2106. std::is_pointer<CharT>::value and
  2107. std::is_integral<typename std::remove_pointer<CharT>::type>::value and
  2108. sizeof(typename std::remove_pointer<CharT>::type) == 1,
  2109. int>::type = 0>
  2110. input_adapter(CharT b, std::size_t l)
  2111. : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
  2112. // derived support
  2113. /// input adapter for string literal
  2114. template<typename CharT,
  2115. typename std::enable_if<
  2116. std::is_pointer<CharT>::value and
  2117. std::is_integral<typename std::remove_pointer<CharT>::type>::value and
  2118. sizeof(typename std::remove_pointer<CharT>::type) == 1,
  2119. int>::type = 0>
  2120. input_adapter(CharT b)
  2121. : input_adapter(reinterpret_cast<const char*>(b),
  2122. std::strlen(reinterpret_cast<const char*>(b))) {}
  2123. /// input adapter for iterator range with contiguous storage
  2124. template<class IteratorType,
  2125. typename std::enable_if<
  2126. std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
  2127. int>::type = 0>
  2128. input_adapter(IteratorType first, IteratorType last)
  2129. {
  2130. #ifndef NDEBUG
  2131. // assertion to check that the iterator range is indeed contiguous,
  2132. // see http://stackoverflow.com/a/35008842/266378 for more discussion
  2133. const auto is_contiguous = std::accumulate(
  2134. first, last, std::pair<bool, int>(true, 0),
  2135. [&first](std::pair<bool, int> res, decltype(*first) val)
  2136. {
  2137. res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
  2138. return res;
  2139. }).first;
  2140. assert(is_contiguous);
  2141. #endif
  2142. // assertion to check that each element is 1 byte long
  2143. static_assert(
  2144. sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
  2145. "each element in the iterator range must have the size of 1 byte");
  2146. const auto len = static_cast<size_t>(std::distance(first, last));
  2147. if (JSON_LIKELY(len > 0))
  2148. {
  2149. // there is at least one element: use the address of first
  2150. ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
  2151. }
  2152. else
  2153. {
  2154. // the address of first cannot be used: use nullptr
  2155. ia = std::make_shared<input_buffer_adapter>(nullptr, len);
  2156. }
  2157. }
  2158. /// input adapter for array
  2159. template<class T, std::size_t N>
  2160. input_adapter(T (&array)[N])
  2161. : input_adapter(std::begin(array), std::end(array)) {}
  2162. /// input adapter for contiguous container
  2163. template<class ContiguousContainer, typename
  2164. std::enable_if<not std::is_pointer<ContiguousContainer>::value and
  2165. std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
  2166. int>::type = 0>
  2167. input_adapter(const ContiguousContainer& c)
  2168. : input_adapter(std::begin(c), std::end(c)) {}
  2169. operator input_adapter_t()
  2170. {
  2171. return ia;
  2172. }
  2173. private:
  2174. /// the actual adapter
  2175. input_adapter_t ia = nullptr;
  2176. };
  2177. } // namespace detail
  2178. } // namespace nlohmann
  2179. // #include <nlohmann/detail/input/lexer.hpp>
  2180. #include <clocale> // localeconv
  2181. #include <cstddef> // size_t
  2182. #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
  2183. #include <cstdio> // snprintf
  2184. #include <initializer_list> // initializer_list
  2185. #include <string> // char_traits, string
  2186. #include <vector> // vector
  2187. // #include <nlohmann/detail/macro_scope.hpp>
  2188. // #include <nlohmann/detail/input/input_adapters.hpp>
  2189. // #include <nlohmann/detail/input/position_t.hpp>
  2190. namespace nlohmann
  2191. {
  2192. namespace detail
  2193. {
  2194. ///////////
  2195. // lexer //
  2196. ///////////
  2197. /*!
  2198. @brief lexical analysis
  2199. This class organizes the lexical analysis during JSON deserialization.
  2200. */
  2201. template<typename BasicJsonType>
  2202. class lexer
  2203. {
  2204. using number_integer_t = typename BasicJsonType::number_integer_t;
  2205. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  2206. using number_float_t = typename BasicJsonType::number_float_t;
  2207. using string_t = typename BasicJsonType::string_t;
  2208. public:
  2209. /// token types for the parser
  2210. enum class token_type
  2211. {
  2212. uninitialized, ///< indicating the scanner is uninitialized
  2213. literal_true, ///< the `true` literal
  2214. literal_false, ///< the `false` literal
  2215. literal_null, ///< the `null` literal
  2216. value_string, ///< a string -- use get_string() for actual value
  2217. value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
  2218. value_integer, ///< a signed integer -- use get_number_integer() for actual value
  2219. value_float, ///< an floating point number -- use get_number_float() for actual value
  2220. begin_array, ///< the character for array begin `[`
  2221. begin_object, ///< the character for object begin `{`
  2222. end_array, ///< the character for array end `]`
  2223. end_object, ///< the character for object end `}`
  2224. name_separator, ///< the name separator `:`
  2225. value_separator, ///< the value separator `,`
  2226. parse_error, ///< indicating a parse error
  2227. end_of_input, ///< indicating the end of the input buffer
  2228. literal_or_value ///< a literal or the begin of a value (only for diagnostics)
  2229. };
  2230. /// return name of values of type token_type (only used for errors)
  2231. static const char* token_type_name(const token_type t) noexcept
  2232. {
  2233. switch (t)
  2234. {
  2235. case token_type::uninitialized:
  2236. return "<uninitialized>";
  2237. case token_type::literal_true:
  2238. return "true literal";
  2239. case token_type::literal_false:
  2240. return "false literal";
  2241. case token_type::literal_null:
  2242. return "null literal";
  2243. case token_type::value_string:
  2244. return "string literal";
  2245. case lexer::token_type::value_unsigned:
  2246. case lexer::token_type::value_integer:
  2247. case lexer::token_type::value_float:
  2248. return "number literal";
  2249. case token_type::begin_array:
  2250. return "'['";
  2251. case token_type::begin_object:
  2252. return "'{'";
  2253. case token_type::end_array:
  2254. return "']'";
  2255. case token_type::end_object:
  2256. return "'}'";
  2257. case token_type::name_separator:
  2258. return "':'";
  2259. case token_type::value_separator:
  2260. return "','";
  2261. case token_type::parse_error:
  2262. return "<parse error>";
  2263. case token_type::end_of_input:
  2264. return "end of input";
  2265. case token_type::literal_or_value:
  2266. return "'[', '{', or a literal";
  2267. // LCOV_EXCL_START
  2268. default: // catch non-enum values
  2269. return "unknown token";
  2270. // LCOV_EXCL_STOP
  2271. }
  2272. }
  2273. explicit lexer(detail::input_adapter_t&& adapter)
  2274. : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
  2275. // delete because of pointer members
  2276. lexer(const lexer&) = delete;
  2277. lexer(lexer&&) = delete;
  2278. lexer& operator=(lexer&) = delete;
  2279. lexer& operator=(lexer&&) = delete;
  2280. ~lexer() = default;
  2281. private:
  2282. /////////////////////
  2283. // locales
  2284. /////////////////////
  2285. /// return the locale-dependent decimal point
  2286. static char get_decimal_point() noexcept
  2287. {
  2288. const auto loc = localeconv();
  2289. assert(loc != nullptr);
  2290. return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
  2291. }
  2292. /////////////////////
  2293. // scan functions
  2294. /////////////////////
  2295. /*!
  2296. @brief get codepoint from 4 hex characters following `\u`
  2297. For input "\u c1 c2 c3 c4" the codepoint is:
  2298. (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
  2299. = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
  2300. Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
  2301. must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
  2302. conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
  2303. between the ASCII value of the character and the desired integer value.
  2304. @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
  2305. non-hex character)
  2306. */
  2307. int get_codepoint()
  2308. {
  2309. // this function only makes sense after reading `\u`
  2310. assert(current == 'u');
  2311. int codepoint = 0;
  2312. const auto factors = { 12, 8, 4, 0 };
  2313. for (const auto factor : factors)
  2314. {
  2315. get();
  2316. if (current >= '0' and current <= '9')
  2317. {
  2318. codepoint += ((current - 0x30) << factor);
  2319. }
  2320. else if (current >= 'A' and current <= 'F')
  2321. {
  2322. codepoint += ((current - 0x37) << factor);
  2323. }
  2324. else if (current >= 'a' and current <= 'f')
  2325. {
  2326. codepoint += ((current - 0x57) << factor);
  2327. }
  2328. else
  2329. {
  2330. return -1;
  2331. }
  2332. }
  2333. assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
  2334. return codepoint;
  2335. }
  2336. /*!
  2337. @brief check if the next byte(s) are inside a given range
  2338. Adds the current byte and, for each passed range, reads a new byte and
  2339. checks if it is inside the range. If a violation was detected, set up an
  2340. error message and return false. Otherwise, return true.
  2341. @param[in] ranges list of integers; interpreted as list of pairs of
  2342. inclusive lower and upper bound, respectively
  2343. @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
  2344. 1, 2, or 3 pairs. This precondition is enforced by an assertion.
  2345. @return true if and only if no range violation was detected
  2346. */
  2347. bool next_byte_in_range(std::initializer_list<int> ranges)
  2348. {
  2349. assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
  2350. add(current);
  2351. for (auto range = ranges.begin(); range != ranges.end(); ++range)
  2352. {
  2353. get();
  2354. if (JSON_LIKELY(*range <= current and current <= *(++range)))
  2355. {
  2356. add(current);
  2357. }
  2358. else
  2359. {
  2360. error_message = "invalid string: ill-formed UTF-8 byte";
  2361. return false;
  2362. }
  2363. }
  2364. return true;
  2365. }
  2366. /*!
  2367. @brief scan a string literal
  2368. This function scans a string according to Sect. 7 of RFC 7159. While
  2369. scanning, bytes are escaped and copied into buffer token_buffer. Then the
  2370. function returns successfully, token_buffer is *not* null-terminated (as it
  2371. may contain \0 bytes), and token_buffer.size() is the number of bytes in the
  2372. string.
  2373. @return token_type::value_string if string could be successfully scanned,
  2374. token_type::parse_error otherwise
  2375. @note In case of errors, variable error_message contains a textual
  2376. description.
  2377. */
  2378. token_type scan_string()
  2379. {
  2380. // reset token_buffer (ignore opening quote)
  2381. reset();
  2382. // we entered the function by reading an open quote
  2383. assert(current == '\"');
  2384. while (true)
  2385. {
  2386. // get next character
  2387. switch (get())
  2388. {
  2389. // end of file while parsing string
  2390. case std::char_traits<char>::eof():
  2391. {
  2392. error_message = "invalid string: missing closing quote";
  2393. return token_type::parse_error;
  2394. }
  2395. // closing quote
  2396. case '\"':
  2397. {
  2398. return token_type::value_string;
  2399. }
  2400. // escapes
  2401. case '\\':
  2402. {
  2403. switch (get())
  2404. {
  2405. // quotation mark
  2406. case '\"':
  2407. add('\"');
  2408. break;
  2409. // reverse solidus
  2410. case '\\':
  2411. add('\\');
  2412. break;
  2413. // solidus
  2414. case '/':
  2415. add('/');
  2416. break;
  2417. // backspace
  2418. case 'b':
  2419. add('\b');
  2420. break;
  2421. // form feed
  2422. case 'f':
  2423. add('\f');
  2424. break;
  2425. // line feed
  2426. case 'n':
  2427. add('\n');
  2428. break;
  2429. // carriage return
  2430. case 'r':
  2431. add('\r');
  2432. break;
  2433. // tab
  2434. case 't':
  2435. add('\t');
  2436. break;
  2437. // unicode escapes
  2438. case 'u':
  2439. {
  2440. const int codepoint1 = get_codepoint();
  2441. int codepoint = codepoint1; // start with codepoint1
  2442. if (JSON_UNLIKELY(codepoint1 == -1))
  2443. {
  2444. error_message = "invalid string: '\\u' must be followed by 4 hex digits";
  2445. return token_type::parse_error;
  2446. }
  2447. // check if code point is a high surrogate
  2448. if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
  2449. {
  2450. // expect next \uxxxx entry
  2451. if (JSON_LIKELY(get() == '\\' and get() == 'u'))
  2452. {
  2453. const int codepoint2 = get_codepoint();
  2454. if (JSON_UNLIKELY(codepoint2 == -1))
  2455. {
  2456. error_message = "invalid string: '\\u' must be followed by 4 hex digits";
  2457. return token_type::parse_error;
  2458. }
  2459. // check if codepoint2 is a low surrogate
  2460. if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
  2461. {
  2462. // overwrite codepoint
  2463. codepoint =
  2464. // high surrogate occupies the most significant 22 bits
  2465. (codepoint1 << 10)
  2466. // low surrogate occupies the least significant 15 bits
  2467. + codepoint2
  2468. // there is still the 0xD800, 0xDC00 and 0x10000 noise
  2469. // in the result so we have to subtract with:
  2470. // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
  2471. - 0x35FDC00;
  2472. }
  2473. else
  2474. {
  2475. error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
  2476. return token_type::parse_error;
  2477. }
  2478. }
  2479. else
  2480. {
  2481. error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
  2482. return token_type::parse_error;
  2483. }
  2484. }
  2485. else
  2486. {
  2487. if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
  2488. {
  2489. error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
  2490. return token_type::parse_error;
  2491. }
  2492. }
  2493. // result of the above calculation yields a proper codepoint
  2494. assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
  2495. // translate codepoint into bytes
  2496. if (codepoint < 0x80)
  2497. {
  2498. // 1-byte characters: 0xxxxxxx (ASCII)
  2499. add(codepoint);
  2500. }
  2501. else if (codepoint <= 0x7FF)
  2502. {
  2503. // 2-byte characters: 110xxxxx 10xxxxxx
  2504. add(0xC0 | (codepoint >> 6));
  2505. add(0x80 | (codepoint & 0x3F));
  2506. }
  2507. else if (codepoint <= 0xFFFF)
  2508. {
  2509. // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
  2510. add(0xE0 | (codepoint >> 12));
  2511. add(0x80 | ((codepoint >> 6) & 0x3F));
  2512. add(0x80 | (codepoint & 0x3F));
  2513. }
  2514. else
  2515. {
  2516. // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  2517. add(0xF0 | (codepoint >> 18));
  2518. add(0x80 | ((codepoint >> 12) & 0x3F));
  2519. add(0x80 | ((codepoint >> 6) & 0x3F));
  2520. add(0x80 | (codepoint & 0x3F));
  2521. }
  2522. break;
  2523. }
  2524. // other characters after escape
  2525. default:
  2526. error_message = "invalid string: forbidden character after backslash";
  2527. return token_type::parse_error;
  2528. }
  2529. break;
  2530. }
  2531. // invalid control characters
  2532. case 0x00:
  2533. {
  2534. error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
  2535. return token_type::parse_error;
  2536. }
  2537. case 0x01:
  2538. {
  2539. error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
  2540. return token_type::parse_error;
  2541. }
  2542. case 0x02:
  2543. {
  2544. error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
  2545. return token_type::parse_error;
  2546. }
  2547. case 0x03:
  2548. {
  2549. error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
  2550. return token_type::parse_error;
  2551. }
  2552. case 0x04:
  2553. {
  2554. error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
  2555. return token_type::parse_error;
  2556. }
  2557. case 0x05:
  2558. {
  2559. error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
  2560. return token_type::parse_error;
  2561. }
  2562. case 0x06:
  2563. {
  2564. error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
  2565. return token_type::parse_error;
  2566. }
  2567. case 0x07:
  2568. {
  2569. error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
  2570. return token_type::parse_error;
  2571. }
  2572. case 0x08:
  2573. {
  2574. error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
  2575. return token_type::parse_error;
  2576. }
  2577. case 0x09:
  2578. {
  2579. error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
  2580. return token_type::parse_error;
  2581. }
  2582. case 0x0A:
  2583. {
  2584. error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
  2585. return token_type::parse_error;
  2586. }
  2587. case 0x0B:
  2588. {
  2589. error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
  2590. return token_type::parse_error;
  2591. }
  2592. case 0x0C:
  2593. {
  2594. error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
  2595. return token_type::parse_error;
  2596. }
  2597. case 0x0D:
  2598. {
  2599. error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
  2600. return token_type::parse_error;
  2601. }
  2602. case 0x0E:
  2603. {
  2604. error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
  2605. return token_type::parse_error;
  2606. }
  2607. case 0x0F:
  2608. {
  2609. error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
  2610. return token_type::parse_error;
  2611. }
  2612. case 0x10:
  2613. {
  2614. error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
  2615. return token_type::parse_error;
  2616. }
  2617. case 0x11:
  2618. {
  2619. error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
  2620. return token_type::parse_error;
  2621. }
  2622. case 0x12:
  2623. {
  2624. error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
  2625. return token_type::parse_error;
  2626. }
  2627. case 0x13:
  2628. {
  2629. error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
  2630. return token_type::parse_error;
  2631. }
  2632. case 0x14:
  2633. {
  2634. error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
  2635. return token_type::parse_error;
  2636. }
  2637. case 0x15:
  2638. {
  2639. error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
  2640. return token_type::parse_error;
  2641. }
  2642. case 0x16:
  2643. {
  2644. error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
  2645. return token_type::parse_error;
  2646. }
  2647. case 0x17:
  2648. {
  2649. error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
  2650. return token_type::parse_error;
  2651. }
  2652. case 0x18:
  2653. {
  2654. error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
  2655. return token_type::parse_error;
  2656. }
  2657. case 0x19:
  2658. {
  2659. error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
  2660. return token_type::parse_error;
  2661. }
  2662. case 0x1A:
  2663. {
  2664. error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
  2665. return token_type::parse_error;
  2666. }
  2667. case 0x1B:
  2668. {
  2669. error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
  2670. return token_type::parse_error;
  2671. }
  2672. case 0x1C:
  2673. {
  2674. error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
  2675. return token_type::parse_error;
  2676. }
  2677. case 0x1D:
  2678. {
  2679. error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
  2680. return token_type::parse_error;
  2681. }
  2682. case 0x1E:
  2683. {
  2684. error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
  2685. return token_type::parse_error;
  2686. }
  2687. case 0x1F:
  2688. {
  2689. error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
  2690. return token_type::parse_error;
  2691. }
  2692. // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
  2693. case 0x20:
  2694. case 0x21:
  2695. case 0x23:
  2696. case 0x24:
  2697. case 0x25:
  2698. case 0x26:
  2699. case 0x27:
  2700. case 0x28:
  2701. case 0x29:
  2702. case 0x2A:
  2703. case 0x2B:
  2704. case 0x2C:
  2705. case 0x2D:
  2706. case 0x2E:
  2707. case 0x2F:
  2708. case 0x30:
  2709. case 0x31:
  2710. case 0x32:
  2711. case 0x33:
  2712. case 0x34:
  2713. case 0x35:
  2714. case 0x36:
  2715. case 0x37:
  2716. case 0x38:
  2717. case 0x39:
  2718. case 0x3A:
  2719. case 0x3B:
  2720. case 0x3C:
  2721. case 0x3D:
  2722. case 0x3E:
  2723. case 0x3F:
  2724. case 0x40:
  2725. case 0x41:
  2726. case 0x42:
  2727. case 0x43:
  2728. case 0x44:
  2729. case 0x45:
  2730. case 0x46:
  2731. case 0x47:
  2732. case 0x48:
  2733. case 0x49:
  2734. case 0x4A:
  2735. case 0x4B:
  2736. case 0x4C:
  2737. case 0x4D:
  2738. case 0x4E:
  2739. case 0x4F:
  2740. case 0x50:
  2741. case 0x51:
  2742. case 0x52:
  2743. case 0x53:
  2744. case 0x54:
  2745. case 0x55:
  2746. case 0x56:
  2747. case 0x57:
  2748. case 0x58:
  2749. case 0x59:
  2750. case 0x5A:
  2751. case 0x5B:
  2752. case 0x5D:
  2753. case 0x5E:
  2754. case 0x5F:
  2755. case 0x60:
  2756. case 0x61:
  2757. case 0x62:
  2758. case 0x63:
  2759. case 0x64:
  2760. case 0x65:
  2761. case 0x66:
  2762. case 0x67:
  2763. case 0x68:
  2764. case 0x69:
  2765. case 0x6A:
  2766. case 0x6B:
  2767. case 0x6C:
  2768. case 0x6D:
  2769. case 0x6E:
  2770. case 0x6F:
  2771. case 0x70:
  2772. case 0x71:
  2773. case 0x72:
  2774. case 0x73:
  2775. case 0x74:
  2776. case 0x75:
  2777. case 0x76:
  2778. case 0x77:
  2779. case 0x78:
  2780. case 0x79:
  2781. case 0x7A:
  2782. case 0x7B:
  2783. case 0x7C:
  2784. case 0x7D:
  2785. case 0x7E:
  2786. case 0x7F:
  2787. {
  2788. add(current);
  2789. break;
  2790. }
  2791. // U+0080..U+07FF: bytes C2..DF 80..BF
  2792. case 0xC2:
  2793. case 0xC3:
  2794. case 0xC4:
  2795. case 0xC5:
  2796. case 0xC6:
  2797. case 0xC7:
  2798. case 0xC8:
  2799. case 0xC9:
  2800. case 0xCA:
  2801. case 0xCB:
  2802. case 0xCC:
  2803. case 0xCD:
  2804. case 0xCE:
  2805. case 0xCF:
  2806. case 0xD0:
  2807. case 0xD1:
  2808. case 0xD2:
  2809. case 0xD3:
  2810. case 0xD4:
  2811. case 0xD5:
  2812. case 0xD6:
  2813. case 0xD7:
  2814. case 0xD8:
  2815. case 0xD9:
  2816. case 0xDA:
  2817. case 0xDB:
  2818. case 0xDC:
  2819. case 0xDD:
  2820. case 0xDE:
  2821. case 0xDF:
  2822. {
  2823. if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
  2824. {
  2825. return token_type::parse_error;
  2826. }
  2827. break;
  2828. }
  2829. // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
  2830. case 0xE0:
  2831. {
  2832. if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
  2833. {
  2834. return token_type::parse_error;
  2835. }
  2836. break;
  2837. }
  2838. // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
  2839. // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
  2840. case 0xE1:
  2841. case 0xE2:
  2842. case 0xE3:
  2843. case 0xE4:
  2844. case 0xE5:
  2845. case 0xE6:
  2846. case 0xE7:
  2847. case 0xE8:
  2848. case 0xE9:
  2849. case 0xEA:
  2850. case 0xEB:
  2851. case 0xEC:
  2852. case 0xEE:
  2853. case 0xEF:
  2854. {
  2855. if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
  2856. {
  2857. return token_type::parse_error;
  2858. }
  2859. break;
  2860. }
  2861. // U+D000..U+D7FF: bytes ED 80..9F 80..BF
  2862. case 0xED:
  2863. {
  2864. if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
  2865. {
  2866. return token_type::parse_error;
  2867. }
  2868. break;
  2869. }
  2870. // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
  2871. case 0xF0:
  2872. {
  2873. if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
  2874. {
  2875. return token_type::parse_error;
  2876. }
  2877. break;
  2878. }
  2879. // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
  2880. case 0xF1:
  2881. case 0xF2:
  2882. case 0xF3:
  2883. {
  2884. if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
  2885. {
  2886. return token_type::parse_error;
  2887. }
  2888. break;
  2889. }
  2890. // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
  2891. case 0xF4:
  2892. {
  2893. if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
  2894. {
  2895. return token_type::parse_error;
  2896. }
  2897. break;
  2898. }
  2899. // remaining bytes (80..C1 and F5..FF) are ill-formed
  2900. default:
  2901. {
  2902. error_message = "invalid string: ill-formed UTF-8 byte";
  2903. return token_type::parse_error;
  2904. }
  2905. }
  2906. }
  2907. }
  2908. static void strtof(float& f, const char* str, char** endptr) noexcept
  2909. {
  2910. f = std::strtof(str, endptr);
  2911. }
  2912. static void strtof(double& f, const char* str, char** endptr) noexcept
  2913. {
  2914. f = std::strtod(str, endptr);
  2915. }
  2916. static void strtof(long double& f, const char* str, char** endptr) noexcept
  2917. {
  2918. f = std::strtold(str, endptr);
  2919. }
  2920. /*!
  2921. @brief scan a number literal
  2922. This function scans a string according to Sect. 6 of RFC 7159.
  2923. The function is realized with a deterministic finite state machine derived
  2924. from the grammar described in RFC 7159. Starting in state "init", the
  2925. input is read and used to determined the next state. Only state "done"
  2926. accepts the number. State "error" is a trap state to model errors. In the
  2927. table below, "anything" means any character but the ones listed before.
  2928. state | 0 | 1-9 | e E | + | - | . | anything
  2929. ---------|----------|----------|----------|---------|---------|----------|-----------
  2930. init | zero | any1 | [error] | [error] | minus | [error] | [error]
  2931. minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
  2932. zero | done | done | exponent | done | done | decimal1 | done
  2933. any1 | any1 | any1 | exponent | done | done | decimal1 | done
  2934. decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
  2935. decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
  2936. exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
  2937. sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
  2938. any2 | any2 | any2 | done | done | done | done | done
  2939. The state machine is realized with one label per state (prefixed with
  2940. "scan_number_") and `goto` statements between them. The state machine
  2941. contains cycles, but any cycle can be left when EOF is read. Therefore,
  2942. the function is guaranteed to terminate.
  2943. During scanning, the read bytes are stored in token_buffer. This string is
  2944. then converted to a signed integer, an unsigned integer, or a
  2945. floating-point number.
  2946. @return token_type::value_unsigned, token_type::value_integer, or
  2947. token_type::value_float if number could be successfully scanned,
  2948. token_type::parse_error otherwise
  2949. @note The scanner is independent of the current locale. Internally, the
  2950. locale's decimal point is used instead of `.` to work with the
  2951. locale-dependent converters.
  2952. */
  2953. token_type scan_number() // lgtm [cpp/use-of-goto]
  2954. {
  2955. // reset token_buffer to store the number's bytes
  2956. reset();
  2957. // the type of the parsed number; initially set to unsigned; will be
  2958. // changed if minus sign, decimal point or exponent is read
  2959. token_type number_type = token_type::value_unsigned;
  2960. // state (init): we just found out we need to scan a number
  2961. switch (current)
  2962. {
  2963. case '-':
  2964. {
  2965. add(current);
  2966. goto scan_number_minus;
  2967. }
  2968. case '0':
  2969. {
  2970. add(current);
  2971. goto scan_number_zero;
  2972. }
  2973. case '1':
  2974. case '2':
  2975. case '3':
  2976. case '4':
  2977. case '5':
  2978. case '6':
  2979. case '7':
  2980. case '8':
  2981. case '9':
  2982. {
  2983. add(current);
  2984. goto scan_number_any1;
  2985. }
  2986. // LCOV_EXCL_START
  2987. default:
  2988. {
  2989. // all other characters are rejected outside scan_number()
  2990. assert(false);
  2991. }
  2992. // LCOV_EXCL_STOP
  2993. }
  2994. scan_number_minus:
  2995. // state: we just parsed a leading minus sign
  2996. number_type = token_type::value_integer;
  2997. switch (get())
  2998. {
  2999. case '0':
  3000. {
  3001. add(current);
  3002. goto scan_number_zero;
  3003. }
  3004. case '1':
  3005. case '2':
  3006. case '3':
  3007. case '4':
  3008. case '5':
  3009. case '6':
  3010. case '7':
  3011. case '8':
  3012. case '9':
  3013. {
  3014. add(current);
  3015. goto scan_number_any1;
  3016. }
  3017. default:
  3018. {
  3019. error_message = "invalid number; expected digit after '-'";
  3020. return token_type::parse_error;
  3021. }
  3022. }
  3023. scan_number_zero:
  3024. // state: we just parse a zero (maybe with a leading minus sign)
  3025. switch (get())
  3026. {
  3027. case '.':
  3028. {
  3029. add(decimal_point_char);
  3030. goto scan_number_decimal1;
  3031. }
  3032. case 'e':
  3033. case 'E':
  3034. {
  3035. add(current);
  3036. goto scan_number_exponent;
  3037. }
  3038. default:
  3039. goto scan_number_done;
  3040. }
  3041. scan_number_any1:
  3042. // state: we just parsed a number 0-9 (maybe with a leading minus sign)
  3043. switch (get())
  3044. {
  3045. case '0':
  3046. case '1':
  3047. case '2':
  3048. case '3':
  3049. case '4':
  3050. case '5':
  3051. case '6':
  3052. case '7':
  3053. case '8':
  3054. case '9':
  3055. {
  3056. add(current);
  3057. goto scan_number_any1;
  3058. }
  3059. case '.':
  3060. {
  3061. add(decimal_point_char);
  3062. goto scan_number_decimal1;
  3063. }
  3064. case 'e':
  3065. case 'E':
  3066. {
  3067. add(current);
  3068. goto scan_number_exponent;
  3069. }
  3070. default:
  3071. goto scan_number_done;
  3072. }
  3073. scan_number_decimal1:
  3074. // state: we just parsed a decimal point
  3075. number_type = token_type::value_float;
  3076. switch (get())
  3077. {
  3078. case '0':
  3079. case '1':
  3080. case '2':
  3081. case '3':
  3082. case '4':
  3083. case '5':
  3084. case '6':
  3085. case '7':
  3086. case '8':
  3087. case '9':
  3088. {
  3089. add(current);
  3090. goto scan_number_decimal2;
  3091. }
  3092. default:
  3093. {
  3094. error_message = "invalid number; expected digit after '.'";
  3095. return token_type::parse_error;
  3096. }
  3097. }
  3098. scan_number_decimal2:
  3099. // we just parsed at least one number after a decimal point
  3100. switch (get())
  3101. {
  3102. case '0':
  3103. case '1':
  3104. case '2':
  3105. case '3':
  3106. case '4':
  3107. case '5':
  3108. case '6':
  3109. case '7':
  3110. case '8':
  3111. case '9':
  3112. {
  3113. add(current);
  3114. goto scan_number_decimal2;
  3115. }
  3116. case 'e':
  3117. case 'E':
  3118. {
  3119. add(current);
  3120. goto scan_number_exponent;
  3121. }
  3122. default:
  3123. goto scan_number_done;
  3124. }
  3125. scan_number_exponent:
  3126. // we just parsed an exponent
  3127. number_type = token_type::value_float;
  3128. switch (get())
  3129. {
  3130. case '+':
  3131. case '-':
  3132. {
  3133. add(current);
  3134. goto scan_number_sign;
  3135. }
  3136. case '0':
  3137. case '1':
  3138. case '2':
  3139. case '3':
  3140. case '4':
  3141. case '5':
  3142. case '6':
  3143. case '7':
  3144. case '8':
  3145. case '9':
  3146. {
  3147. add(current);
  3148. goto scan_number_any2;
  3149. }
  3150. default:
  3151. {
  3152. error_message =
  3153. "invalid number; expected '+', '-', or digit after exponent";
  3154. return token_type::parse_error;
  3155. }
  3156. }
  3157. scan_number_sign:
  3158. // we just parsed an exponent sign
  3159. switch (get())
  3160. {
  3161. case '0':
  3162. case '1':
  3163. case '2':
  3164. case '3':
  3165. case '4':
  3166. case '5':
  3167. case '6':
  3168. case '7':
  3169. case '8':
  3170. case '9':
  3171. {
  3172. add(current);
  3173. goto scan_number_any2;
  3174. }
  3175. default:
  3176. {
  3177. error_message = "invalid number; expected digit after exponent sign";
  3178. return token_type::parse_error;
  3179. }
  3180. }
  3181. scan_number_any2:
  3182. // we just parsed a number after the exponent or exponent sign
  3183. switch (get())
  3184. {
  3185. case '0':
  3186. case '1':
  3187. case '2':
  3188. case '3':
  3189. case '4':
  3190. case '5':
  3191. case '6':
  3192. case '7':
  3193. case '8':
  3194. case '9':
  3195. {
  3196. add(current);
  3197. goto scan_number_any2;
  3198. }
  3199. default:
  3200. goto scan_number_done;
  3201. }
  3202. scan_number_done:
  3203. // unget the character after the number (we only read it to know that
  3204. // we are done scanning a number)
  3205. unget();
  3206. char* endptr = nullptr;
  3207. errno = 0;
  3208. // try to parse integers first and fall back to floats
  3209. if (number_type == token_type::value_unsigned)
  3210. {
  3211. const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
  3212. // we checked the number format before
  3213. assert(endptr == token_buffer.data() + token_buffer.size());
  3214. if (errno == 0)
  3215. {
  3216. value_unsigned = static_cast<number_unsigned_t>(x);
  3217. if (value_unsigned == x)
  3218. {
  3219. return token_type::value_unsigned;
  3220. }
  3221. }
  3222. }
  3223. else if (number_type == token_type::value_integer)
  3224. {
  3225. const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
  3226. // we checked the number format before
  3227. assert(endptr == token_buffer.data() + token_buffer.size());
  3228. if (errno == 0)
  3229. {
  3230. value_integer = static_cast<number_integer_t>(x);
  3231. if (value_integer == x)
  3232. {
  3233. return token_type::value_integer;
  3234. }
  3235. }
  3236. }
  3237. // this code is reached if we parse a floating-point number or if an
  3238. // integer conversion above failed
  3239. strtof(value_float, token_buffer.data(), &endptr);
  3240. // we checked the number format before
  3241. assert(endptr == token_buffer.data() + token_buffer.size());
  3242. return token_type::value_float;
  3243. }
  3244. /*!
  3245. @param[in] literal_text the literal text to expect
  3246. @param[in] length the length of the passed literal text
  3247. @param[in] return_type the token type to return on success
  3248. */
  3249. token_type scan_literal(const char* literal_text, const std::size_t length,
  3250. token_type return_type)
  3251. {
  3252. assert(current == literal_text[0]);
  3253. for (std::size_t i = 1; i < length; ++i)
  3254. {
  3255. if (JSON_UNLIKELY(get() != literal_text[i]))
  3256. {
  3257. error_message = "invalid literal";
  3258. return token_type::parse_error;
  3259. }
  3260. }
  3261. return return_type;
  3262. }
  3263. /////////////////////
  3264. // input management
  3265. /////////////////////
  3266. /// reset token_buffer; current character is beginning of token
  3267. void reset() noexcept
  3268. {
  3269. token_buffer.clear();
  3270. token_string.clear();
  3271. token_string.push_back(std::char_traits<char>::to_char_type(current));
  3272. }
  3273. /*
  3274. @brief get next character from the input
  3275. This function provides the interface to the used input adapter. It does
  3276. not throw in case the input reached EOF, but returns a
  3277. `std::char_traits<char>::eof()` in that case. Stores the scanned characters
  3278. for use in error messages.
  3279. @return character read from the input
  3280. */
  3281. std::char_traits<char>::int_type get()
  3282. {
  3283. ++position.chars_read_total;
  3284. ++position.chars_read_current_line;
  3285. if (next_unget)
  3286. {
  3287. // just reset the next_unget variable and work with current
  3288. next_unget = false;
  3289. }
  3290. else
  3291. {
  3292. current = ia->get_character();
  3293. }
  3294. if (JSON_LIKELY(current != std::char_traits<char>::eof()))
  3295. {
  3296. token_string.push_back(std::char_traits<char>::to_char_type(current));
  3297. }
  3298. if (current == '\n')
  3299. {
  3300. ++position.lines_read;
  3301. ++position.chars_read_current_line = 0;
  3302. }
  3303. return current;
  3304. }
  3305. /*!
  3306. @brief unget current character (read it again on next get)
  3307. We implement unget by setting variable next_unget to true. The input is not
  3308. changed - we just simulate ungetting by modifying chars_read_total,
  3309. chars_read_current_line, and token_string. The next call to get() will
  3310. behave as if the unget character is read again.
  3311. */
  3312. void unget()
  3313. {
  3314. next_unget = true;
  3315. --position.chars_read_total;
  3316. // in case we "unget" a newline, we have to also decrement the lines_read
  3317. if (position.chars_read_current_line == 0)
  3318. {
  3319. if (position.lines_read > 0)
  3320. {
  3321. --position.lines_read;
  3322. }
  3323. }
  3324. else
  3325. {
  3326. --position.chars_read_current_line;
  3327. }
  3328. if (JSON_LIKELY(current != std::char_traits<char>::eof()))
  3329. {
  3330. assert(token_string.size() != 0);
  3331. token_string.pop_back();
  3332. }
  3333. }
  3334. /// add a character to token_buffer
  3335. void add(int c)
  3336. {
  3337. token_buffer.push_back(std::char_traits<char>::to_char_type(c));
  3338. }
  3339. public:
  3340. /////////////////////
  3341. // value getters
  3342. /////////////////////
  3343. /// return integer value
  3344. constexpr number_integer_t get_number_integer() const noexcept
  3345. {
  3346. return value_integer;
  3347. }
  3348. /// return unsigned integer value
  3349. constexpr number_unsigned_t get_number_unsigned() const noexcept
  3350. {
  3351. return value_unsigned;
  3352. }
  3353. /// return floating-point value
  3354. constexpr number_float_t get_number_float() const noexcept
  3355. {
  3356. return value_float;
  3357. }
  3358. /// return current string value (implicitly resets the token; useful only once)
  3359. string_t& get_string()
  3360. {
  3361. return token_buffer;
  3362. }
  3363. /////////////////////
  3364. // diagnostics
  3365. /////////////////////
  3366. /// return position of last read token
  3367. constexpr position_t get_position() const noexcept
  3368. {
  3369. return position;
  3370. }
  3371. /// return the last read token (for errors only). Will never contain EOF
  3372. /// (an arbitrary value that is not a valid char value, often -1), because
  3373. /// 255 may legitimately occur. May contain NUL, which should be escaped.
  3374. std::string get_token_string() const
  3375. {
  3376. // escape control characters
  3377. std::string result;
  3378. for (const auto c : token_string)
  3379. {
  3380. if ('\x00' <= c and c <= '\x1F')
  3381. {
  3382. // escape control characters
  3383. char cs[9];
  3384. (std::snprintf)(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
  3385. result += cs;
  3386. }
  3387. else
  3388. {
  3389. // add character as is
  3390. result.push_back(c);
  3391. }
  3392. }
  3393. return result;
  3394. }
  3395. /// return syntax error message
  3396. constexpr const char* get_error_message() const noexcept
  3397. {
  3398. return error_message;
  3399. }
  3400. /////////////////////
  3401. // actual scanner
  3402. /////////////////////
  3403. /*!
  3404. @brief skip the UTF-8 byte order mark
  3405. @return true iff there is no BOM or the correct BOM has been skipped
  3406. */
  3407. bool skip_bom()
  3408. {
  3409. if (get() == 0xEF)
  3410. {
  3411. // check if we completely parse the BOM
  3412. return get() == 0xBB and get() == 0xBF;
  3413. }
  3414. // the first character is not the beginning of the BOM; unget it to
  3415. // process is later
  3416. unget();
  3417. return true;
  3418. }
  3419. token_type scan()
  3420. {
  3421. // initially, skip the BOM
  3422. if (position.chars_read_total == 0 and not skip_bom())
  3423. {
  3424. error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
  3425. return token_type::parse_error;
  3426. }
  3427. // read next character and ignore whitespace
  3428. do
  3429. {
  3430. get();
  3431. }
  3432. while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
  3433. switch (current)
  3434. {
  3435. // structural characters
  3436. case '[':
  3437. return token_type::begin_array;
  3438. case ']':
  3439. return token_type::end_array;
  3440. case '{':
  3441. return token_type::begin_object;
  3442. case '}':
  3443. return token_type::end_object;
  3444. case ':':
  3445. return token_type::name_separator;
  3446. case ',':
  3447. return token_type::value_separator;
  3448. // literals
  3449. case 't':
  3450. return scan_literal("true", 4, token_type::literal_true);
  3451. case 'f':
  3452. return scan_literal("false", 5, token_type::literal_false);
  3453. case 'n':
  3454. return scan_literal("null", 4, token_type::literal_null);
  3455. // string
  3456. case '\"':
  3457. return scan_string();
  3458. // number
  3459. case '-':
  3460. case '0':
  3461. case '1':
  3462. case '2':
  3463. case '3':
  3464. case '4':
  3465. case '5':
  3466. case '6':
  3467. case '7':
  3468. case '8':
  3469. case '9':
  3470. return scan_number();
  3471. // end of input (the null byte is needed when parsing from
  3472. // string literals)
  3473. case '\0':
  3474. case std::char_traits<char>::eof():
  3475. return token_type::end_of_input;
  3476. // error
  3477. default:
  3478. error_message = "invalid literal";
  3479. return token_type::parse_error;
  3480. }
  3481. }
  3482. private:
  3483. /// input adapter
  3484. detail::input_adapter_t ia = nullptr;
  3485. /// the current character
  3486. std::char_traits<char>::int_type current = std::char_traits<char>::eof();
  3487. /// whether the next get() call should just return current
  3488. bool next_unget = false;
  3489. /// the start position of the current token
  3490. position_t position;
  3491. /// raw input token string (for error messages)
  3492. std::vector<char> token_string {};
  3493. /// buffer for variable-length tokens (numbers, strings)
  3494. string_t token_buffer {};
  3495. /// a description of occurred lexer errors
  3496. const char* error_message = "";
  3497. // number values
  3498. number_integer_t value_integer = 0;
  3499. number_unsigned_t value_unsigned = 0;
  3500. number_float_t value_float = 0;
  3501. /// the decimal point
  3502. const char decimal_point_char = '.';
  3503. };
  3504. } // namespace detail
  3505. } // namespace nlohmann
  3506. // #include <nlohmann/detail/input/parser.hpp>
  3507. #include <cassert> // assert
  3508. #include <cmath> // isfinite
  3509. #include <cstdint> // uint8_t
  3510. #include <functional> // function
  3511. #include <string> // string
  3512. #include <utility> // move
  3513. // #include <nlohmann/detail/exceptions.hpp>
  3514. // #include <nlohmann/detail/macro_scope.hpp>
  3515. // #include <nlohmann/detail/meta/is_sax.hpp>
  3516. #include <cstdint> // size_t
  3517. #include <utility> // declval
  3518. // #include <nlohmann/detail/meta/detected.hpp>
  3519. // #include <nlohmann/detail/meta/type_traits.hpp>
  3520. namespace nlohmann
  3521. {
  3522. namespace detail
  3523. {
  3524. template <typename T>
  3525. using null_function_t = decltype(std::declval<T&>().null());
  3526. template <typename T>
  3527. using boolean_function_t =
  3528. decltype(std::declval<T&>().boolean(std::declval<bool>()));
  3529. template <typename T, typename Integer>
  3530. using number_integer_function_t =
  3531. decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
  3532. template <typename T, typename Unsigned>
  3533. using number_unsigned_function_t =
  3534. decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
  3535. template <typename T, typename Float, typename String>
  3536. using number_float_function_t = decltype(std::declval<T&>().number_float(
  3537. std::declval<Float>(), std::declval<const String&>()));
  3538. template <typename T, typename String>
  3539. using string_function_t =
  3540. decltype(std::declval<T&>().string(std::declval<String&>()));
  3541. template <typename T>
  3542. using start_object_function_t =
  3543. decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
  3544. template <typename T, typename String>
  3545. using key_function_t =
  3546. decltype(std::declval<T&>().key(std::declval<String&>()));
  3547. template <typename T>
  3548. using end_object_function_t = decltype(std::declval<T&>().end_object());
  3549. template <typename T>
  3550. using start_array_function_t =
  3551. decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
  3552. template <typename T>
  3553. using end_array_function_t = decltype(std::declval<T&>().end_array());
  3554. template <typename T, typename Exception>
  3555. using parse_error_function_t = decltype(std::declval<T&>().parse_error(
  3556. std::declval<std::size_t>(), std::declval<const std::string&>(),
  3557. std::declval<const Exception&>()));
  3558. template <typename SAX, typename BasicJsonType>
  3559. struct is_sax
  3560. {
  3561. private:
  3562. static_assert(is_basic_json<BasicJsonType>::value,
  3563. "BasicJsonType must be of type basic_json<...>");
  3564. using number_integer_t = typename BasicJsonType::number_integer_t;
  3565. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  3566. using number_float_t = typename BasicJsonType::number_float_t;
  3567. using string_t = typename BasicJsonType::string_t;
  3568. using exception_t = typename BasicJsonType::exception;
  3569. public:
  3570. static constexpr bool value =
  3571. is_detected_exact<bool, null_function_t, SAX>::value &&
  3572. is_detected_exact<bool, boolean_function_t, SAX>::value &&
  3573. is_detected_exact<bool, number_integer_function_t, SAX,
  3574. number_integer_t>::value &&
  3575. is_detected_exact<bool, number_unsigned_function_t, SAX,
  3576. number_unsigned_t>::value &&
  3577. is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
  3578. string_t>::value &&
  3579. is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
  3580. is_detected_exact<bool, start_object_function_t, SAX>::value &&
  3581. is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
  3582. is_detected_exact<bool, end_object_function_t, SAX>::value &&
  3583. is_detected_exact<bool, start_array_function_t, SAX>::value &&
  3584. is_detected_exact<bool, end_array_function_t, SAX>::value &&
  3585. is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
  3586. };
  3587. template <typename SAX, typename BasicJsonType>
  3588. struct is_sax_static_asserts
  3589. {
  3590. private:
  3591. static_assert(is_basic_json<BasicJsonType>::value,
  3592. "BasicJsonType must be of type basic_json<...>");
  3593. using number_integer_t = typename BasicJsonType::number_integer_t;
  3594. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  3595. using number_float_t = typename BasicJsonType::number_float_t;
  3596. using string_t = typename BasicJsonType::string_t;
  3597. using exception_t = typename BasicJsonType::exception;
  3598. public:
  3599. static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
  3600. "Missing/invalid function: bool null()");
  3601. static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
  3602. "Missing/invalid function: bool boolean(bool)");
  3603. static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
  3604. "Missing/invalid function: bool boolean(bool)");
  3605. static_assert(
  3606. is_detected_exact<bool, number_integer_function_t, SAX,
  3607. number_integer_t>::value,
  3608. "Missing/invalid function: bool number_integer(number_integer_t)");
  3609. static_assert(
  3610. is_detected_exact<bool, number_unsigned_function_t, SAX,
  3611. number_unsigned_t>::value,
  3612. "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
  3613. static_assert(is_detected_exact<bool, number_float_function_t, SAX,
  3614. number_float_t, string_t>::value,
  3615. "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
  3616. static_assert(
  3617. is_detected_exact<bool, string_function_t, SAX, string_t>::value,
  3618. "Missing/invalid function: bool string(string_t&)");
  3619. static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
  3620. "Missing/invalid function: bool start_object(std::size_t)");
  3621. static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
  3622. "Missing/invalid function: bool key(string_t&)");
  3623. static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
  3624. "Missing/invalid function: bool end_object()");
  3625. static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
  3626. "Missing/invalid function: bool start_array(std::size_t)");
  3627. static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
  3628. "Missing/invalid function: bool end_array()");
  3629. static_assert(
  3630. is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
  3631. "Missing/invalid function: bool parse_error(std::size_t, const "
  3632. "std::string&, const exception&)");
  3633. };
  3634. } // namespace detail
  3635. } // namespace nlohmann
  3636. // #include <nlohmann/detail/input/input_adapters.hpp>
  3637. // #include <nlohmann/detail/input/json_sax.hpp>
  3638. #include <cstddef>
  3639. #include <string>
  3640. #include <vector>
  3641. // #include <nlohmann/detail/input/parser.hpp>
  3642. // #include <nlohmann/detail/exceptions.hpp>
  3643. namespace nlohmann
  3644. {
  3645. /*!
  3646. @brief SAX interface
  3647. This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
  3648. Each function is called in different situations while the input is parsed. The
  3649. boolean return value informs the parser whether to continue processing the
  3650. input.
  3651. */
  3652. template<typename BasicJsonType>
  3653. struct json_sax
  3654. {
  3655. /// type for (signed) integers
  3656. using number_integer_t = typename BasicJsonType::number_integer_t;
  3657. /// type for unsigned integers
  3658. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  3659. /// type for floating-point numbers
  3660. using number_float_t = typename BasicJsonType::number_float_t;
  3661. /// type for strings
  3662. using string_t = typename BasicJsonType::string_t;
  3663. /*!
  3664. @brief a null value was read
  3665. @return whether parsing should proceed
  3666. */
  3667. virtual bool null() = 0;
  3668. /*!
  3669. @brief a boolean value was read
  3670. @param[in] val boolean value
  3671. @return whether parsing should proceed
  3672. */
  3673. virtual bool boolean(bool val) = 0;
  3674. /*!
  3675. @brief an integer number was read
  3676. @param[in] val integer value
  3677. @return whether parsing should proceed
  3678. */
  3679. virtual bool number_integer(number_integer_t val) = 0;
  3680. /*!
  3681. @brief an unsigned integer number was read
  3682. @param[in] val unsigned integer value
  3683. @return whether parsing should proceed
  3684. */
  3685. virtual bool number_unsigned(number_unsigned_t val) = 0;
  3686. /*!
  3687. @brief an floating-point number was read
  3688. @param[in] val floating-point value
  3689. @param[in] s raw token value
  3690. @return whether parsing should proceed
  3691. */
  3692. virtual bool number_float(number_float_t val, const string_t& s) = 0;
  3693. /*!
  3694. @brief a string was read
  3695. @param[in] val string value
  3696. @return whether parsing should proceed
  3697. @note It is safe to move the passed string.
  3698. */
  3699. virtual bool string(string_t& val) = 0;
  3700. /*!
  3701. @brief the beginning of an object was read
  3702. @param[in] elements number of object elements or -1 if unknown
  3703. @return whether parsing should proceed
  3704. @note binary formats may report the number of elements
  3705. */
  3706. virtual bool start_object(std::size_t elements) = 0;
  3707. /*!
  3708. @brief an object key was read
  3709. @param[in] val object key
  3710. @return whether parsing should proceed
  3711. @note It is safe to move the passed string.
  3712. */
  3713. virtual bool key(string_t& val) = 0;
  3714. /*!
  3715. @brief the end of an object was read
  3716. @return whether parsing should proceed
  3717. */
  3718. virtual bool end_object() = 0;
  3719. /*!
  3720. @brief the beginning of an array was read
  3721. @param[in] elements number of array elements or -1 if unknown
  3722. @return whether parsing should proceed
  3723. @note binary formats may report the number of elements
  3724. */
  3725. virtual bool start_array(std::size_t elements) = 0;
  3726. /*!
  3727. @brief the end of an array was read
  3728. @return whether parsing should proceed
  3729. */
  3730. virtual bool end_array() = 0;
  3731. /*!
  3732. @brief a parse error occurred
  3733. @param[in] position the position in the input where the error occurs
  3734. @param[in] last_token the last read token
  3735. @param[in] ex an exception object describing the error
  3736. @return whether parsing should proceed (must return false)
  3737. */
  3738. virtual bool parse_error(std::size_t position,
  3739. const std::string& last_token,
  3740. const detail::exception& ex) = 0;
  3741. virtual ~json_sax() = default;
  3742. };
  3743. namespace detail
  3744. {
  3745. /*!
  3746. @brief SAX implementation to create a JSON value from SAX events
  3747. This class implements the @ref json_sax interface and processes the SAX events
  3748. to create a JSON value which makes it basically a DOM parser. The structure or
  3749. hierarchy of the JSON value is managed by the stack `ref_stack` which contains
  3750. a pointer to the respective array or object for each recursion depth.
  3751. After successful parsing, the value that is passed by reference to the
  3752. constructor contains the parsed value.
  3753. @tparam BasicJsonType the JSON type
  3754. */
  3755. template<typename BasicJsonType>
  3756. class json_sax_dom_parser
  3757. {
  3758. public:
  3759. using number_integer_t = typename BasicJsonType::number_integer_t;
  3760. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  3761. using number_float_t = typename BasicJsonType::number_float_t;
  3762. using string_t = typename BasicJsonType::string_t;
  3763. /*!
  3764. @param[in, out] r reference to a JSON value that is manipulated while
  3765. parsing
  3766. @param[in] allow_exceptions_ whether parse errors yield exceptions
  3767. */
  3768. explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
  3769. : root(r), allow_exceptions(allow_exceptions_)
  3770. {}
  3771. bool null()
  3772. {
  3773. handle_value(nullptr);
  3774. return true;
  3775. }
  3776. bool boolean(bool val)
  3777. {
  3778. handle_value(val);
  3779. return true;
  3780. }
  3781. bool number_integer(number_integer_t val)
  3782. {
  3783. handle_value(val);
  3784. return true;
  3785. }
  3786. bool number_unsigned(number_unsigned_t val)
  3787. {
  3788. handle_value(val);
  3789. return true;
  3790. }
  3791. bool number_float(number_float_t val, const string_t& /*unused*/)
  3792. {
  3793. handle_value(val);
  3794. return true;
  3795. }
  3796. bool string(string_t& val)
  3797. {
  3798. handle_value(val);
  3799. return true;
  3800. }
  3801. bool start_object(std::size_t len)
  3802. {
  3803. ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
  3804. if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
  3805. {
  3806. JSON_THROW(out_of_range::create(408,
  3807. "excessive object size: " + std::to_string(len)));
  3808. }
  3809. return true;
  3810. }
  3811. bool key(string_t& val)
  3812. {
  3813. // add null at given key and store the reference for later
  3814. object_element = &(ref_stack.back()->m_value.object->operator[](val));
  3815. return true;
  3816. }
  3817. bool end_object()
  3818. {
  3819. ref_stack.pop_back();
  3820. return true;
  3821. }
  3822. bool start_array(std::size_t len)
  3823. {
  3824. ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
  3825. if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
  3826. {
  3827. JSON_THROW(out_of_range::create(408,
  3828. "excessive array size: " + std::to_string(len)));
  3829. }
  3830. return true;
  3831. }
  3832. bool end_array()
  3833. {
  3834. ref_stack.pop_back();
  3835. return true;
  3836. }
  3837. bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
  3838. const detail::exception& ex)
  3839. {
  3840. errored = true;
  3841. if (allow_exceptions)
  3842. {
  3843. // determine the proper exception type from the id
  3844. switch ((ex.id / 100) % 100)
  3845. {
  3846. case 1:
  3847. JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
  3848. case 4:
  3849. JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
  3850. // LCOV_EXCL_START
  3851. case 2:
  3852. JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
  3853. case 3:
  3854. JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
  3855. case 5:
  3856. JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
  3857. default:
  3858. assert(false);
  3859. // LCOV_EXCL_STOP
  3860. }
  3861. }
  3862. return false;
  3863. }
  3864. constexpr bool is_errored() const
  3865. {
  3866. return errored;
  3867. }
  3868. private:
  3869. /*!
  3870. @invariant If the ref stack is empty, then the passed value will be the new
  3871. root.
  3872. @invariant If the ref stack contains a value, then it is an array or an
  3873. object to which we can add elements
  3874. */
  3875. template<typename Value>
  3876. BasicJsonType* handle_value(Value&& v)
  3877. {
  3878. if (ref_stack.empty())
  3879. {
  3880. root = BasicJsonType(std::forward<Value>(v));
  3881. return &root;
  3882. }
  3883. assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
  3884. if (ref_stack.back()->is_array())
  3885. {
  3886. ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
  3887. return &(ref_stack.back()->m_value.array->back());
  3888. }
  3889. else
  3890. {
  3891. assert(object_element);
  3892. *object_element = BasicJsonType(std::forward<Value>(v));
  3893. return object_element;
  3894. }
  3895. }
  3896. /// the parsed JSON value
  3897. BasicJsonType& root;
  3898. /// stack to model hierarchy of values
  3899. std::vector<BasicJsonType*> ref_stack;
  3900. /// helper to hold the reference for the next object element
  3901. BasicJsonType* object_element = nullptr;
  3902. /// whether a syntax error occurred
  3903. bool errored = false;
  3904. /// whether to throw exceptions in case of errors
  3905. const bool allow_exceptions = true;
  3906. };
  3907. template<typename BasicJsonType>
  3908. class json_sax_dom_callback_parser
  3909. {
  3910. public:
  3911. using number_integer_t = typename BasicJsonType::number_integer_t;
  3912. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  3913. using number_float_t = typename BasicJsonType::number_float_t;
  3914. using string_t = typename BasicJsonType::string_t;
  3915. using parser_callback_t = typename BasicJsonType::parser_callback_t;
  3916. using parse_event_t = typename BasicJsonType::parse_event_t;
  3917. json_sax_dom_callback_parser(BasicJsonType& r,
  3918. const parser_callback_t cb,
  3919. const bool allow_exceptions_ = true)
  3920. : root(r), callback(cb), allow_exceptions(allow_exceptions_)
  3921. {
  3922. keep_stack.push_back(true);
  3923. }
  3924. bool null()
  3925. {
  3926. handle_value(nullptr);
  3927. return true;
  3928. }
  3929. bool boolean(bool val)
  3930. {
  3931. handle_value(val);
  3932. return true;
  3933. }
  3934. bool number_integer(number_integer_t val)
  3935. {
  3936. handle_value(val);
  3937. return true;
  3938. }
  3939. bool number_unsigned(number_unsigned_t val)
  3940. {
  3941. handle_value(val);
  3942. return true;
  3943. }
  3944. bool number_float(number_float_t val, const string_t& /*unused*/)
  3945. {
  3946. handle_value(val);
  3947. return true;
  3948. }
  3949. bool string(string_t& val)
  3950. {
  3951. handle_value(val);
  3952. return true;
  3953. }
  3954. bool start_object(std::size_t len)
  3955. {
  3956. // check callback for object start
  3957. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
  3958. keep_stack.push_back(keep);
  3959. auto val = handle_value(BasicJsonType::value_t::object, true);
  3960. ref_stack.push_back(val.second);
  3961. // check object limit
  3962. if (ref_stack.back())
  3963. {
  3964. if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
  3965. {
  3966. JSON_THROW(out_of_range::create(408,
  3967. "excessive object size: " + std::to_string(len)));
  3968. }
  3969. }
  3970. return true;
  3971. }
  3972. bool key(string_t& val)
  3973. {
  3974. BasicJsonType k = BasicJsonType(val);
  3975. // check callback for key
  3976. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
  3977. key_keep_stack.push_back(keep);
  3978. // add discarded value at given key and store the reference for later
  3979. if (keep and ref_stack.back())
  3980. {
  3981. object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
  3982. }
  3983. return true;
  3984. }
  3985. bool end_object()
  3986. {
  3987. if (ref_stack.back())
  3988. {
  3989. if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
  3990. {
  3991. // discard object
  3992. *ref_stack.back() = discarded;
  3993. }
  3994. }
  3995. assert(not ref_stack.empty());
  3996. assert(not keep_stack.empty());
  3997. ref_stack.pop_back();
  3998. keep_stack.pop_back();
  3999. if (not ref_stack.empty() and ref_stack.back())
  4000. {
  4001. // remove discarded value
  4002. if (ref_stack.back()->is_object())
  4003. {
  4004. for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
  4005. {
  4006. if (it->is_discarded())
  4007. {
  4008. ref_stack.back()->erase(it);
  4009. break;
  4010. }
  4011. }
  4012. }
  4013. }
  4014. return true;
  4015. }
  4016. bool start_array(std::size_t len)
  4017. {
  4018. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
  4019. keep_stack.push_back(keep);
  4020. auto val = handle_value(BasicJsonType::value_t::array, true);
  4021. ref_stack.push_back(val.second);
  4022. // check array limit
  4023. if (ref_stack.back())
  4024. {
  4025. if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
  4026. {
  4027. JSON_THROW(out_of_range::create(408,
  4028. "excessive array size: " + std::to_string(len)));
  4029. }
  4030. }
  4031. return true;
  4032. }
  4033. bool end_array()
  4034. {
  4035. bool keep = true;
  4036. if (ref_stack.back())
  4037. {
  4038. keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
  4039. if (not keep)
  4040. {
  4041. // discard array
  4042. *ref_stack.back() = discarded;
  4043. }
  4044. }
  4045. assert(not ref_stack.empty());
  4046. assert(not keep_stack.empty());
  4047. ref_stack.pop_back();
  4048. keep_stack.pop_back();
  4049. // remove discarded value
  4050. if (not keep and not ref_stack.empty())
  4051. {
  4052. if (ref_stack.back()->is_array())
  4053. {
  4054. ref_stack.back()->m_value.array->pop_back();
  4055. }
  4056. }
  4057. return true;
  4058. }
  4059. bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
  4060. const detail::exception& ex)
  4061. {
  4062. errored = true;
  4063. if (allow_exceptions)
  4064. {
  4065. // determine the proper exception type from the id
  4066. switch ((ex.id / 100) % 100)
  4067. {
  4068. case 1:
  4069. JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
  4070. case 4:
  4071. JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
  4072. // LCOV_EXCL_START
  4073. case 2:
  4074. JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
  4075. case 3:
  4076. JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
  4077. case 5:
  4078. JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
  4079. default:
  4080. assert(false);
  4081. // LCOV_EXCL_STOP
  4082. }
  4083. }
  4084. return false;
  4085. }
  4086. constexpr bool is_errored() const
  4087. {
  4088. return errored;
  4089. }
  4090. private:
  4091. /*!
  4092. @param[in] v value to add to the JSON value we build during parsing
  4093. @param[in] skip_callback whether we should skip calling the callback
  4094. function; this is required after start_array() and
  4095. start_object() SAX events, because otherwise we would call the
  4096. callback function with an empty array or object, respectively.
  4097. @invariant If the ref stack is empty, then the passed value will be the new
  4098. root.
  4099. @invariant If the ref stack contains a value, then it is an array or an
  4100. object to which we can add elements
  4101. @return pair of boolean (whether value should be kept) and pointer (to the
  4102. passed value in the ref_stack hierarchy; nullptr if not kept)
  4103. */
  4104. template<typename Value>
  4105. std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
  4106. {
  4107. assert(not keep_stack.empty());
  4108. // do not handle this value if we know it would be added to a discarded
  4109. // container
  4110. if (not keep_stack.back())
  4111. {
  4112. return {false, nullptr};
  4113. }
  4114. // create value
  4115. auto value = BasicJsonType(std::forward<Value>(v));
  4116. // check callback
  4117. const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
  4118. // do not handle this value if we just learnt it shall be discarded
  4119. if (not keep)
  4120. {
  4121. return {false, nullptr};
  4122. }
  4123. if (ref_stack.empty())
  4124. {
  4125. root = std::move(value);
  4126. return {true, &root};
  4127. }
  4128. // skip this value if we already decided to skip the parent
  4129. // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
  4130. if (not ref_stack.back())
  4131. {
  4132. return {false, nullptr};
  4133. }
  4134. // we now only expect arrays and objects
  4135. assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
  4136. if (ref_stack.back()->is_array())
  4137. {
  4138. ref_stack.back()->m_value.array->push_back(std::move(value));
  4139. return {true, &(ref_stack.back()->m_value.array->back())};
  4140. }
  4141. else
  4142. {
  4143. // check if we should store an element for the current key
  4144. assert(not key_keep_stack.empty());
  4145. const bool store_element = key_keep_stack.back();
  4146. key_keep_stack.pop_back();
  4147. if (not store_element)
  4148. {
  4149. return {false, nullptr};
  4150. }
  4151. assert(object_element);
  4152. *object_element = std::move(value);
  4153. return {true, object_element};
  4154. }
  4155. }
  4156. /// the parsed JSON value
  4157. BasicJsonType& root;
  4158. /// stack to model hierarchy of values
  4159. std::vector<BasicJsonType*> ref_stack;
  4160. /// stack to manage which values to keep
  4161. std::vector<bool> keep_stack;
  4162. /// stack to manage which object keys to keep
  4163. std::vector<bool> key_keep_stack;
  4164. /// helper to hold the reference for the next object element
  4165. BasicJsonType* object_element = nullptr;
  4166. /// whether a syntax error occurred
  4167. bool errored = false;
  4168. /// callback function
  4169. const parser_callback_t callback = nullptr;
  4170. /// whether to throw exceptions in case of errors
  4171. const bool allow_exceptions = true;
  4172. /// a discarded value for the callback
  4173. BasicJsonType discarded = BasicJsonType::value_t::discarded;
  4174. };
  4175. template<typename BasicJsonType>
  4176. class json_sax_acceptor
  4177. {
  4178. public:
  4179. using number_integer_t = typename BasicJsonType::number_integer_t;
  4180. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  4181. using number_float_t = typename BasicJsonType::number_float_t;
  4182. using string_t = typename BasicJsonType::string_t;
  4183. bool null()
  4184. {
  4185. return true;
  4186. }
  4187. bool boolean(bool /*unused*/)
  4188. {
  4189. return true;
  4190. }
  4191. bool number_integer(number_integer_t /*unused*/)
  4192. {
  4193. return true;
  4194. }
  4195. bool number_unsigned(number_unsigned_t /*unused*/)
  4196. {
  4197. return true;
  4198. }
  4199. bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
  4200. {
  4201. return true;
  4202. }
  4203. bool string(string_t& /*unused*/)
  4204. {
  4205. return true;
  4206. }
  4207. bool start_object(std::size_t /*unused*/ = std::size_t(-1))
  4208. {
  4209. return true;
  4210. }
  4211. bool key(string_t& /*unused*/)
  4212. {
  4213. return true;
  4214. }
  4215. bool end_object()
  4216. {
  4217. return true;
  4218. }
  4219. bool start_array(std::size_t /*unused*/ = std::size_t(-1))
  4220. {
  4221. return true;
  4222. }
  4223. bool end_array()
  4224. {
  4225. return true;
  4226. }
  4227. bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
  4228. {
  4229. return false;
  4230. }
  4231. };
  4232. } // namespace detail
  4233. } // namespace nlohmann
  4234. // #include <nlohmann/detail/input/lexer.hpp>
  4235. // #include <nlohmann/detail/value_t.hpp>
  4236. namespace nlohmann
  4237. {
  4238. namespace detail
  4239. {
  4240. ////////////
  4241. // parser //
  4242. ////////////
  4243. /*!
  4244. @brief syntax analysis
  4245. This class implements a recursive decent parser.
  4246. */
  4247. template<typename BasicJsonType>
  4248. class parser
  4249. {
  4250. using number_integer_t = typename BasicJsonType::number_integer_t;
  4251. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  4252. using number_float_t = typename BasicJsonType::number_float_t;
  4253. using string_t = typename BasicJsonType::string_t;
  4254. using lexer_t = lexer<BasicJsonType>;
  4255. using token_type = typename lexer_t::token_type;
  4256. public:
  4257. enum class parse_event_t : uint8_t
  4258. {
  4259. /// the parser read `{` and started to process a JSON object
  4260. object_start,
  4261. /// the parser read `}` and finished processing a JSON object
  4262. object_end,
  4263. /// the parser read `[` and started to process a JSON array
  4264. array_start,
  4265. /// the parser read `]` and finished processing a JSON array
  4266. array_end,
  4267. /// the parser read a key of a value in an object
  4268. key,
  4269. /// the parser finished reading a JSON value
  4270. value
  4271. };
  4272. using parser_callback_t =
  4273. std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
  4274. /// a parser reading from an input adapter
  4275. explicit parser(detail::input_adapter_t&& adapter,
  4276. const parser_callback_t cb = nullptr,
  4277. const bool allow_exceptions_ = true)
  4278. : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
  4279. {
  4280. // read first token
  4281. get_token();
  4282. }
  4283. /*!
  4284. @brief public parser interface
  4285. @param[in] strict whether to expect the last token to be EOF
  4286. @param[in,out] result parsed JSON value
  4287. @throw parse_error.101 in case of an unexpected token
  4288. @throw parse_error.102 if to_unicode fails or surrogate error
  4289. @throw parse_error.103 if to_unicode fails
  4290. */
  4291. void parse(const bool strict, BasicJsonType& result)
  4292. {
  4293. if (callback)
  4294. {
  4295. json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
  4296. sax_parse_internal(&sdp);
  4297. result.assert_invariant();
  4298. // in strict mode, input must be completely read
  4299. if (strict and (get_token() != token_type::end_of_input))
  4300. {
  4301. sdp.parse_error(m_lexer.get_position(),
  4302. m_lexer.get_token_string(),
  4303. parse_error::create(101, m_lexer.get_position(),
  4304. exception_message(token_type::end_of_input, "value")));
  4305. }
  4306. // in case of an error, return discarded value
  4307. if (sdp.is_errored())
  4308. {
  4309. result = value_t::discarded;
  4310. return;
  4311. }
  4312. // set top-level value to null if it was discarded by the callback
  4313. // function
  4314. if (result.is_discarded())
  4315. {
  4316. result = nullptr;
  4317. }
  4318. }
  4319. else
  4320. {
  4321. json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
  4322. sax_parse_internal(&sdp);
  4323. result.assert_invariant();
  4324. // in strict mode, input must be completely read
  4325. if (strict and (get_token() != token_type::end_of_input))
  4326. {
  4327. sdp.parse_error(m_lexer.get_position(),
  4328. m_lexer.get_token_string(),
  4329. parse_error::create(101, m_lexer.get_position(),
  4330. exception_message(token_type::end_of_input, "value")));
  4331. }
  4332. // in case of an error, return discarded value
  4333. if (sdp.is_errored())
  4334. {
  4335. result = value_t::discarded;
  4336. return;
  4337. }
  4338. }
  4339. }
  4340. /*!
  4341. @brief public accept interface
  4342. @param[in] strict whether to expect the last token to be EOF
  4343. @return whether the input is a proper JSON text
  4344. */
  4345. bool accept(const bool strict = true)
  4346. {
  4347. json_sax_acceptor<BasicJsonType> sax_acceptor;
  4348. return sax_parse(&sax_acceptor, strict);
  4349. }
  4350. template <typename SAX>
  4351. bool sax_parse(SAX* sax, const bool strict = true)
  4352. {
  4353. (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
  4354. const bool result = sax_parse_internal(sax);
  4355. // strict mode: next byte must be EOF
  4356. if (result and strict and (get_token() != token_type::end_of_input))
  4357. {
  4358. return sax->parse_error(m_lexer.get_position(),
  4359. m_lexer.get_token_string(),
  4360. parse_error::create(101, m_lexer.get_position(),
  4361. exception_message(token_type::end_of_input, "value")));
  4362. }
  4363. return result;
  4364. }
  4365. private:
  4366. template <typename SAX>
  4367. bool sax_parse_internal(SAX* sax)
  4368. {
  4369. // stack to remember the hierarchy of structured values we are parsing
  4370. // true = array; false = object
  4371. std::vector<bool> states;
  4372. // value to avoid a goto (see comment where set to true)
  4373. bool skip_to_state_evaluation = false;
  4374. while (true)
  4375. {
  4376. if (not skip_to_state_evaluation)
  4377. {
  4378. // invariant: get_token() was called before each iteration
  4379. switch (last_token)
  4380. {
  4381. case token_type::begin_object:
  4382. {
  4383. if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
  4384. {
  4385. return false;
  4386. }
  4387. // closing } -> we are done
  4388. if (get_token() == token_type::end_object)
  4389. {
  4390. if (JSON_UNLIKELY(not sax->end_object()))
  4391. {
  4392. return false;
  4393. }
  4394. break;
  4395. }
  4396. // parse key
  4397. if (JSON_UNLIKELY(last_token != token_type::value_string))
  4398. {
  4399. return sax->parse_error(m_lexer.get_position(),
  4400. m_lexer.get_token_string(),
  4401. parse_error::create(101, m_lexer.get_position(),
  4402. exception_message(token_type::value_string, "object key")));
  4403. }
  4404. if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
  4405. {
  4406. return false;
  4407. }
  4408. // parse separator (:)
  4409. if (JSON_UNLIKELY(get_token() != token_type::name_separator))
  4410. {
  4411. return sax->parse_error(m_lexer.get_position(),
  4412. m_lexer.get_token_string(),
  4413. parse_error::create(101, m_lexer.get_position(),
  4414. exception_message(token_type::name_separator, "object separator")));
  4415. }
  4416. // remember we are now inside an object
  4417. states.push_back(false);
  4418. // parse values
  4419. get_token();
  4420. continue;
  4421. }
  4422. case token_type::begin_array:
  4423. {
  4424. if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
  4425. {
  4426. return false;
  4427. }
  4428. // closing ] -> we are done
  4429. if (get_token() == token_type::end_array)
  4430. {
  4431. if (JSON_UNLIKELY(not sax->end_array()))
  4432. {
  4433. return false;
  4434. }
  4435. break;
  4436. }
  4437. // remember we are now inside an array
  4438. states.push_back(true);
  4439. // parse values (no need to call get_token)
  4440. continue;
  4441. }
  4442. case token_type::value_float:
  4443. {
  4444. const auto res = m_lexer.get_number_float();
  4445. if (JSON_UNLIKELY(not std::isfinite(res)))
  4446. {
  4447. return sax->parse_error(m_lexer.get_position(),
  4448. m_lexer.get_token_string(),
  4449. out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
  4450. }
  4451. else
  4452. {
  4453. if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
  4454. {
  4455. return false;
  4456. }
  4457. break;
  4458. }
  4459. }
  4460. case token_type::literal_false:
  4461. {
  4462. if (JSON_UNLIKELY(not sax->boolean(false)))
  4463. {
  4464. return false;
  4465. }
  4466. break;
  4467. }
  4468. case token_type::literal_null:
  4469. {
  4470. if (JSON_UNLIKELY(not sax->null()))
  4471. {
  4472. return false;
  4473. }
  4474. break;
  4475. }
  4476. case token_type::literal_true:
  4477. {
  4478. if (JSON_UNLIKELY(not sax->boolean(true)))
  4479. {
  4480. return false;
  4481. }
  4482. break;
  4483. }
  4484. case token_type::value_integer:
  4485. {
  4486. if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
  4487. {
  4488. return false;
  4489. }
  4490. break;
  4491. }
  4492. case token_type::value_string:
  4493. {
  4494. if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
  4495. {
  4496. return false;
  4497. }
  4498. break;
  4499. }
  4500. case token_type::value_unsigned:
  4501. {
  4502. if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
  4503. {
  4504. return false;
  4505. }
  4506. break;
  4507. }
  4508. case token_type::parse_error:
  4509. {
  4510. // using "uninitialized" to avoid "expected" message
  4511. return sax->parse_error(m_lexer.get_position(),
  4512. m_lexer.get_token_string(),
  4513. parse_error::create(101, m_lexer.get_position(),
  4514. exception_message(token_type::uninitialized, "value")));
  4515. }
  4516. default: // the last token was unexpected
  4517. {
  4518. return sax->parse_error(m_lexer.get_position(),
  4519. m_lexer.get_token_string(),
  4520. parse_error::create(101, m_lexer.get_position(),
  4521. exception_message(token_type::literal_or_value, "value")));
  4522. }
  4523. }
  4524. }
  4525. else
  4526. {
  4527. skip_to_state_evaluation = false;
  4528. }
  4529. // we reached this line after we successfully parsed a value
  4530. if (states.empty())
  4531. {
  4532. // empty stack: we reached the end of the hierarchy: done
  4533. return true;
  4534. }
  4535. else
  4536. {
  4537. if (states.back()) // array
  4538. {
  4539. // comma -> next value
  4540. if (get_token() == token_type::value_separator)
  4541. {
  4542. // parse a new value
  4543. get_token();
  4544. continue;
  4545. }
  4546. // closing ]
  4547. if (JSON_LIKELY(last_token == token_type::end_array))
  4548. {
  4549. if (JSON_UNLIKELY(not sax->end_array()))
  4550. {
  4551. return false;
  4552. }
  4553. // We are done with this array. Before we can parse a
  4554. // new value, we need to evaluate the new state first.
  4555. // By setting skip_to_state_evaluation to false, we
  4556. // are effectively jumping to the beginning of this if.
  4557. assert(not states.empty());
  4558. states.pop_back();
  4559. skip_to_state_evaluation = true;
  4560. continue;
  4561. }
  4562. else
  4563. {
  4564. return sax->parse_error(m_lexer.get_position(),
  4565. m_lexer.get_token_string(),
  4566. parse_error::create(101, m_lexer.get_position(),
  4567. exception_message(token_type::end_array, "array")));
  4568. }
  4569. }
  4570. else // object
  4571. {
  4572. // comma -> next value
  4573. if (get_token() == token_type::value_separator)
  4574. {
  4575. // parse key
  4576. if (JSON_UNLIKELY(get_token() != token_type::value_string))
  4577. {
  4578. return sax->parse_error(m_lexer.get_position(),
  4579. m_lexer.get_token_string(),
  4580. parse_error::create(101, m_lexer.get_position(),
  4581. exception_message(token_type::value_string, "object key")));
  4582. }
  4583. else
  4584. {
  4585. if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
  4586. {
  4587. return false;
  4588. }
  4589. }
  4590. // parse separator (:)
  4591. if (JSON_UNLIKELY(get_token() != token_type::name_separator))
  4592. {
  4593. return sax->parse_error(m_lexer.get_position(),
  4594. m_lexer.get_token_string(),
  4595. parse_error::create(101, m_lexer.get_position(),
  4596. exception_message(token_type::name_separator, "object separator")));
  4597. }
  4598. // parse values
  4599. get_token();
  4600. continue;
  4601. }
  4602. // closing }
  4603. if (JSON_LIKELY(last_token == token_type::end_object))
  4604. {
  4605. if (JSON_UNLIKELY(not sax->end_object()))
  4606. {
  4607. return false;
  4608. }
  4609. // We are done with this object. Before we can parse a
  4610. // new value, we need to evaluate the new state first.
  4611. // By setting skip_to_state_evaluation to false, we
  4612. // are effectively jumping to the beginning of this if.
  4613. assert(not states.empty());
  4614. states.pop_back();
  4615. skip_to_state_evaluation = true;
  4616. continue;
  4617. }
  4618. else
  4619. {
  4620. return sax->parse_error(m_lexer.get_position(),
  4621. m_lexer.get_token_string(),
  4622. parse_error::create(101, m_lexer.get_position(),
  4623. exception_message(token_type::end_object, "object")));
  4624. }
  4625. }
  4626. }
  4627. }
  4628. }
  4629. /// get next token from lexer
  4630. token_type get_token()
  4631. {
  4632. return (last_token = m_lexer.scan());
  4633. }
  4634. std::string exception_message(const token_type expected, const std::string& context)
  4635. {
  4636. std::string error_msg = "syntax error ";
  4637. if (not context.empty())
  4638. {
  4639. error_msg += "while parsing " + context + " ";
  4640. }
  4641. error_msg += "- ";
  4642. if (last_token == token_type::parse_error)
  4643. {
  4644. error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
  4645. m_lexer.get_token_string() + "'";
  4646. }
  4647. else
  4648. {
  4649. error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
  4650. }
  4651. if (expected != token_type::uninitialized)
  4652. {
  4653. error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
  4654. }
  4655. return error_msg;
  4656. }
  4657. private:
  4658. /// callback function
  4659. const parser_callback_t callback = nullptr;
  4660. /// the type of the last read token
  4661. token_type last_token = token_type::uninitialized;
  4662. /// the lexer
  4663. lexer_t m_lexer;
  4664. /// whether to throw exceptions in case of errors
  4665. const bool allow_exceptions = true;
  4666. };
  4667. } // namespace detail
  4668. } // namespace nlohmann
  4669. // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
  4670. #include <cstddef> // ptrdiff_t
  4671. #include <limits> // numeric_limits
  4672. namespace nlohmann
  4673. {
  4674. namespace detail
  4675. {
  4676. /*
  4677. @brief an iterator for primitive JSON types
  4678. This class models an iterator for primitive JSON types (boolean, number,
  4679. string). It's only purpose is to allow the iterator/const_iterator classes
  4680. to "iterate" over primitive values. Internally, the iterator is modeled by
  4681. a `difference_type` variable. Value begin_value (`0`) models the begin,
  4682. end_value (`1`) models past the end.
  4683. */
  4684. class primitive_iterator_t
  4685. {
  4686. private:
  4687. using difference_type = std::ptrdiff_t;
  4688. static constexpr difference_type begin_value = 0;
  4689. static constexpr difference_type end_value = begin_value + 1;
  4690. /// iterator as signed integer type
  4691. difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
  4692. public:
  4693. constexpr difference_type get_value() const noexcept
  4694. {
  4695. return m_it;
  4696. }
  4697. /// set iterator to a defined beginning
  4698. void set_begin() noexcept
  4699. {
  4700. m_it = begin_value;
  4701. }
  4702. /// set iterator to a defined past the end
  4703. void set_end() noexcept
  4704. {
  4705. m_it = end_value;
  4706. }
  4707. /// return whether the iterator can be dereferenced
  4708. constexpr bool is_begin() const noexcept
  4709. {
  4710. return m_it == begin_value;
  4711. }
  4712. /// return whether the iterator is at end
  4713. constexpr bool is_end() const noexcept
  4714. {
  4715. return m_it == end_value;
  4716. }
  4717. friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
  4718. {
  4719. return lhs.m_it == rhs.m_it;
  4720. }
  4721. friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
  4722. {
  4723. return lhs.m_it < rhs.m_it;
  4724. }
  4725. primitive_iterator_t operator+(difference_type n) noexcept
  4726. {
  4727. auto result = *this;
  4728. result += n;
  4729. return result;
  4730. }
  4731. friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
  4732. {
  4733. return lhs.m_it - rhs.m_it;
  4734. }
  4735. primitive_iterator_t& operator++() noexcept
  4736. {
  4737. ++m_it;
  4738. return *this;
  4739. }
  4740. primitive_iterator_t const operator++(int) noexcept
  4741. {
  4742. auto result = *this;
  4743. ++m_it;
  4744. return result;
  4745. }
  4746. primitive_iterator_t& operator--() noexcept
  4747. {
  4748. --m_it;
  4749. return *this;
  4750. }
  4751. primitive_iterator_t const operator--(int) noexcept
  4752. {
  4753. auto result = *this;
  4754. --m_it;
  4755. return result;
  4756. }
  4757. primitive_iterator_t& operator+=(difference_type n) noexcept
  4758. {
  4759. m_it += n;
  4760. return *this;
  4761. }
  4762. primitive_iterator_t& operator-=(difference_type n) noexcept
  4763. {
  4764. m_it -= n;
  4765. return *this;
  4766. }
  4767. };
  4768. } // namespace detail
  4769. } // namespace nlohmann
  4770. // #include <nlohmann/detail/iterators/internal_iterator.hpp>
  4771. // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
  4772. namespace nlohmann
  4773. {
  4774. namespace detail
  4775. {
  4776. /*!
  4777. @brief an iterator value
  4778. @note This structure could easily be a union, but MSVC currently does not allow
  4779. unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
  4780. */
  4781. template<typename BasicJsonType> struct internal_iterator
  4782. {
  4783. /// iterator for JSON objects
  4784. typename BasicJsonType::object_t::iterator object_iterator {};
  4785. /// iterator for JSON arrays
  4786. typename BasicJsonType::array_t::iterator array_iterator {};
  4787. /// generic iterator for all other types
  4788. primitive_iterator_t primitive_iterator {};
  4789. };
  4790. } // namespace detail
  4791. } // namespace nlohmann
  4792. // #include <nlohmann/detail/iterators/iter_impl.hpp>
  4793. #include <ciso646> // not
  4794. #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
  4795. #include <type_traits> // conditional, is_const, remove_const
  4796. // #include <nlohmann/detail/exceptions.hpp>
  4797. // #include <nlohmann/detail/iterators/internal_iterator.hpp>
  4798. // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
  4799. // #include <nlohmann/detail/macro_scope.hpp>
  4800. // #include <nlohmann/detail/meta/cpp_future.hpp>
  4801. // #include <nlohmann/detail/value_t.hpp>
  4802. namespace nlohmann
  4803. {
  4804. namespace detail
  4805. {
  4806. // forward declare, to be able to friend it later on
  4807. template<typename IteratorType> class iteration_proxy;
  4808. template<typename IteratorType> class iteration_proxy_value;
  4809. /*!
  4810. @brief a template for a bidirectional iterator for the @ref basic_json class
  4811. This class implements a both iterators (iterator and const_iterator) for the
  4812. @ref basic_json class.
  4813. @note An iterator is called *initialized* when a pointer to a JSON value has
  4814. been set (e.g., by a constructor or a copy assignment). If the iterator is
  4815. default-constructed, it is *uninitialized* and most methods are undefined.
  4816. **The library uses assertions to detect calls on uninitialized iterators.**
  4817. @requirement The class satisfies the following concept requirements:
  4818. -
  4819. [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
  4820. The iterator that can be moved can be moved in both directions (i.e.
  4821. incremented and decremented).
  4822. @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
  4823. iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
  4824. */
  4825. template<typename BasicJsonType>
  4826. class iter_impl
  4827. {
  4828. /// allow basic_json to access private members
  4829. friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
  4830. friend BasicJsonType;
  4831. friend iteration_proxy<iter_impl>;
  4832. friend iteration_proxy_value<iter_impl>;
  4833. using object_t = typename BasicJsonType::object_t;
  4834. using array_t = typename BasicJsonType::array_t;
  4835. // make sure BasicJsonType is basic_json or const basic_json
  4836. static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
  4837. "iter_impl only accepts (const) basic_json");
  4838. public:
  4839. /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
  4840. /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
  4841. /// A user-defined iterator should provide publicly accessible typedefs named
  4842. /// iterator_category, value_type, difference_type, pointer, and reference.
  4843. /// Note that value_type is required to be non-const, even for constant iterators.
  4844. using iterator_category = std::bidirectional_iterator_tag;
  4845. /// the type of the values when the iterator is dereferenced
  4846. using value_type = typename BasicJsonType::value_type;
  4847. /// a type to represent differences between iterators
  4848. using difference_type = typename BasicJsonType::difference_type;
  4849. /// defines a pointer to the type iterated over (value_type)
  4850. using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
  4851. typename BasicJsonType::const_pointer,
  4852. typename BasicJsonType::pointer>::type;
  4853. /// defines a reference to the type iterated over (value_type)
  4854. using reference =
  4855. typename std::conditional<std::is_const<BasicJsonType>::value,
  4856. typename BasicJsonType::const_reference,
  4857. typename BasicJsonType::reference>::type;
  4858. /// default constructor
  4859. iter_impl() = default;
  4860. /*!
  4861. @brief constructor for a given JSON instance
  4862. @param[in] object pointer to a JSON object for this iterator
  4863. @pre object != nullptr
  4864. @post The iterator is initialized; i.e. `m_object != nullptr`.
  4865. */
  4866. explicit iter_impl(pointer object) noexcept : m_object(object)
  4867. {
  4868. assert(m_object != nullptr);
  4869. switch (m_object->m_type)
  4870. {
  4871. case value_t::object:
  4872. {
  4873. m_it.object_iterator = typename object_t::iterator();
  4874. break;
  4875. }
  4876. case value_t::array:
  4877. {
  4878. m_it.array_iterator = typename array_t::iterator();
  4879. break;
  4880. }
  4881. default:
  4882. {
  4883. m_it.primitive_iterator = primitive_iterator_t();
  4884. break;
  4885. }
  4886. }
  4887. }
  4888. /*!
  4889. @note The conventional copy constructor and copy assignment are implicitly
  4890. defined. Combined with the following converting constructor and
  4891. assignment, they support: (1) copy from iterator to iterator, (2)
  4892. copy from const iterator to const iterator, and (3) conversion from
  4893. iterator to const iterator. However conversion from const iterator
  4894. to iterator is not defined.
  4895. */
  4896. /*!
  4897. @brief converting constructor
  4898. @param[in] other non-const iterator to copy from
  4899. @note It is not checked whether @a other is initialized.
  4900. */
  4901. iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
  4902. : m_object(other.m_object), m_it(other.m_it) {}
  4903. /*!
  4904. @brief converting assignment
  4905. @param[in,out] other non-const iterator to copy from
  4906. @return const/non-const iterator
  4907. @note It is not checked whether @a other is initialized.
  4908. */
  4909. iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
  4910. {
  4911. m_object = other.m_object;
  4912. m_it = other.m_it;
  4913. return *this;
  4914. }
  4915. private:
  4916. /*!
  4917. @brief set the iterator to the first value
  4918. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  4919. */
  4920. void set_begin() noexcept
  4921. {
  4922. assert(m_object != nullptr);
  4923. switch (m_object->m_type)
  4924. {
  4925. case value_t::object:
  4926. {
  4927. m_it.object_iterator = m_object->m_value.object->begin();
  4928. break;
  4929. }
  4930. case value_t::array:
  4931. {
  4932. m_it.array_iterator = m_object->m_value.array->begin();
  4933. break;
  4934. }
  4935. case value_t::null:
  4936. {
  4937. // set to end so begin()==end() is true: null is empty
  4938. m_it.primitive_iterator.set_end();
  4939. break;
  4940. }
  4941. default:
  4942. {
  4943. m_it.primitive_iterator.set_begin();
  4944. break;
  4945. }
  4946. }
  4947. }
  4948. /*!
  4949. @brief set the iterator past the last value
  4950. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  4951. */
  4952. void set_end() noexcept
  4953. {
  4954. assert(m_object != nullptr);
  4955. switch (m_object->m_type)
  4956. {
  4957. case value_t::object:
  4958. {
  4959. m_it.object_iterator = m_object->m_value.object->end();
  4960. break;
  4961. }
  4962. case value_t::array:
  4963. {
  4964. m_it.array_iterator = m_object->m_value.array->end();
  4965. break;
  4966. }
  4967. default:
  4968. {
  4969. m_it.primitive_iterator.set_end();
  4970. break;
  4971. }
  4972. }
  4973. }
  4974. public:
  4975. /*!
  4976. @brief return a reference to the value pointed to by the iterator
  4977. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  4978. */
  4979. reference operator*() const
  4980. {
  4981. assert(m_object != nullptr);
  4982. switch (m_object->m_type)
  4983. {
  4984. case value_t::object:
  4985. {
  4986. assert(m_it.object_iterator != m_object->m_value.object->end());
  4987. return m_it.object_iterator->second;
  4988. }
  4989. case value_t::array:
  4990. {
  4991. assert(m_it.array_iterator != m_object->m_value.array->end());
  4992. return *m_it.array_iterator;
  4993. }
  4994. case value_t::null:
  4995. JSON_THROW(invalid_iterator::create(214, "cannot get value"));
  4996. default:
  4997. {
  4998. if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
  4999. {
  5000. return *m_object;
  5001. }
  5002. JSON_THROW(invalid_iterator::create(214, "cannot get value"));
  5003. }
  5004. }
  5005. }
  5006. /*!
  5007. @brief dereference the iterator
  5008. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5009. */
  5010. pointer operator->() const
  5011. {
  5012. assert(m_object != nullptr);
  5013. switch (m_object->m_type)
  5014. {
  5015. case value_t::object:
  5016. {
  5017. assert(m_it.object_iterator != m_object->m_value.object->end());
  5018. return &(m_it.object_iterator->second);
  5019. }
  5020. case value_t::array:
  5021. {
  5022. assert(m_it.array_iterator != m_object->m_value.array->end());
  5023. return &*m_it.array_iterator;
  5024. }
  5025. default:
  5026. {
  5027. if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
  5028. {
  5029. return m_object;
  5030. }
  5031. JSON_THROW(invalid_iterator::create(214, "cannot get value"));
  5032. }
  5033. }
  5034. }
  5035. /*!
  5036. @brief post-increment (it++)
  5037. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5038. */
  5039. iter_impl const operator++(int)
  5040. {
  5041. auto result = *this;
  5042. ++(*this);
  5043. return result;
  5044. }
  5045. /*!
  5046. @brief pre-increment (++it)
  5047. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5048. */
  5049. iter_impl& operator++()
  5050. {
  5051. assert(m_object != nullptr);
  5052. switch (m_object->m_type)
  5053. {
  5054. case value_t::object:
  5055. {
  5056. std::advance(m_it.object_iterator, 1);
  5057. break;
  5058. }
  5059. case value_t::array:
  5060. {
  5061. std::advance(m_it.array_iterator, 1);
  5062. break;
  5063. }
  5064. default:
  5065. {
  5066. ++m_it.primitive_iterator;
  5067. break;
  5068. }
  5069. }
  5070. return *this;
  5071. }
  5072. /*!
  5073. @brief post-decrement (it--)
  5074. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5075. */
  5076. iter_impl const operator--(int)
  5077. {
  5078. auto result = *this;
  5079. --(*this);
  5080. return result;
  5081. }
  5082. /*!
  5083. @brief pre-decrement (--it)
  5084. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5085. */
  5086. iter_impl& operator--()
  5087. {
  5088. assert(m_object != nullptr);
  5089. switch (m_object->m_type)
  5090. {
  5091. case value_t::object:
  5092. {
  5093. std::advance(m_it.object_iterator, -1);
  5094. break;
  5095. }
  5096. case value_t::array:
  5097. {
  5098. std::advance(m_it.array_iterator, -1);
  5099. break;
  5100. }
  5101. default:
  5102. {
  5103. --m_it.primitive_iterator;
  5104. break;
  5105. }
  5106. }
  5107. return *this;
  5108. }
  5109. /*!
  5110. @brief comparison: equal
  5111. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5112. */
  5113. bool operator==(const iter_impl& other) const
  5114. {
  5115. // if objects are not the same, the comparison is undefined
  5116. if (JSON_UNLIKELY(m_object != other.m_object))
  5117. {
  5118. JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
  5119. }
  5120. assert(m_object != nullptr);
  5121. switch (m_object->m_type)
  5122. {
  5123. case value_t::object:
  5124. return (m_it.object_iterator == other.m_it.object_iterator);
  5125. case value_t::array:
  5126. return (m_it.array_iterator == other.m_it.array_iterator);
  5127. default:
  5128. return (m_it.primitive_iterator == other.m_it.primitive_iterator);
  5129. }
  5130. }
  5131. /*!
  5132. @brief comparison: not equal
  5133. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5134. */
  5135. bool operator!=(const iter_impl& other) const
  5136. {
  5137. return not operator==(other);
  5138. }
  5139. /*!
  5140. @brief comparison: smaller
  5141. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5142. */
  5143. bool operator<(const iter_impl& other) const
  5144. {
  5145. // if objects are not the same, the comparison is undefined
  5146. if (JSON_UNLIKELY(m_object != other.m_object))
  5147. {
  5148. JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
  5149. }
  5150. assert(m_object != nullptr);
  5151. switch (m_object->m_type)
  5152. {
  5153. case value_t::object:
  5154. JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
  5155. case value_t::array:
  5156. return (m_it.array_iterator < other.m_it.array_iterator);
  5157. default:
  5158. return (m_it.primitive_iterator < other.m_it.primitive_iterator);
  5159. }
  5160. }
  5161. /*!
  5162. @brief comparison: less than or equal
  5163. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5164. */
  5165. bool operator<=(const iter_impl& other) const
  5166. {
  5167. return not other.operator < (*this);
  5168. }
  5169. /*!
  5170. @brief comparison: greater than
  5171. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5172. */
  5173. bool operator>(const iter_impl& other) const
  5174. {
  5175. return not operator<=(other);
  5176. }
  5177. /*!
  5178. @brief comparison: greater than or equal
  5179. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5180. */
  5181. bool operator>=(const iter_impl& other) const
  5182. {
  5183. return not operator<(other);
  5184. }
  5185. /*!
  5186. @brief add to iterator
  5187. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5188. */
  5189. iter_impl& operator+=(difference_type i)
  5190. {
  5191. assert(m_object != nullptr);
  5192. switch (m_object->m_type)
  5193. {
  5194. case value_t::object:
  5195. JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
  5196. case value_t::array:
  5197. {
  5198. std::advance(m_it.array_iterator, i);
  5199. break;
  5200. }
  5201. default:
  5202. {
  5203. m_it.primitive_iterator += i;
  5204. break;
  5205. }
  5206. }
  5207. return *this;
  5208. }
  5209. /*!
  5210. @brief subtract from iterator
  5211. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5212. */
  5213. iter_impl& operator-=(difference_type i)
  5214. {
  5215. return operator+=(-i);
  5216. }
  5217. /*!
  5218. @brief add to iterator
  5219. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5220. */
  5221. iter_impl operator+(difference_type i) const
  5222. {
  5223. auto result = *this;
  5224. result += i;
  5225. return result;
  5226. }
  5227. /*!
  5228. @brief addition of distance and iterator
  5229. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5230. */
  5231. friend iter_impl operator+(difference_type i, const iter_impl& it)
  5232. {
  5233. auto result = it;
  5234. result += i;
  5235. return result;
  5236. }
  5237. /*!
  5238. @brief subtract from iterator
  5239. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5240. */
  5241. iter_impl operator-(difference_type i) const
  5242. {
  5243. auto result = *this;
  5244. result -= i;
  5245. return result;
  5246. }
  5247. /*!
  5248. @brief return difference
  5249. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5250. */
  5251. difference_type operator-(const iter_impl& other) const
  5252. {
  5253. assert(m_object != nullptr);
  5254. switch (m_object->m_type)
  5255. {
  5256. case value_t::object:
  5257. JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
  5258. case value_t::array:
  5259. return m_it.array_iterator - other.m_it.array_iterator;
  5260. default:
  5261. return m_it.primitive_iterator - other.m_it.primitive_iterator;
  5262. }
  5263. }
  5264. /*!
  5265. @brief access to successor
  5266. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5267. */
  5268. reference operator[](difference_type n) const
  5269. {
  5270. assert(m_object != nullptr);
  5271. switch (m_object->m_type)
  5272. {
  5273. case value_t::object:
  5274. JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
  5275. case value_t::array:
  5276. return *std::next(m_it.array_iterator, n);
  5277. case value_t::null:
  5278. JSON_THROW(invalid_iterator::create(214, "cannot get value"));
  5279. default:
  5280. {
  5281. if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
  5282. {
  5283. return *m_object;
  5284. }
  5285. JSON_THROW(invalid_iterator::create(214, "cannot get value"));
  5286. }
  5287. }
  5288. }
  5289. /*!
  5290. @brief return the key of an object iterator
  5291. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5292. */
  5293. const typename object_t::key_type& key() const
  5294. {
  5295. assert(m_object != nullptr);
  5296. if (JSON_LIKELY(m_object->is_object()))
  5297. {
  5298. return m_it.object_iterator->first;
  5299. }
  5300. JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
  5301. }
  5302. /*!
  5303. @brief return the value of an iterator
  5304. @pre The iterator is initialized; i.e. `m_object != nullptr`.
  5305. */
  5306. reference value() const
  5307. {
  5308. return operator*();
  5309. }
  5310. private:
  5311. /// associated JSON instance
  5312. pointer m_object = nullptr;
  5313. /// the actual iterator of the associated instance
  5314. internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
  5315. };
  5316. } // namespace detail
  5317. } // namespace nlohmann
  5318. // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
  5319. // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
  5320. #include <cstddef> // ptrdiff_t
  5321. #include <iterator> // reverse_iterator
  5322. #include <utility> // declval
  5323. namespace nlohmann
  5324. {
  5325. namespace detail
  5326. {
  5327. //////////////////////
  5328. // reverse_iterator //
  5329. //////////////////////
  5330. /*!
  5331. @brief a template for a reverse iterator class
  5332. @tparam Base the base iterator type to reverse. Valid types are @ref
  5333. iterator (to create @ref reverse_iterator) and @ref const_iterator (to
  5334. create @ref const_reverse_iterator).
  5335. @requirement The class satisfies the following concept requirements:
  5336. -
  5337. [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
  5338. The iterator that can be moved can be moved in both directions (i.e.
  5339. incremented and decremented).
  5340. - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
  5341. It is possible to write to the pointed-to element (only if @a Base is
  5342. @ref iterator).
  5343. @since version 1.0.0
  5344. */
  5345. template<typename Base>
  5346. class json_reverse_iterator : public std::reverse_iterator<Base>
  5347. {
  5348. public:
  5349. using difference_type = std::ptrdiff_t;
  5350. /// shortcut to the reverse iterator adapter
  5351. using base_iterator = std::reverse_iterator<Base>;
  5352. /// the reference type for the pointed-to element
  5353. using reference = typename Base::reference;
  5354. /// create reverse iterator from iterator
  5355. explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
  5356. : base_iterator(it) {}
  5357. /// create reverse iterator from base class
  5358. explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
  5359. /// post-increment (it++)
  5360. json_reverse_iterator const operator++(int)
  5361. {
  5362. return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
  5363. }
  5364. /// pre-increment (++it)
  5365. json_reverse_iterator& operator++()
  5366. {
  5367. return static_cast<json_reverse_iterator&>(base_iterator::operator++());
  5368. }
  5369. /// post-decrement (it--)
  5370. json_reverse_iterator const operator--(int)
  5371. {
  5372. return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
  5373. }
  5374. /// pre-decrement (--it)
  5375. json_reverse_iterator& operator--()
  5376. {
  5377. return static_cast<json_reverse_iterator&>(base_iterator::operator--());
  5378. }
  5379. /// add to iterator
  5380. json_reverse_iterator& operator+=(difference_type i)
  5381. {
  5382. return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
  5383. }
  5384. /// add to iterator
  5385. json_reverse_iterator operator+(difference_type i) const
  5386. {
  5387. return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
  5388. }
  5389. /// subtract from iterator
  5390. json_reverse_iterator operator-(difference_type i) const
  5391. {
  5392. return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
  5393. }
  5394. /// return difference
  5395. difference_type operator-(const json_reverse_iterator& other) const
  5396. {
  5397. return base_iterator(*this) - base_iterator(other);
  5398. }
  5399. /// access to successor
  5400. reference operator[](difference_type n) const
  5401. {
  5402. return *(this->operator+(n));
  5403. }
  5404. /// return the key of an object iterator
  5405. auto key() const -> decltype(std::declval<Base>().key())
  5406. {
  5407. auto it = --this->base();
  5408. return it.key();
  5409. }
  5410. /// return the value of an iterator
  5411. reference value() const
  5412. {
  5413. auto it = --this->base();
  5414. return it.operator * ();
  5415. }
  5416. };
  5417. } // namespace detail
  5418. } // namespace nlohmann
  5419. // #include <nlohmann/detail/output/output_adapters.hpp>
  5420. #include <algorithm> // copy
  5421. #include <cstddef> // size_t
  5422. #include <ios> // streamsize
  5423. #include <iterator> // back_inserter
  5424. #include <memory> // shared_ptr, make_shared
  5425. #include <ostream> // basic_ostream
  5426. #include <string> // basic_string
  5427. #include <vector> // vector
  5428. namespace nlohmann
  5429. {
  5430. namespace detail
  5431. {
  5432. /// abstract output adapter interface
  5433. template<typename CharType> struct output_adapter_protocol
  5434. {
  5435. virtual void write_character(CharType c) = 0;
  5436. virtual void write_characters(const CharType* s, std::size_t length) = 0;
  5437. virtual ~output_adapter_protocol() = default;
  5438. };
  5439. /// a type to simplify interfaces
  5440. template<typename CharType>
  5441. using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
  5442. /// output adapter for byte vectors
  5443. template<typename CharType>
  5444. class output_vector_adapter : public output_adapter_protocol<CharType>
  5445. {
  5446. public:
  5447. explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
  5448. : v(vec)
  5449. {}
  5450. void write_character(CharType c) override
  5451. {
  5452. v.push_back(c);
  5453. }
  5454. void write_characters(const CharType* s, std::size_t length) override
  5455. {
  5456. std::copy(s, s + length, std::back_inserter(v));
  5457. }
  5458. private:
  5459. std::vector<CharType>& v;
  5460. };
  5461. /// output adapter for output streams
  5462. template<typename CharType>
  5463. class output_stream_adapter : public output_adapter_protocol<CharType>
  5464. {
  5465. public:
  5466. explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
  5467. : stream(s)
  5468. {}
  5469. void write_character(CharType c) override
  5470. {
  5471. stream.put(c);
  5472. }
  5473. void write_characters(const CharType* s, std::size_t length) override
  5474. {
  5475. stream.write(s, static_cast<std::streamsize>(length));
  5476. }
  5477. private:
  5478. std::basic_ostream<CharType>& stream;
  5479. };
  5480. /// output adapter for basic_string
  5481. template<typename CharType, typename StringType = std::basic_string<CharType>>
  5482. class output_string_adapter : public output_adapter_protocol<CharType>
  5483. {
  5484. public:
  5485. explicit output_string_adapter(StringType& s) noexcept
  5486. : str(s)
  5487. {}
  5488. void write_character(CharType c) override
  5489. {
  5490. str.push_back(c);
  5491. }
  5492. void write_characters(const CharType* s, std::size_t length) override
  5493. {
  5494. str.append(s, length);
  5495. }
  5496. private:
  5497. StringType& str;
  5498. };
  5499. template<typename CharType, typename StringType = std::basic_string<CharType>>
  5500. class output_adapter
  5501. {
  5502. public:
  5503. output_adapter(std::vector<CharType>& vec)
  5504. : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
  5505. output_adapter(std::basic_ostream<CharType>& s)
  5506. : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
  5507. output_adapter(StringType& s)
  5508. : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
  5509. operator output_adapter_t<CharType>()
  5510. {
  5511. return oa;
  5512. }
  5513. private:
  5514. output_adapter_t<CharType> oa = nullptr;
  5515. };
  5516. } // namespace detail
  5517. } // namespace nlohmann
  5518. // #include <nlohmann/detail/input/binary_reader.hpp>
  5519. #include <algorithm> // generate_n
  5520. #include <array> // array
  5521. #include <cassert> // assert
  5522. #include <cmath> // ldexp
  5523. #include <cstddef> // size_t
  5524. #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
  5525. #include <cstdio> // snprintf
  5526. #include <cstring> // memcpy
  5527. #include <iterator> // back_inserter
  5528. #include <limits> // numeric_limits
  5529. #include <string> // char_traits, string
  5530. #include <utility> // make_pair, move
  5531. // #include <nlohmann/detail/input/input_adapters.hpp>
  5532. // #include <nlohmann/detail/input/json_sax.hpp>
  5533. // #include <nlohmann/detail/exceptions.hpp>
  5534. // #include <nlohmann/detail/macro_scope.hpp>
  5535. // #include <nlohmann/detail/meta/is_sax.hpp>
  5536. // #include <nlohmann/detail/value_t.hpp>
  5537. namespace nlohmann
  5538. {
  5539. namespace detail
  5540. {
  5541. ///////////////////
  5542. // binary reader //
  5543. ///////////////////
  5544. /*!
  5545. @brief deserialization of CBOR, MessagePack, and UBJSON values
  5546. */
  5547. template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
  5548. class binary_reader
  5549. {
  5550. using number_integer_t = typename BasicJsonType::number_integer_t;
  5551. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  5552. using number_float_t = typename BasicJsonType::number_float_t;
  5553. using string_t = typename BasicJsonType::string_t;
  5554. using json_sax_t = SAX;
  5555. public:
  5556. /*!
  5557. @brief create a binary reader
  5558. @param[in] adapter input adapter to read from
  5559. */
  5560. explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
  5561. {
  5562. (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
  5563. assert(ia);
  5564. }
  5565. /*!
  5566. @param[in] format the binary format to parse
  5567. @param[in] sax_ a SAX event processor
  5568. @param[in] strict whether to expect the input to be consumed completed
  5569. @return
  5570. */
  5571. bool sax_parse(const input_format_t format,
  5572. json_sax_t* sax_,
  5573. const bool strict = true)
  5574. {
  5575. sax = sax_;
  5576. bool result = false;
  5577. switch (format)
  5578. {
  5579. case input_format_t::bson:
  5580. result = parse_bson_internal();
  5581. break;
  5582. case input_format_t::cbor:
  5583. result = parse_cbor_internal();
  5584. break;
  5585. case input_format_t::msgpack:
  5586. result = parse_msgpack_internal();
  5587. break;
  5588. case input_format_t::ubjson:
  5589. result = parse_ubjson_internal();
  5590. break;
  5591. // LCOV_EXCL_START
  5592. default:
  5593. assert(false);
  5594. // LCOV_EXCL_STOP
  5595. }
  5596. // strict mode: next byte must be EOF
  5597. if (result and strict)
  5598. {
  5599. if (format == input_format_t::ubjson)
  5600. {
  5601. get_ignore_noop();
  5602. }
  5603. else
  5604. {
  5605. get();
  5606. }
  5607. if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
  5608. {
  5609. return sax->parse_error(chars_read, get_token_string(),
  5610. parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
  5611. }
  5612. }
  5613. return result;
  5614. }
  5615. /*!
  5616. @brief determine system byte order
  5617. @return true if and only if system's byte order is little endian
  5618. @note from http://stackoverflow.com/a/1001328/266378
  5619. */
  5620. static constexpr bool little_endianess(int num = 1) noexcept
  5621. {
  5622. return (*reinterpret_cast<char*>(&num) == 1);
  5623. }
  5624. private:
  5625. //////////
  5626. // BSON //
  5627. //////////
  5628. /*!
  5629. @brief Reads in a BSON-object and passes it to the SAX-parser.
  5630. @return whether a valid BSON-value was passed to the SAX parser
  5631. */
  5632. bool parse_bson_internal()
  5633. {
  5634. std::int32_t document_size;
  5635. get_number<std::int32_t, true>(input_format_t::bson, document_size);
  5636. if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
  5637. {
  5638. return false;
  5639. }
  5640. if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
  5641. {
  5642. return false;
  5643. }
  5644. return sax->end_object();
  5645. }
  5646. /*!
  5647. @brief Parses a C-style string from the BSON input.
  5648. @param[in, out] result A reference to the string variable where the read
  5649. string is to be stored.
  5650. @return `true` if the \x00-byte indicating the end of the string was
  5651. encountered before the EOF; false` indicates an unexpected EOF.
  5652. */
  5653. bool get_bson_cstr(string_t& result)
  5654. {
  5655. auto out = std::back_inserter(result);
  5656. while (true)
  5657. {
  5658. get();
  5659. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
  5660. {
  5661. return false;
  5662. }
  5663. if (current == 0x00)
  5664. {
  5665. return true;
  5666. }
  5667. *out++ = static_cast<char>(current);
  5668. }
  5669. return true;
  5670. }
  5671. /*!
  5672. @brief Parses a zero-terminated string of length @a len from the BSON
  5673. input.
  5674. @param[in] len The length (including the zero-byte at the end) of the
  5675. string to be read.
  5676. @param[in, out] result A reference to the string variable where the read
  5677. string is to be stored.
  5678. @tparam NumberType The type of the length @a len
  5679. @pre len >= 1
  5680. @return `true` if the string was successfully parsed
  5681. */
  5682. template<typename NumberType>
  5683. bool get_bson_string(const NumberType len, string_t& result)
  5684. {
  5685. if (JSON_UNLIKELY(len < 1))
  5686. {
  5687. auto last_token = get_token_string();
  5688. return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
  5689. }
  5690. return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
  5691. }
  5692. /*!
  5693. @brief Read a BSON document element of the given @a element_type.
  5694. @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
  5695. @param[in] element_type_parse_position The position in the input stream,
  5696. where the `element_type` was read.
  5697. @warning Not all BSON element types are supported yet. An unsupported
  5698. @a element_type will give rise to a parse_error.114:
  5699. Unsupported BSON record type 0x...
  5700. @return whether a valid BSON-object/array was passed to the SAX parser
  5701. */
  5702. bool parse_bson_element_internal(const int element_type,
  5703. const std::size_t element_type_parse_position)
  5704. {
  5705. switch (element_type)
  5706. {
  5707. case 0x01: // double
  5708. {
  5709. double number;
  5710. return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
  5711. }
  5712. case 0x02: // string
  5713. {
  5714. std::int32_t len;
  5715. string_t value;
  5716. return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
  5717. }
  5718. case 0x03: // object
  5719. {
  5720. return parse_bson_internal();
  5721. }
  5722. case 0x04: // array
  5723. {
  5724. return parse_bson_array();
  5725. }
  5726. case 0x08: // boolean
  5727. {
  5728. return sax->boolean(get() != 0);
  5729. }
  5730. case 0x0A: // null
  5731. {
  5732. return sax->null();
  5733. }
  5734. case 0x10: // int32
  5735. {
  5736. std::int32_t value;
  5737. return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
  5738. }
  5739. case 0x12: // int64
  5740. {
  5741. std::int64_t value;
  5742. return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
  5743. }
  5744. default: // anything else not supported (yet)
  5745. {
  5746. char cr[3];
  5747. (std::snprintf)(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
  5748. return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
  5749. }
  5750. }
  5751. }
  5752. /*!
  5753. @brief Read a BSON element list (as specified in the BSON-spec)
  5754. The same binary layout is used for objects and arrays, hence it must be
  5755. indicated with the argument @a is_array which one is expected
  5756. (true --> array, false --> object).
  5757. @param[in] is_array Determines if the element list being read is to be
  5758. treated as an object (@a is_array == false), or as an
  5759. array (@a is_array == true).
  5760. @return whether a valid BSON-object/array was passed to the SAX parser
  5761. */
  5762. bool parse_bson_element_list(const bool is_array)
  5763. {
  5764. string_t key;
  5765. while (int element_type = get())
  5766. {
  5767. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
  5768. {
  5769. return false;
  5770. }
  5771. const std::size_t element_type_parse_position = chars_read;
  5772. if (JSON_UNLIKELY(not get_bson_cstr(key)))
  5773. {
  5774. return false;
  5775. }
  5776. if (not is_array)
  5777. {
  5778. if (not sax->key(key))
  5779. {
  5780. return false;
  5781. }
  5782. }
  5783. if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
  5784. {
  5785. return false;
  5786. }
  5787. // get_bson_cstr only appends
  5788. key.clear();
  5789. }
  5790. return true;
  5791. }
  5792. /*!
  5793. @brief Reads an array from the BSON input and passes it to the SAX-parser.
  5794. @return whether a valid BSON-array was passed to the SAX parser
  5795. */
  5796. bool parse_bson_array()
  5797. {
  5798. std::int32_t document_size;
  5799. get_number<std::int32_t, true>(input_format_t::bson, document_size);
  5800. if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
  5801. {
  5802. return false;
  5803. }
  5804. if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
  5805. {
  5806. return false;
  5807. }
  5808. return sax->end_array();
  5809. }
  5810. //////////
  5811. // CBOR //
  5812. //////////
  5813. /*!
  5814. @param[in] get_char whether a new character should be retrieved from the
  5815. input (true, default) or whether the last read
  5816. character should be considered instead
  5817. @return whether a valid CBOR value was passed to the SAX parser
  5818. */
  5819. bool parse_cbor_internal(const bool get_char = true)
  5820. {
  5821. switch (get_char ? get() : current)
  5822. {
  5823. // EOF
  5824. case std::char_traits<char>::eof():
  5825. return unexpect_eof(input_format_t::cbor, "value");
  5826. // Integer 0x00..0x17 (0..23)
  5827. case 0x00:
  5828. case 0x01:
  5829. case 0x02:
  5830. case 0x03:
  5831. case 0x04:
  5832. case 0x05:
  5833. case 0x06:
  5834. case 0x07:
  5835. case 0x08:
  5836. case 0x09:
  5837. case 0x0A:
  5838. case 0x0B:
  5839. case 0x0C:
  5840. case 0x0D:
  5841. case 0x0E:
  5842. case 0x0F:
  5843. case 0x10:
  5844. case 0x11:
  5845. case 0x12:
  5846. case 0x13:
  5847. case 0x14:
  5848. case 0x15:
  5849. case 0x16:
  5850. case 0x17:
  5851. return sax->number_unsigned(static_cast<number_unsigned_t>(current));
  5852. case 0x18: // Unsigned integer (one-byte uint8_t follows)
  5853. {
  5854. uint8_t number;
  5855. return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
  5856. }
  5857. case 0x19: // Unsigned integer (two-byte uint16_t follows)
  5858. {
  5859. uint16_t number;
  5860. return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
  5861. }
  5862. case 0x1A: // Unsigned integer (four-byte uint32_t follows)
  5863. {
  5864. uint32_t number;
  5865. return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
  5866. }
  5867. case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
  5868. {
  5869. uint64_t number;
  5870. return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
  5871. }
  5872. // Negative integer -1-0x00..-1-0x17 (-1..-24)
  5873. case 0x20:
  5874. case 0x21:
  5875. case 0x22:
  5876. case 0x23:
  5877. case 0x24:
  5878. case 0x25:
  5879. case 0x26:
  5880. case 0x27:
  5881. case 0x28:
  5882. case 0x29:
  5883. case 0x2A:
  5884. case 0x2B:
  5885. case 0x2C:
  5886. case 0x2D:
  5887. case 0x2E:
  5888. case 0x2F:
  5889. case 0x30:
  5890. case 0x31:
  5891. case 0x32:
  5892. case 0x33:
  5893. case 0x34:
  5894. case 0x35:
  5895. case 0x36:
  5896. case 0x37:
  5897. return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
  5898. case 0x38: // Negative integer (one-byte uint8_t follows)
  5899. {
  5900. uint8_t number;
  5901. return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
  5902. }
  5903. case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
  5904. {
  5905. uint16_t number;
  5906. return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
  5907. }
  5908. case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
  5909. {
  5910. uint32_t number;
  5911. return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
  5912. }
  5913. case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
  5914. {
  5915. uint64_t number;
  5916. return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
  5917. - static_cast<number_integer_t>(number));
  5918. }
  5919. // UTF-8 string (0x00..0x17 bytes follow)
  5920. case 0x60:
  5921. case 0x61:
  5922. case 0x62:
  5923. case 0x63:
  5924. case 0x64:
  5925. case 0x65:
  5926. case 0x66:
  5927. case 0x67:
  5928. case 0x68:
  5929. case 0x69:
  5930. case 0x6A:
  5931. case 0x6B:
  5932. case 0x6C:
  5933. case 0x6D:
  5934. case 0x6E:
  5935. case 0x6F:
  5936. case 0x70:
  5937. case 0x71:
  5938. case 0x72:
  5939. case 0x73:
  5940. case 0x74:
  5941. case 0x75:
  5942. case 0x76:
  5943. case 0x77:
  5944. case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
  5945. case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
  5946. case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
  5947. case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
  5948. case 0x7F: // UTF-8 string (indefinite length)
  5949. {
  5950. string_t s;
  5951. return get_cbor_string(s) and sax->string(s);
  5952. }
  5953. // array (0x00..0x17 data items follow)
  5954. case 0x80:
  5955. case 0x81:
  5956. case 0x82:
  5957. case 0x83:
  5958. case 0x84:
  5959. case 0x85:
  5960. case 0x86:
  5961. case 0x87:
  5962. case 0x88:
  5963. case 0x89:
  5964. case 0x8A:
  5965. case 0x8B:
  5966. case 0x8C:
  5967. case 0x8D:
  5968. case 0x8E:
  5969. case 0x8F:
  5970. case 0x90:
  5971. case 0x91:
  5972. case 0x92:
  5973. case 0x93:
  5974. case 0x94:
  5975. case 0x95:
  5976. case 0x96:
  5977. case 0x97:
  5978. return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
  5979. case 0x98: // array (one-byte uint8_t for n follows)
  5980. {
  5981. uint8_t len;
  5982. return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
  5983. }
  5984. case 0x99: // array (two-byte uint16_t for n follow)
  5985. {
  5986. uint16_t len;
  5987. return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
  5988. }
  5989. case 0x9A: // array (four-byte uint32_t for n follow)
  5990. {
  5991. uint32_t len;
  5992. return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
  5993. }
  5994. case 0x9B: // array (eight-byte uint64_t for n follow)
  5995. {
  5996. uint64_t len;
  5997. return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
  5998. }
  5999. case 0x9F: // array (indefinite length)
  6000. return get_cbor_array(std::size_t(-1));
  6001. // map (0x00..0x17 pairs of data items follow)
  6002. case 0xA0:
  6003. case 0xA1:
  6004. case 0xA2:
  6005. case 0xA3:
  6006. case 0xA4:
  6007. case 0xA5:
  6008. case 0xA6:
  6009. case 0xA7:
  6010. case 0xA8:
  6011. case 0xA9:
  6012. case 0xAA:
  6013. case 0xAB:
  6014. case 0xAC:
  6015. case 0xAD:
  6016. case 0xAE:
  6017. case 0xAF:
  6018. case 0xB0:
  6019. case 0xB1:
  6020. case 0xB2:
  6021. case 0xB3:
  6022. case 0xB4:
  6023. case 0xB5:
  6024. case 0xB6:
  6025. case 0xB7:
  6026. return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
  6027. case 0xB8: // map (one-byte uint8_t for n follows)
  6028. {
  6029. uint8_t len;
  6030. return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
  6031. }
  6032. case 0xB9: // map (two-byte uint16_t for n follow)
  6033. {
  6034. uint16_t len;
  6035. return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
  6036. }
  6037. case 0xBA: // map (four-byte uint32_t for n follow)
  6038. {
  6039. uint32_t len;
  6040. return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
  6041. }
  6042. case 0xBB: // map (eight-byte uint64_t for n follow)
  6043. {
  6044. uint64_t len;
  6045. return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
  6046. }
  6047. case 0xBF: // map (indefinite length)
  6048. return get_cbor_object(std::size_t(-1));
  6049. case 0xF4: // false
  6050. return sax->boolean(false);
  6051. case 0xF5: // true
  6052. return sax->boolean(true);
  6053. case 0xF6: // null
  6054. return sax->null();
  6055. case 0xF9: // Half-Precision Float (two-byte IEEE 754)
  6056. {
  6057. const int byte1_raw = get();
  6058. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
  6059. {
  6060. return false;
  6061. }
  6062. const int byte2_raw = get();
  6063. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
  6064. {
  6065. return false;
  6066. }
  6067. const auto byte1 = static_cast<unsigned char>(byte1_raw);
  6068. const auto byte2 = static_cast<unsigned char>(byte2_raw);
  6069. // code from RFC 7049, Appendix D, Figure 3:
  6070. // As half-precision floating-point numbers were only added
  6071. // to IEEE 754 in 2008, today's programming platforms often
  6072. // still only have limited support for them. It is very
  6073. // easy to include at least decoding support for them even
  6074. // without such support. An example of a small decoder for
  6075. // half-precision floating-point numbers in the C language
  6076. // is shown in Fig. 3.
  6077. const int half = (byte1 << 8) + byte2;
  6078. const double val = [&half]
  6079. {
  6080. const int exp = (half >> 10) & 0x1F;
  6081. const int mant = half & 0x3FF;
  6082. assert(0 <= exp and exp <= 32);
  6083. assert(0 <= mant and mant <= 1024);
  6084. switch (exp)
  6085. {
  6086. case 0:
  6087. return std::ldexp(mant, -24);
  6088. case 31:
  6089. return (mant == 0)
  6090. ? std::numeric_limits<double>::infinity()
  6091. : std::numeric_limits<double>::quiet_NaN();
  6092. default:
  6093. return std::ldexp(mant + 1024, exp - 25);
  6094. }
  6095. }();
  6096. return sax->number_float((half & 0x8000) != 0
  6097. ? static_cast<number_float_t>(-val)
  6098. : static_cast<number_float_t>(val), "");
  6099. }
  6100. case 0xFA: // Single-Precision Float (four-byte IEEE 754)
  6101. {
  6102. float number;
  6103. return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6104. }
  6105. case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
  6106. {
  6107. double number;
  6108. return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6109. }
  6110. default: // anything else (0xFF is handled inside the other types)
  6111. {
  6112. auto last_token = get_token_string();
  6113. return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
  6114. }
  6115. }
  6116. }
  6117. /*!
  6118. @brief reads a CBOR string
  6119. This function first reads starting bytes to determine the expected
  6120. string length and then copies this number of bytes into a string.
  6121. Additionally, CBOR's strings with indefinite lengths are supported.
  6122. @param[out] result created string
  6123. @return whether string creation completed
  6124. */
  6125. bool get_cbor_string(string_t& result)
  6126. {
  6127. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
  6128. {
  6129. return false;
  6130. }
  6131. switch (current)
  6132. {
  6133. // UTF-8 string (0x00..0x17 bytes follow)
  6134. case 0x60:
  6135. case 0x61:
  6136. case 0x62:
  6137. case 0x63:
  6138. case 0x64:
  6139. case 0x65:
  6140. case 0x66:
  6141. case 0x67:
  6142. case 0x68:
  6143. case 0x69:
  6144. case 0x6A:
  6145. case 0x6B:
  6146. case 0x6C:
  6147. case 0x6D:
  6148. case 0x6E:
  6149. case 0x6F:
  6150. case 0x70:
  6151. case 0x71:
  6152. case 0x72:
  6153. case 0x73:
  6154. case 0x74:
  6155. case 0x75:
  6156. case 0x76:
  6157. case 0x77:
  6158. {
  6159. return get_string(input_format_t::cbor, current & 0x1F, result);
  6160. }
  6161. case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
  6162. {
  6163. uint8_t len;
  6164. return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
  6165. }
  6166. case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
  6167. {
  6168. uint16_t len;
  6169. return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
  6170. }
  6171. case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
  6172. {
  6173. uint32_t len;
  6174. return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
  6175. }
  6176. case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
  6177. {
  6178. uint64_t len;
  6179. return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
  6180. }
  6181. case 0x7F: // UTF-8 string (indefinite length)
  6182. {
  6183. while (get() != 0xFF)
  6184. {
  6185. string_t chunk;
  6186. if (not get_cbor_string(chunk))
  6187. {
  6188. return false;
  6189. }
  6190. result.append(chunk);
  6191. }
  6192. return true;
  6193. }
  6194. default:
  6195. {
  6196. auto last_token = get_token_string();
  6197. return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
  6198. }
  6199. }
  6200. }
  6201. /*!
  6202. @param[in] len the length of the array or std::size_t(-1) for an
  6203. array of indefinite size
  6204. @return whether array creation completed
  6205. */
  6206. bool get_cbor_array(const std::size_t len)
  6207. {
  6208. if (JSON_UNLIKELY(not sax->start_array(len)))
  6209. {
  6210. return false;
  6211. }
  6212. if (len != std::size_t(-1))
  6213. {
  6214. for (std::size_t i = 0; i < len; ++i)
  6215. {
  6216. if (JSON_UNLIKELY(not parse_cbor_internal()))
  6217. {
  6218. return false;
  6219. }
  6220. }
  6221. }
  6222. else
  6223. {
  6224. while (get() != 0xFF)
  6225. {
  6226. if (JSON_UNLIKELY(not parse_cbor_internal(false)))
  6227. {
  6228. return false;
  6229. }
  6230. }
  6231. }
  6232. return sax->end_array();
  6233. }
  6234. /*!
  6235. @param[in] len the length of the object or std::size_t(-1) for an
  6236. object of indefinite size
  6237. @return whether object creation completed
  6238. */
  6239. bool get_cbor_object(const std::size_t len)
  6240. {
  6241. if (not JSON_UNLIKELY(sax->start_object(len)))
  6242. {
  6243. return false;
  6244. }
  6245. string_t key;
  6246. if (len != std::size_t(-1))
  6247. {
  6248. for (std::size_t i = 0; i < len; ++i)
  6249. {
  6250. get();
  6251. if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
  6252. {
  6253. return false;
  6254. }
  6255. if (JSON_UNLIKELY(not parse_cbor_internal()))
  6256. {
  6257. return false;
  6258. }
  6259. key.clear();
  6260. }
  6261. }
  6262. else
  6263. {
  6264. while (get() != 0xFF)
  6265. {
  6266. if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
  6267. {
  6268. return false;
  6269. }
  6270. if (JSON_UNLIKELY(not parse_cbor_internal()))
  6271. {
  6272. return false;
  6273. }
  6274. key.clear();
  6275. }
  6276. }
  6277. return sax->end_object();
  6278. }
  6279. /////////////
  6280. // MsgPack //
  6281. /////////////
  6282. /*!
  6283. @return whether a valid MessagePack value was passed to the SAX parser
  6284. */
  6285. bool parse_msgpack_internal()
  6286. {
  6287. switch (get())
  6288. {
  6289. // EOF
  6290. case std::char_traits<char>::eof():
  6291. return unexpect_eof(input_format_t::msgpack, "value");
  6292. // positive fixint
  6293. case 0x00:
  6294. case 0x01:
  6295. case 0x02:
  6296. case 0x03:
  6297. case 0x04:
  6298. case 0x05:
  6299. case 0x06:
  6300. case 0x07:
  6301. case 0x08:
  6302. case 0x09:
  6303. case 0x0A:
  6304. case 0x0B:
  6305. case 0x0C:
  6306. case 0x0D:
  6307. case 0x0E:
  6308. case 0x0F:
  6309. case 0x10:
  6310. case 0x11:
  6311. case 0x12:
  6312. case 0x13:
  6313. case 0x14:
  6314. case 0x15:
  6315. case 0x16:
  6316. case 0x17:
  6317. case 0x18:
  6318. case 0x19:
  6319. case 0x1A:
  6320. case 0x1B:
  6321. case 0x1C:
  6322. case 0x1D:
  6323. case 0x1E:
  6324. case 0x1F:
  6325. case 0x20:
  6326. case 0x21:
  6327. case 0x22:
  6328. case 0x23:
  6329. case 0x24:
  6330. case 0x25:
  6331. case 0x26:
  6332. case 0x27:
  6333. case 0x28:
  6334. case 0x29:
  6335. case 0x2A:
  6336. case 0x2B:
  6337. case 0x2C:
  6338. case 0x2D:
  6339. case 0x2E:
  6340. case 0x2F:
  6341. case 0x30:
  6342. case 0x31:
  6343. case 0x32:
  6344. case 0x33:
  6345. case 0x34:
  6346. case 0x35:
  6347. case 0x36:
  6348. case 0x37:
  6349. case 0x38:
  6350. case 0x39:
  6351. case 0x3A:
  6352. case 0x3B:
  6353. case 0x3C:
  6354. case 0x3D:
  6355. case 0x3E:
  6356. case 0x3F:
  6357. case 0x40:
  6358. case 0x41:
  6359. case 0x42:
  6360. case 0x43:
  6361. case 0x44:
  6362. case 0x45:
  6363. case 0x46:
  6364. case 0x47:
  6365. case 0x48:
  6366. case 0x49:
  6367. case 0x4A:
  6368. case 0x4B:
  6369. case 0x4C:
  6370. case 0x4D:
  6371. case 0x4E:
  6372. case 0x4F:
  6373. case 0x50:
  6374. case 0x51:
  6375. case 0x52:
  6376. case 0x53:
  6377. case 0x54:
  6378. case 0x55:
  6379. case 0x56:
  6380. case 0x57:
  6381. case 0x58:
  6382. case 0x59:
  6383. case 0x5A:
  6384. case 0x5B:
  6385. case 0x5C:
  6386. case 0x5D:
  6387. case 0x5E:
  6388. case 0x5F:
  6389. case 0x60:
  6390. case 0x61:
  6391. case 0x62:
  6392. case 0x63:
  6393. case 0x64:
  6394. case 0x65:
  6395. case 0x66:
  6396. case 0x67:
  6397. case 0x68:
  6398. case 0x69:
  6399. case 0x6A:
  6400. case 0x6B:
  6401. case 0x6C:
  6402. case 0x6D:
  6403. case 0x6E:
  6404. case 0x6F:
  6405. case 0x70:
  6406. case 0x71:
  6407. case 0x72:
  6408. case 0x73:
  6409. case 0x74:
  6410. case 0x75:
  6411. case 0x76:
  6412. case 0x77:
  6413. case 0x78:
  6414. case 0x79:
  6415. case 0x7A:
  6416. case 0x7B:
  6417. case 0x7C:
  6418. case 0x7D:
  6419. case 0x7E:
  6420. case 0x7F:
  6421. return sax->number_unsigned(static_cast<number_unsigned_t>(current));
  6422. // fixmap
  6423. case 0x80:
  6424. case 0x81:
  6425. case 0x82:
  6426. case 0x83:
  6427. case 0x84:
  6428. case 0x85:
  6429. case 0x86:
  6430. case 0x87:
  6431. case 0x88:
  6432. case 0x89:
  6433. case 0x8A:
  6434. case 0x8B:
  6435. case 0x8C:
  6436. case 0x8D:
  6437. case 0x8E:
  6438. case 0x8F:
  6439. return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
  6440. // fixarray
  6441. case 0x90:
  6442. case 0x91:
  6443. case 0x92:
  6444. case 0x93:
  6445. case 0x94:
  6446. case 0x95:
  6447. case 0x96:
  6448. case 0x97:
  6449. case 0x98:
  6450. case 0x99:
  6451. case 0x9A:
  6452. case 0x9B:
  6453. case 0x9C:
  6454. case 0x9D:
  6455. case 0x9E:
  6456. case 0x9F:
  6457. return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
  6458. // fixstr
  6459. case 0xA0:
  6460. case 0xA1:
  6461. case 0xA2:
  6462. case 0xA3:
  6463. case 0xA4:
  6464. case 0xA5:
  6465. case 0xA6:
  6466. case 0xA7:
  6467. case 0xA8:
  6468. case 0xA9:
  6469. case 0xAA:
  6470. case 0xAB:
  6471. case 0xAC:
  6472. case 0xAD:
  6473. case 0xAE:
  6474. case 0xAF:
  6475. case 0xB0:
  6476. case 0xB1:
  6477. case 0xB2:
  6478. case 0xB3:
  6479. case 0xB4:
  6480. case 0xB5:
  6481. case 0xB6:
  6482. case 0xB7:
  6483. case 0xB8:
  6484. case 0xB9:
  6485. case 0xBA:
  6486. case 0xBB:
  6487. case 0xBC:
  6488. case 0xBD:
  6489. case 0xBE:
  6490. case 0xBF:
  6491. {
  6492. string_t s;
  6493. return get_msgpack_string(s) and sax->string(s);
  6494. }
  6495. case 0xC0: // nil
  6496. return sax->null();
  6497. case 0xC2: // false
  6498. return sax->boolean(false);
  6499. case 0xC3: // true
  6500. return sax->boolean(true);
  6501. case 0xCA: // float 32
  6502. {
  6503. float number;
  6504. return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6505. }
  6506. case 0xCB: // float 64
  6507. {
  6508. double number;
  6509. return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6510. }
  6511. case 0xCC: // uint 8
  6512. {
  6513. uint8_t number;
  6514. return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
  6515. }
  6516. case 0xCD: // uint 16
  6517. {
  6518. uint16_t number;
  6519. return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
  6520. }
  6521. case 0xCE: // uint 32
  6522. {
  6523. uint32_t number;
  6524. return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
  6525. }
  6526. case 0xCF: // uint 64
  6527. {
  6528. uint64_t number;
  6529. return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
  6530. }
  6531. case 0xD0: // int 8
  6532. {
  6533. int8_t number;
  6534. return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
  6535. }
  6536. case 0xD1: // int 16
  6537. {
  6538. int16_t number;
  6539. return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
  6540. }
  6541. case 0xD2: // int 32
  6542. {
  6543. int32_t number;
  6544. return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
  6545. }
  6546. case 0xD3: // int 64
  6547. {
  6548. int64_t number;
  6549. return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
  6550. }
  6551. case 0xD9: // str 8
  6552. case 0xDA: // str 16
  6553. case 0xDB: // str 32
  6554. {
  6555. string_t s;
  6556. return get_msgpack_string(s) and sax->string(s);
  6557. }
  6558. case 0xDC: // array 16
  6559. {
  6560. uint16_t len;
  6561. return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
  6562. }
  6563. case 0xDD: // array 32
  6564. {
  6565. uint32_t len;
  6566. return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
  6567. }
  6568. case 0xDE: // map 16
  6569. {
  6570. uint16_t len;
  6571. return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
  6572. }
  6573. case 0xDF: // map 32
  6574. {
  6575. uint32_t len;
  6576. return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
  6577. }
  6578. // negative fixint
  6579. case 0xE0:
  6580. case 0xE1:
  6581. case 0xE2:
  6582. case 0xE3:
  6583. case 0xE4:
  6584. case 0xE5:
  6585. case 0xE6:
  6586. case 0xE7:
  6587. case 0xE8:
  6588. case 0xE9:
  6589. case 0xEA:
  6590. case 0xEB:
  6591. case 0xEC:
  6592. case 0xED:
  6593. case 0xEE:
  6594. case 0xEF:
  6595. case 0xF0:
  6596. case 0xF1:
  6597. case 0xF2:
  6598. case 0xF3:
  6599. case 0xF4:
  6600. case 0xF5:
  6601. case 0xF6:
  6602. case 0xF7:
  6603. case 0xF8:
  6604. case 0xF9:
  6605. case 0xFA:
  6606. case 0xFB:
  6607. case 0xFC:
  6608. case 0xFD:
  6609. case 0xFE:
  6610. case 0xFF:
  6611. return sax->number_integer(static_cast<int8_t>(current));
  6612. default: // anything else
  6613. {
  6614. auto last_token = get_token_string();
  6615. return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
  6616. }
  6617. }
  6618. }
  6619. /*!
  6620. @brief reads a MessagePack string
  6621. This function first reads starting bytes to determine the expected
  6622. string length and then copies this number of bytes into a string.
  6623. @param[out] result created string
  6624. @return whether string creation completed
  6625. */
  6626. bool get_msgpack_string(string_t& result)
  6627. {
  6628. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
  6629. {
  6630. return false;
  6631. }
  6632. switch (current)
  6633. {
  6634. // fixstr
  6635. case 0xA0:
  6636. case 0xA1:
  6637. case 0xA2:
  6638. case 0xA3:
  6639. case 0xA4:
  6640. case 0xA5:
  6641. case 0xA6:
  6642. case 0xA7:
  6643. case 0xA8:
  6644. case 0xA9:
  6645. case 0xAA:
  6646. case 0xAB:
  6647. case 0xAC:
  6648. case 0xAD:
  6649. case 0xAE:
  6650. case 0xAF:
  6651. case 0xB0:
  6652. case 0xB1:
  6653. case 0xB2:
  6654. case 0xB3:
  6655. case 0xB4:
  6656. case 0xB5:
  6657. case 0xB6:
  6658. case 0xB7:
  6659. case 0xB8:
  6660. case 0xB9:
  6661. case 0xBA:
  6662. case 0xBB:
  6663. case 0xBC:
  6664. case 0xBD:
  6665. case 0xBE:
  6666. case 0xBF:
  6667. {
  6668. return get_string(input_format_t::msgpack, current & 0x1F, result);
  6669. }
  6670. case 0xD9: // str 8
  6671. {
  6672. uint8_t len;
  6673. return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
  6674. }
  6675. case 0xDA: // str 16
  6676. {
  6677. uint16_t len;
  6678. return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
  6679. }
  6680. case 0xDB: // str 32
  6681. {
  6682. uint32_t len;
  6683. return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
  6684. }
  6685. default:
  6686. {
  6687. auto last_token = get_token_string();
  6688. return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
  6689. }
  6690. }
  6691. }
  6692. /*!
  6693. @param[in] len the length of the array
  6694. @return whether array creation completed
  6695. */
  6696. bool get_msgpack_array(const std::size_t len)
  6697. {
  6698. if (JSON_UNLIKELY(not sax->start_array(len)))
  6699. {
  6700. return false;
  6701. }
  6702. for (std::size_t i = 0; i < len; ++i)
  6703. {
  6704. if (JSON_UNLIKELY(not parse_msgpack_internal()))
  6705. {
  6706. return false;
  6707. }
  6708. }
  6709. return sax->end_array();
  6710. }
  6711. /*!
  6712. @param[in] len the length of the object
  6713. @return whether object creation completed
  6714. */
  6715. bool get_msgpack_object(const std::size_t len)
  6716. {
  6717. if (JSON_UNLIKELY(not sax->start_object(len)))
  6718. {
  6719. return false;
  6720. }
  6721. string_t key;
  6722. for (std::size_t i = 0; i < len; ++i)
  6723. {
  6724. get();
  6725. if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
  6726. {
  6727. return false;
  6728. }
  6729. if (JSON_UNLIKELY(not parse_msgpack_internal()))
  6730. {
  6731. return false;
  6732. }
  6733. key.clear();
  6734. }
  6735. return sax->end_object();
  6736. }
  6737. ////////////
  6738. // UBJSON //
  6739. ////////////
  6740. /*!
  6741. @param[in] get_char whether a new character should be retrieved from the
  6742. input (true, default) or whether the last read
  6743. character should be considered instead
  6744. @return whether a valid UBJSON value was passed to the SAX parser
  6745. */
  6746. bool parse_ubjson_internal(const bool get_char = true)
  6747. {
  6748. return get_ubjson_value(get_char ? get_ignore_noop() : current);
  6749. }
  6750. /*!
  6751. @brief reads a UBJSON string
  6752. This function is either called after reading the 'S' byte explicitly
  6753. indicating a string, or in case of an object key where the 'S' byte can be
  6754. left out.
  6755. @param[out] result created string
  6756. @param[in] get_char whether a new character should be retrieved from the
  6757. input (true, default) or whether the last read
  6758. character should be considered instead
  6759. @return whether string creation completed
  6760. */
  6761. bool get_ubjson_string(string_t& result, const bool get_char = true)
  6762. {
  6763. if (get_char)
  6764. {
  6765. get(); // TODO: may we ignore N here?
  6766. }
  6767. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
  6768. {
  6769. return false;
  6770. }
  6771. switch (current)
  6772. {
  6773. case 'U':
  6774. {
  6775. uint8_t len;
  6776. return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
  6777. }
  6778. case 'i':
  6779. {
  6780. int8_t len;
  6781. return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
  6782. }
  6783. case 'I':
  6784. {
  6785. int16_t len;
  6786. return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
  6787. }
  6788. case 'l':
  6789. {
  6790. int32_t len;
  6791. return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
  6792. }
  6793. case 'L':
  6794. {
  6795. int64_t len;
  6796. return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
  6797. }
  6798. default:
  6799. auto last_token = get_token_string();
  6800. return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
  6801. }
  6802. }
  6803. /*!
  6804. @param[out] result determined size
  6805. @return whether size determination completed
  6806. */
  6807. bool get_ubjson_size_value(std::size_t& result)
  6808. {
  6809. switch (get_ignore_noop())
  6810. {
  6811. case 'U':
  6812. {
  6813. uint8_t number;
  6814. if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
  6815. {
  6816. return false;
  6817. }
  6818. result = static_cast<std::size_t>(number);
  6819. return true;
  6820. }
  6821. case 'i':
  6822. {
  6823. int8_t number;
  6824. if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
  6825. {
  6826. return false;
  6827. }
  6828. result = static_cast<std::size_t>(number);
  6829. return true;
  6830. }
  6831. case 'I':
  6832. {
  6833. int16_t number;
  6834. if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
  6835. {
  6836. return false;
  6837. }
  6838. result = static_cast<std::size_t>(number);
  6839. return true;
  6840. }
  6841. case 'l':
  6842. {
  6843. int32_t number;
  6844. if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
  6845. {
  6846. return false;
  6847. }
  6848. result = static_cast<std::size_t>(number);
  6849. return true;
  6850. }
  6851. case 'L':
  6852. {
  6853. int64_t number;
  6854. if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
  6855. {
  6856. return false;
  6857. }
  6858. result = static_cast<std::size_t>(number);
  6859. return true;
  6860. }
  6861. default:
  6862. {
  6863. auto last_token = get_token_string();
  6864. return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
  6865. }
  6866. }
  6867. }
  6868. /*!
  6869. @brief determine the type and size for a container
  6870. In the optimized UBJSON format, a type and a size can be provided to allow
  6871. for a more compact representation.
  6872. @param[out] result pair of the size and the type
  6873. @return whether pair creation completed
  6874. */
  6875. bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
  6876. {
  6877. result.first = string_t::npos; // size
  6878. result.second = 0; // type
  6879. get_ignore_noop();
  6880. if (current == '$')
  6881. {
  6882. result.second = get(); // must not ignore 'N', because 'N' maybe the type
  6883. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
  6884. {
  6885. return false;
  6886. }
  6887. get_ignore_noop();
  6888. if (JSON_UNLIKELY(current != '#'))
  6889. {
  6890. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
  6891. {
  6892. return false;
  6893. }
  6894. auto last_token = get_token_string();
  6895. return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
  6896. }
  6897. return get_ubjson_size_value(result.first);
  6898. }
  6899. else if (current == '#')
  6900. {
  6901. return get_ubjson_size_value(result.first);
  6902. }
  6903. return true;
  6904. }
  6905. /*!
  6906. @param prefix the previously read or set type prefix
  6907. @return whether value creation completed
  6908. */
  6909. bool get_ubjson_value(const int prefix)
  6910. {
  6911. switch (prefix)
  6912. {
  6913. case std::char_traits<char>::eof(): // EOF
  6914. return unexpect_eof(input_format_t::ubjson, "value");
  6915. case 'T': // true
  6916. return sax->boolean(true);
  6917. case 'F': // false
  6918. return sax->boolean(false);
  6919. case 'Z': // null
  6920. return sax->null();
  6921. case 'U':
  6922. {
  6923. uint8_t number;
  6924. return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
  6925. }
  6926. case 'i':
  6927. {
  6928. int8_t number;
  6929. return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
  6930. }
  6931. case 'I':
  6932. {
  6933. int16_t number;
  6934. return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
  6935. }
  6936. case 'l':
  6937. {
  6938. int32_t number;
  6939. return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
  6940. }
  6941. case 'L':
  6942. {
  6943. int64_t number;
  6944. return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
  6945. }
  6946. case 'd':
  6947. {
  6948. float number;
  6949. return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6950. }
  6951. case 'D':
  6952. {
  6953. double number;
  6954. return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
  6955. }
  6956. case 'C': // char
  6957. {
  6958. get();
  6959. if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
  6960. {
  6961. return false;
  6962. }
  6963. if (JSON_UNLIKELY(current > 127))
  6964. {
  6965. auto last_token = get_token_string();
  6966. return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
  6967. }
  6968. string_t s(1, static_cast<char>(current));
  6969. return sax->string(s);
  6970. }
  6971. case 'S': // string
  6972. {
  6973. string_t s;
  6974. return get_ubjson_string(s) and sax->string(s);
  6975. }
  6976. case '[': // array
  6977. return get_ubjson_array();
  6978. case '{': // object
  6979. return get_ubjson_object();
  6980. default: // anything else
  6981. {
  6982. auto last_token = get_token_string();
  6983. return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
  6984. }
  6985. }
  6986. }
  6987. /*!
  6988. @return whether array creation completed
  6989. */
  6990. bool get_ubjson_array()
  6991. {
  6992. std::pair<std::size_t, int> size_and_type;
  6993. if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
  6994. {
  6995. return false;
  6996. }
  6997. if (size_and_type.first != string_t::npos)
  6998. {
  6999. if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
  7000. {
  7001. return false;
  7002. }
  7003. if (size_and_type.second != 0)
  7004. {
  7005. if (size_and_type.second != 'N')
  7006. {
  7007. for (std::size_t i = 0; i < size_and_type.first; ++i)
  7008. {
  7009. if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
  7010. {
  7011. return false;
  7012. }
  7013. }
  7014. }
  7015. }
  7016. else
  7017. {
  7018. for (std::size_t i = 0; i < size_and_type.first; ++i)
  7019. {
  7020. if (JSON_UNLIKELY(not parse_ubjson_internal()))
  7021. {
  7022. return false;
  7023. }
  7024. }
  7025. }
  7026. }
  7027. else
  7028. {
  7029. if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
  7030. {
  7031. return false;
  7032. }
  7033. while (current != ']')
  7034. {
  7035. if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
  7036. {
  7037. return false;
  7038. }
  7039. get_ignore_noop();
  7040. }
  7041. }
  7042. return sax->end_array();
  7043. }
  7044. /*!
  7045. @return whether object creation completed
  7046. */
  7047. bool get_ubjson_object()
  7048. {
  7049. std::pair<std::size_t, int> size_and_type;
  7050. if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
  7051. {
  7052. return false;
  7053. }
  7054. string_t key;
  7055. if (size_and_type.first != string_t::npos)
  7056. {
  7057. if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
  7058. {
  7059. return false;
  7060. }
  7061. if (size_and_type.second != 0)
  7062. {
  7063. for (std::size_t i = 0; i < size_and_type.first; ++i)
  7064. {
  7065. if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
  7066. {
  7067. return false;
  7068. }
  7069. if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
  7070. {
  7071. return false;
  7072. }
  7073. key.clear();
  7074. }
  7075. }
  7076. else
  7077. {
  7078. for (std::size_t i = 0; i < size_and_type.first; ++i)
  7079. {
  7080. if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
  7081. {
  7082. return false;
  7083. }
  7084. if (JSON_UNLIKELY(not parse_ubjson_internal()))
  7085. {
  7086. return false;
  7087. }
  7088. key.clear();
  7089. }
  7090. }
  7091. }
  7092. else
  7093. {
  7094. if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
  7095. {
  7096. return false;
  7097. }
  7098. while (current != '}')
  7099. {
  7100. if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
  7101. {
  7102. return false;
  7103. }
  7104. if (JSON_UNLIKELY(not parse_ubjson_internal()))
  7105. {
  7106. return false;
  7107. }
  7108. get_ignore_noop();
  7109. key.clear();
  7110. }
  7111. }
  7112. return sax->end_object();
  7113. }
  7114. ///////////////////////
  7115. // Utility functions //
  7116. ///////////////////////
  7117. /*!
  7118. @brief get next character from the input
  7119. This function provides the interface to the used input adapter. It does
  7120. not throw in case the input reached EOF, but returns a -'ve valued
  7121. `std::char_traits<char>::eof()` in that case.
  7122. @return character read from the input
  7123. */
  7124. int get()
  7125. {
  7126. ++chars_read;
  7127. return (current = ia->get_character());
  7128. }
  7129. /*!
  7130. @return character read from the input after ignoring all 'N' entries
  7131. */
  7132. int get_ignore_noop()
  7133. {
  7134. do
  7135. {
  7136. get();
  7137. }
  7138. while (current == 'N');
  7139. return current;
  7140. }
  7141. /*
  7142. @brief read a number from the input
  7143. @tparam NumberType the type of the number
  7144. @param[in] format the current format (for diagnostics)
  7145. @param[out] result number of type @a NumberType
  7146. @return whether conversion completed
  7147. @note This function needs to respect the system's endianess, because
  7148. bytes in CBOR, MessagePack, and UBJSON are stored in network order
  7149. (big endian) and therefore need reordering on little endian systems.
  7150. */
  7151. template<typename NumberType, bool InputIsLittleEndian = false>
  7152. bool get_number(const input_format_t format, NumberType& result)
  7153. {
  7154. // step 1: read input into array with system's byte order
  7155. std::array<uint8_t, sizeof(NumberType)> vec;
  7156. for (std::size_t i = 0; i < sizeof(NumberType); ++i)
  7157. {
  7158. get();
  7159. if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
  7160. {
  7161. return false;
  7162. }
  7163. // reverse byte order prior to conversion if necessary
  7164. if (is_little_endian && !InputIsLittleEndian)
  7165. {
  7166. vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
  7167. }
  7168. else
  7169. {
  7170. vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
  7171. }
  7172. }
  7173. // step 2: convert array into number of type T and return
  7174. std::memcpy(&result, vec.data(), sizeof(NumberType));
  7175. return true;
  7176. }
  7177. /*!
  7178. @brief create a string by reading characters from the input
  7179. @tparam NumberType the type of the number
  7180. @param[in] format the current format (for diagnostics)
  7181. @param[in] len number of characters to read
  7182. @param[out] result string created by reading @a len bytes
  7183. @return whether string creation completed
  7184. @note We can not reserve @a len bytes for the result, because @a len
  7185. may be too large. Usually, @ref unexpect_eof() detects the end of
  7186. the input before we run out of string memory.
  7187. */
  7188. template<typename NumberType>
  7189. bool get_string(const input_format_t format,
  7190. const NumberType len,
  7191. string_t& result)
  7192. {
  7193. bool success = true;
  7194. std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
  7195. {
  7196. get();
  7197. if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
  7198. {
  7199. success = false;
  7200. }
  7201. return static_cast<char>(current);
  7202. });
  7203. return success;
  7204. }
  7205. /*!
  7206. @param[in] format the current format (for diagnostics)
  7207. @param[in] context further context information (for diagnostics)
  7208. @return whether the last read character is not EOF
  7209. */
  7210. bool unexpect_eof(const input_format_t format, const char* context) const
  7211. {
  7212. if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
  7213. {
  7214. return sax->parse_error(chars_read, "<end of file>",
  7215. parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
  7216. }
  7217. return true;
  7218. }
  7219. /*!
  7220. @return a string representation of the last read byte
  7221. */
  7222. std::string get_token_string() const
  7223. {
  7224. char cr[3];
  7225. (std::snprintf)(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
  7226. return std::string{cr};
  7227. }
  7228. /*!
  7229. @param[in] format the current format
  7230. @param[in] detail a detailed error message
  7231. @param[in] context further contect information
  7232. @return a message string to use in the parse_error exceptions
  7233. */
  7234. std::string exception_message(const input_format_t format,
  7235. const std::string& detail,
  7236. const std::string& context) const
  7237. {
  7238. std::string error_msg = "syntax error while parsing ";
  7239. switch (format)
  7240. {
  7241. case input_format_t::cbor:
  7242. error_msg += "CBOR";
  7243. break;
  7244. case input_format_t::msgpack:
  7245. error_msg += "MessagePack";
  7246. break;
  7247. case input_format_t::ubjson:
  7248. error_msg += "UBJSON";
  7249. break;
  7250. case input_format_t::bson:
  7251. error_msg += "BSON";
  7252. break;
  7253. // LCOV_EXCL_START
  7254. default:
  7255. assert(false);
  7256. // LCOV_EXCL_STOP
  7257. }
  7258. return error_msg + " " + context + ": " + detail;
  7259. }
  7260. private:
  7261. /// input adapter
  7262. input_adapter_t ia = nullptr;
  7263. /// the current character
  7264. int current = std::char_traits<char>::eof();
  7265. /// the number of characters read
  7266. std::size_t chars_read = 0;
  7267. /// whether we can assume little endianess
  7268. const bool is_little_endian = little_endianess();
  7269. /// the SAX parser
  7270. json_sax_t* sax = nullptr;
  7271. };
  7272. } // namespace detail
  7273. } // namespace nlohmann
  7274. // #include <nlohmann/detail/output/binary_writer.hpp>
  7275. #include <algorithm> // reverse
  7276. #include <array> // array
  7277. #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
  7278. #include <cstring> // memcpy
  7279. #include <limits> // numeric_limits
  7280. // #include <nlohmann/detail/input/binary_reader.hpp>
  7281. // #include <nlohmann/detail/output/output_adapters.hpp>
  7282. namespace nlohmann
  7283. {
  7284. namespace detail
  7285. {
  7286. ///////////////////
  7287. // binary writer //
  7288. ///////////////////
  7289. /*!
  7290. @brief serialization to CBOR and MessagePack values
  7291. */
  7292. template<typename BasicJsonType, typename CharType>
  7293. class binary_writer
  7294. {
  7295. using string_t = typename BasicJsonType::string_t;
  7296. public:
  7297. /*!
  7298. @brief create a binary writer
  7299. @param[in] adapter output adapter to write to
  7300. */
  7301. explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
  7302. {
  7303. assert(oa);
  7304. }
  7305. /*!
  7306. @param[in] j JSON value to serialize
  7307. @pre j.type() == value_t::object
  7308. */
  7309. void write_bson(const BasicJsonType& j)
  7310. {
  7311. switch (j.type())
  7312. {
  7313. case value_t::object:
  7314. {
  7315. write_bson_object(*j.m_value.object);
  7316. break;
  7317. }
  7318. default:
  7319. {
  7320. JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
  7321. }
  7322. }
  7323. }
  7324. /*!
  7325. @param[in] j JSON value to serialize
  7326. */
  7327. void write_cbor(const BasicJsonType& j)
  7328. {
  7329. switch (j.type())
  7330. {
  7331. case value_t::null:
  7332. {
  7333. oa->write_character(to_char_type(0xF6));
  7334. break;
  7335. }
  7336. case value_t::boolean:
  7337. {
  7338. oa->write_character(j.m_value.boolean
  7339. ? to_char_type(0xF5)
  7340. : to_char_type(0xF4));
  7341. break;
  7342. }
  7343. case value_t::number_integer:
  7344. {
  7345. if (j.m_value.number_integer >= 0)
  7346. {
  7347. // CBOR does not differentiate between positive signed
  7348. // integers and unsigned integers. Therefore, we used the
  7349. // code from the value_t::number_unsigned case here.
  7350. if (j.m_value.number_integer <= 0x17)
  7351. {
  7352. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7353. }
  7354. else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
  7355. {
  7356. oa->write_character(to_char_type(0x18));
  7357. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7358. }
  7359. else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
  7360. {
  7361. oa->write_character(to_char_type(0x19));
  7362. write_number(static_cast<uint16_t>(j.m_value.number_integer));
  7363. }
  7364. else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
  7365. {
  7366. oa->write_character(to_char_type(0x1A));
  7367. write_number(static_cast<uint32_t>(j.m_value.number_integer));
  7368. }
  7369. else
  7370. {
  7371. oa->write_character(to_char_type(0x1B));
  7372. write_number(static_cast<uint64_t>(j.m_value.number_integer));
  7373. }
  7374. }
  7375. else
  7376. {
  7377. // The conversions below encode the sign in the first
  7378. // byte, and the value is converted to a positive number.
  7379. const auto positive_number = -1 - j.m_value.number_integer;
  7380. if (j.m_value.number_integer >= -24)
  7381. {
  7382. write_number(static_cast<uint8_t>(0x20 + positive_number));
  7383. }
  7384. else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
  7385. {
  7386. oa->write_character(to_char_type(0x38));
  7387. write_number(static_cast<uint8_t>(positive_number));
  7388. }
  7389. else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
  7390. {
  7391. oa->write_character(to_char_type(0x39));
  7392. write_number(static_cast<uint16_t>(positive_number));
  7393. }
  7394. else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
  7395. {
  7396. oa->write_character(to_char_type(0x3A));
  7397. write_number(static_cast<uint32_t>(positive_number));
  7398. }
  7399. else
  7400. {
  7401. oa->write_character(to_char_type(0x3B));
  7402. write_number(static_cast<uint64_t>(positive_number));
  7403. }
  7404. }
  7405. break;
  7406. }
  7407. case value_t::number_unsigned:
  7408. {
  7409. if (j.m_value.number_unsigned <= 0x17)
  7410. {
  7411. write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
  7412. }
  7413. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
  7414. {
  7415. oa->write_character(to_char_type(0x18));
  7416. write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
  7417. }
  7418. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
  7419. {
  7420. oa->write_character(to_char_type(0x19));
  7421. write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
  7422. }
  7423. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
  7424. {
  7425. oa->write_character(to_char_type(0x1A));
  7426. write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
  7427. }
  7428. else
  7429. {
  7430. oa->write_character(to_char_type(0x1B));
  7431. write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
  7432. }
  7433. break;
  7434. }
  7435. case value_t::number_float:
  7436. {
  7437. oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
  7438. write_number(j.m_value.number_float);
  7439. break;
  7440. }
  7441. case value_t::string:
  7442. {
  7443. // step 1: write control byte and the string length
  7444. const auto N = j.m_value.string->size();
  7445. if (N <= 0x17)
  7446. {
  7447. write_number(static_cast<uint8_t>(0x60 + N));
  7448. }
  7449. else if (N <= (std::numeric_limits<uint8_t>::max)())
  7450. {
  7451. oa->write_character(to_char_type(0x78));
  7452. write_number(static_cast<uint8_t>(N));
  7453. }
  7454. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7455. {
  7456. oa->write_character(to_char_type(0x79));
  7457. write_number(static_cast<uint16_t>(N));
  7458. }
  7459. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7460. {
  7461. oa->write_character(to_char_type(0x7A));
  7462. write_number(static_cast<uint32_t>(N));
  7463. }
  7464. // LCOV_EXCL_START
  7465. else if (N <= (std::numeric_limits<uint64_t>::max)())
  7466. {
  7467. oa->write_character(to_char_type(0x7B));
  7468. write_number(static_cast<uint64_t>(N));
  7469. }
  7470. // LCOV_EXCL_STOP
  7471. // step 2: write the string
  7472. oa->write_characters(
  7473. reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
  7474. j.m_value.string->size());
  7475. break;
  7476. }
  7477. case value_t::array:
  7478. {
  7479. // step 1: write control byte and the array size
  7480. const auto N = j.m_value.array->size();
  7481. if (N <= 0x17)
  7482. {
  7483. write_number(static_cast<uint8_t>(0x80 + N));
  7484. }
  7485. else if (N <= (std::numeric_limits<uint8_t>::max)())
  7486. {
  7487. oa->write_character(to_char_type(0x98));
  7488. write_number(static_cast<uint8_t>(N));
  7489. }
  7490. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7491. {
  7492. oa->write_character(to_char_type(0x99));
  7493. write_number(static_cast<uint16_t>(N));
  7494. }
  7495. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7496. {
  7497. oa->write_character(to_char_type(0x9A));
  7498. write_number(static_cast<uint32_t>(N));
  7499. }
  7500. // LCOV_EXCL_START
  7501. else if (N <= (std::numeric_limits<uint64_t>::max)())
  7502. {
  7503. oa->write_character(to_char_type(0x9B));
  7504. write_number(static_cast<uint64_t>(N));
  7505. }
  7506. // LCOV_EXCL_STOP
  7507. // step 2: write each element
  7508. for (const auto& el : *j.m_value.array)
  7509. {
  7510. write_cbor(el);
  7511. }
  7512. break;
  7513. }
  7514. case value_t::object:
  7515. {
  7516. // step 1: write control byte and the object size
  7517. const auto N = j.m_value.object->size();
  7518. if (N <= 0x17)
  7519. {
  7520. write_number(static_cast<uint8_t>(0xA0 + N));
  7521. }
  7522. else if (N <= (std::numeric_limits<uint8_t>::max)())
  7523. {
  7524. oa->write_character(to_char_type(0xB8));
  7525. write_number(static_cast<uint8_t>(N));
  7526. }
  7527. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7528. {
  7529. oa->write_character(to_char_type(0xB9));
  7530. write_number(static_cast<uint16_t>(N));
  7531. }
  7532. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7533. {
  7534. oa->write_character(to_char_type(0xBA));
  7535. write_number(static_cast<uint32_t>(N));
  7536. }
  7537. // LCOV_EXCL_START
  7538. else if (N <= (std::numeric_limits<uint64_t>::max)())
  7539. {
  7540. oa->write_character(to_char_type(0xBB));
  7541. write_number(static_cast<uint64_t>(N));
  7542. }
  7543. // LCOV_EXCL_STOP
  7544. // step 2: write each element
  7545. for (const auto& el : *j.m_value.object)
  7546. {
  7547. write_cbor(el.first);
  7548. write_cbor(el.second);
  7549. }
  7550. break;
  7551. }
  7552. default:
  7553. break;
  7554. }
  7555. }
  7556. /*!
  7557. @param[in] j JSON value to serialize
  7558. */
  7559. void write_msgpack(const BasicJsonType& j)
  7560. {
  7561. switch (j.type())
  7562. {
  7563. case value_t::null: // nil
  7564. {
  7565. oa->write_character(to_char_type(0xC0));
  7566. break;
  7567. }
  7568. case value_t::boolean: // true and false
  7569. {
  7570. oa->write_character(j.m_value.boolean
  7571. ? to_char_type(0xC3)
  7572. : to_char_type(0xC2));
  7573. break;
  7574. }
  7575. case value_t::number_integer:
  7576. {
  7577. if (j.m_value.number_integer >= 0)
  7578. {
  7579. // MessagePack does not differentiate between positive
  7580. // signed integers and unsigned integers. Therefore, we used
  7581. // the code from the value_t::number_unsigned case here.
  7582. if (j.m_value.number_unsigned < 128)
  7583. {
  7584. // positive fixnum
  7585. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7586. }
  7587. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
  7588. {
  7589. // uint 8
  7590. oa->write_character(to_char_type(0xCC));
  7591. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7592. }
  7593. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
  7594. {
  7595. // uint 16
  7596. oa->write_character(to_char_type(0xCD));
  7597. write_number(static_cast<uint16_t>(j.m_value.number_integer));
  7598. }
  7599. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
  7600. {
  7601. // uint 32
  7602. oa->write_character(to_char_type(0xCE));
  7603. write_number(static_cast<uint32_t>(j.m_value.number_integer));
  7604. }
  7605. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
  7606. {
  7607. // uint 64
  7608. oa->write_character(to_char_type(0xCF));
  7609. write_number(static_cast<uint64_t>(j.m_value.number_integer));
  7610. }
  7611. }
  7612. else
  7613. {
  7614. if (j.m_value.number_integer >= -32)
  7615. {
  7616. // negative fixnum
  7617. write_number(static_cast<int8_t>(j.m_value.number_integer));
  7618. }
  7619. else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
  7620. j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
  7621. {
  7622. // int 8
  7623. oa->write_character(to_char_type(0xD0));
  7624. write_number(static_cast<int8_t>(j.m_value.number_integer));
  7625. }
  7626. else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
  7627. j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
  7628. {
  7629. // int 16
  7630. oa->write_character(to_char_type(0xD1));
  7631. write_number(static_cast<int16_t>(j.m_value.number_integer));
  7632. }
  7633. else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
  7634. j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
  7635. {
  7636. // int 32
  7637. oa->write_character(to_char_type(0xD2));
  7638. write_number(static_cast<int32_t>(j.m_value.number_integer));
  7639. }
  7640. else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
  7641. j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
  7642. {
  7643. // int 64
  7644. oa->write_character(to_char_type(0xD3));
  7645. write_number(static_cast<int64_t>(j.m_value.number_integer));
  7646. }
  7647. }
  7648. break;
  7649. }
  7650. case value_t::number_unsigned:
  7651. {
  7652. if (j.m_value.number_unsigned < 128)
  7653. {
  7654. // positive fixnum
  7655. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7656. }
  7657. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
  7658. {
  7659. // uint 8
  7660. oa->write_character(to_char_type(0xCC));
  7661. write_number(static_cast<uint8_t>(j.m_value.number_integer));
  7662. }
  7663. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
  7664. {
  7665. // uint 16
  7666. oa->write_character(to_char_type(0xCD));
  7667. write_number(static_cast<uint16_t>(j.m_value.number_integer));
  7668. }
  7669. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
  7670. {
  7671. // uint 32
  7672. oa->write_character(to_char_type(0xCE));
  7673. write_number(static_cast<uint32_t>(j.m_value.number_integer));
  7674. }
  7675. else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
  7676. {
  7677. // uint 64
  7678. oa->write_character(to_char_type(0xCF));
  7679. write_number(static_cast<uint64_t>(j.m_value.number_integer));
  7680. }
  7681. break;
  7682. }
  7683. case value_t::number_float:
  7684. {
  7685. oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
  7686. write_number(j.m_value.number_float);
  7687. break;
  7688. }
  7689. case value_t::string:
  7690. {
  7691. // step 1: write control byte and the string length
  7692. const auto N = j.m_value.string->size();
  7693. if (N <= 31)
  7694. {
  7695. // fixstr
  7696. write_number(static_cast<uint8_t>(0xA0 | N));
  7697. }
  7698. else if (N <= (std::numeric_limits<uint8_t>::max)())
  7699. {
  7700. // str 8
  7701. oa->write_character(to_char_type(0xD9));
  7702. write_number(static_cast<uint8_t>(N));
  7703. }
  7704. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7705. {
  7706. // str 16
  7707. oa->write_character(to_char_type(0xDA));
  7708. write_number(static_cast<uint16_t>(N));
  7709. }
  7710. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7711. {
  7712. // str 32
  7713. oa->write_character(to_char_type(0xDB));
  7714. write_number(static_cast<uint32_t>(N));
  7715. }
  7716. // step 2: write the string
  7717. oa->write_characters(
  7718. reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
  7719. j.m_value.string->size());
  7720. break;
  7721. }
  7722. case value_t::array:
  7723. {
  7724. // step 1: write control byte and the array size
  7725. const auto N = j.m_value.array->size();
  7726. if (N <= 15)
  7727. {
  7728. // fixarray
  7729. write_number(static_cast<uint8_t>(0x90 | N));
  7730. }
  7731. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7732. {
  7733. // array 16
  7734. oa->write_character(to_char_type(0xDC));
  7735. write_number(static_cast<uint16_t>(N));
  7736. }
  7737. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7738. {
  7739. // array 32
  7740. oa->write_character(to_char_type(0xDD));
  7741. write_number(static_cast<uint32_t>(N));
  7742. }
  7743. // step 2: write each element
  7744. for (const auto& el : *j.m_value.array)
  7745. {
  7746. write_msgpack(el);
  7747. }
  7748. break;
  7749. }
  7750. case value_t::object:
  7751. {
  7752. // step 1: write control byte and the object size
  7753. const auto N = j.m_value.object->size();
  7754. if (N <= 15)
  7755. {
  7756. // fixmap
  7757. write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
  7758. }
  7759. else if (N <= (std::numeric_limits<uint16_t>::max)())
  7760. {
  7761. // map 16
  7762. oa->write_character(to_char_type(0xDE));
  7763. write_number(static_cast<uint16_t>(N));
  7764. }
  7765. else if (N <= (std::numeric_limits<uint32_t>::max)())
  7766. {
  7767. // map 32
  7768. oa->write_character(to_char_type(0xDF));
  7769. write_number(static_cast<uint32_t>(N));
  7770. }
  7771. // step 2: write each element
  7772. for (const auto& el : *j.m_value.object)
  7773. {
  7774. write_msgpack(el.first);
  7775. write_msgpack(el.second);
  7776. }
  7777. break;
  7778. }
  7779. default:
  7780. break;
  7781. }
  7782. }
  7783. /*!
  7784. @param[in] j JSON value to serialize
  7785. @param[in] use_count whether to use '#' prefixes (optimized format)
  7786. @param[in] use_type whether to use '$' prefixes (optimized format)
  7787. @param[in] add_prefix whether prefixes need to be used for this value
  7788. */
  7789. void write_ubjson(const BasicJsonType& j, const bool use_count,
  7790. const bool use_type, const bool add_prefix = true)
  7791. {
  7792. switch (j.type())
  7793. {
  7794. case value_t::null:
  7795. {
  7796. if (add_prefix)
  7797. {
  7798. oa->write_character(to_char_type('Z'));
  7799. }
  7800. break;
  7801. }
  7802. case value_t::boolean:
  7803. {
  7804. if (add_prefix)
  7805. {
  7806. oa->write_character(j.m_value.boolean
  7807. ? to_char_type('T')
  7808. : to_char_type('F'));
  7809. }
  7810. break;
  7811. }
  7812. case value_t::number_integer:
  7813. {
  7814. write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
  7815. break;
  7816. }
  7817. case value_t::number_unsigned:
  7818. {
  7819. write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
  7820. break;
  7821. }
  7822. case value_t::number_float:
  7823. {
  7824. write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
  7825. break;
  7826. }
  7827. case value_t::string:
  7828. {
  7829. if (add_prefix)
  7830. {
  7831. oa->write_character(to_char_type('S'));
  7832. }
  7833. write_number_with_ubjson_prefix(j.m_value.string->size(), true);
  7834. oa->write_characters(
  7835. reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
  7836. j.m_value.string->size());
  7837. break;
  7838. }
  7839. case value_t::array:
  7840. {
  7841. if (add_prefix)
  7842. {
  7843. oa->write_character(to_char_type('['));
  7844. }
  7845. bool prefix_required = true;
  7846. if (use_type and not j.m_value.array->empty())
  7847. {
  7848. assert(use_count);
  7849. const CharType first_prefix = ubjson_prefix(j.front());
  7850. const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
  7851. [this, first_prefix](const BasicJsonType & v)
  7852. {
  7853. return ubjson_prefix(v) == first_prefix;
  7854. });
  7855. if (same_prefix)
  7856. {
  7857. prefix_required = false;
  7858. oa->write_character(to_char_type('$'));
  7859. oa->write_character(first_prefix);
  7860. }
  7861. }
  7862. if (use_count)
  7863. {
  7864. oa->write_character(to_char_type('#'));
  7865. write_number_with_ubjson_prefix(j.m_value.array->size(), true);
  7866. }
  7867. for (const auto& el : *j.m_value.array)
  7868. {
  7869. write_ubjson(el, use_count, use_type, prefix_required);
  7870. }
  7871. if (not use_count)
  7872. {
  7873. oa->write_character(to_char_type(']'));
  7874. }
  7875. break;
  7876. }
  7877. case value_t::object:
  7878. {
  7879. if (add_prefix)
  7880. {
  7881. oa->write_character(to_char_type('{'));
  7882. }
  7883. bool prefix_required = true;
  7884. if (use_type and not j.m_value.object->empty())
  7885. {
  7886. assert(use_count);
  7887. const CharType first_prefix = ubjson_prefix(j.front());
  7888. const bool same_prefix = std::all_of(j.begin(), j.end(),
  7889. [this, first_prefix](const BasicJsonType & v)
  7890. {
  7891. return ubjson_prefix(v) == first_prefix;
  7892. });
  7893. if (same_prefix)
  7894. {
  7895. prefix_required = false;
  7896. oa->write_character(to_char_type('$'));
  7897. oa->write_character(first_prefix);
  7898. }
  7899. }
  7900. if (use_count)
  7901. {
  7902. oa->write_character(to_char_type('#'));
  7903. write_number_with_ubjson_prefix(j.m_value.object->size(), true);
  7904. }
  7905. for (const auto& el : *j.m_value.object)
  7906. {
  7907. write_number_with_ubjson_prefix(el.first.size(), true);
  7908. oa->write_characters(
  7909. reinterpret_cast<const CharType*>(el.first.c_str()),
  7910. el.first.size());
  7911. write_ubjson(el.second, use_count, use_type, prefix_required);
  7912. }
  7913. if (not use_count)
  7914. {
  7915. oa->write_character(to_char_type('}'));
  7916. }
  7917. break;
  7918. }
  7919. default:
  7920. break;
  7921. }
  7922. }
  7923. private:
  7924. //////////
  7925. // BSON //
  7926. //////////
  7927. /*!
  7928. @return The size of a BSON document entry header, including the id marker
  7929. and the entry name size (and its null-terminator).
  7930. */
  7931. static std::size_t calc_bson_entry_header_size(const string_t& name)
  7932. {
  7933. const auto it = name.find(static_cast<typename string_t::value_type>(0));
  7934. if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
  7935. {
  7936. JSON_THROW(out_of_range::create(409,
  7937. "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
  7938. }
  7939. return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
  7940. }
  7941. /*!
  7942. @brief Writes the given @a element_type and @a name to the output adapter
  7943. */
  7944. void write_bson_entry_header(const string_t& name,
  7945. const std::uint8_t element_type)
  7946. {
  7947. oa->write_character(to_char_type(element_type)); // boolean
  7948. oa->write_characters(
  7949. reinterpret_cast<const CharType*>(name.c_str()),
  7950. name.size() + 1u);
  7951. }
  7952. /*!
  7953. @brief Writes a BSON element with key @a name and boolean value @a value
  7954. */
  7955. void write_bson_boolean(const string_t& name,
  7956. const bool value)
  7957. {
  7958. write_bson_entry_header(name, 0x08);
  7959. oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
  7960. }
  7961. /*!
  7962. @brief Writes a BSON element with key @a name and double value @a value
  7963. */
  7964. void write_bson_double(const string_t& name,
  7965. const double value)
  7966. {
  7967. write_bson_entry_header(name, 0x01);
  7968. write_number<double, true>(value);
  7969. }
  7970. /*!
  7971. @return The size of the BSON-encoded string in @a value
  7972. */
  7973. static std::size_t calc_bson_string_size(const string_t& value)
  7974. {
  7975. return sizeof(std::int32_t) + value.size() + 1ul;
  7976. }
  7977. /*!
  7978. @brief Writes a BSON element with key @a name and string value @a value
  7979. */
  7980. void write_bson_string(const string_t& name,
  7981. const string_t& value)
  7982. {
  7983. write_bson_entry_header(name, 0x02);
  7984. write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
  7985. oa->write_characters(
  7986. reinterpret_cast<const CharType*>(value.c_str()),
  7987. value.size() + 1);
  7988. }
  7989. /*!
  7990. @brief Writes a BSON element with key @a name and null value
  7991. */
  7992. void write_bson_null(const string_t& name)
  7993. {
  7994. write_bson_entry_header(name, 0x0A);
  7995. }
  7996. /*!
  7997. @return The size of the BSON-encoded integer @a value
  7998. */
  7999. static std::size_t calc_bson_integer_size(const std::int64_t value)
  8000. {
  8001. if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
  8002. {
  8003. return sizeof(std::int32_t);
  8004. }
  8005. else
  8006. {
  8007. return sizeof(std::int64_t);
  8008. }
  8009. }
  8010. /*!
  8011. @brief Writes a BSON element with key @a name and integer @a value
  8012. */
  8013. void write_bson_integer(const string_t& name,
  8014. const std::int64_t value)
  8015. {
  8016. if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
  8017. {
  8018. write_bson_entry_header(name, 0x10); // int32
  8019. write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
  8020. }
  8021. else
  8022. {
  8023. write_bson_entry_header(name, 0x12); // int64
  8024. write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
  8025. }
  8026. }
  8027. /*!
  8028. @return The size of the BSON-encoded unsigned integer in @a j
  8029. */
  8030. static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
  8031. {
  8032. return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  8033. ? sizeof(std::int32_t)
  8034. : sizeof(std::int64_t);
  8035. }
  8036. /*!
  8037. @brief Writes a BSON element with key @a name and unsigned @a value
  8038. */
  8039. void write_bson_unsigned(const string_t& name,
  8040. const std::uint64_t value)
  8041. {
  8042. if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  8043. {
  8044. write_bson_entry_header(name, 0x10 /* int32 */);
  8045. write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
  8046. }
  8047. else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
  8048. {
  8049. write_bson_entry_header(name, 0x12 /* int64 */);
  8050. write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
  8051. }
  8052. else
  8053. {
  8054. JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
  8055. }
  8056. }
  8057. /*!
  8058. @brief Writes a BSON element with key @a name and object @a value
  8059. */
  8060. void write_bson_object_entry(const string_t& name,
  8061. const typename BasicJsonType::object_t& value)
  8062. {
  8063. write_bson_entry_header(name, 0x03); // object
  8064. write_bson_object(value);
  8065. }
  8066. /*!
  8067. @return The size of the BSON-encoded array @a value
  8068. */
  8069. static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
  8070. {
  8071. std::size_t embedded_document_size = 0ul;
  8072. std::size_t array_index = 0ul;
  8073. for (const auto& el : value)
  8074. {
  8075. embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
  8076. }
  8077. return sizeof(std::int32_t) + embedded_document_size + 1ul;
  8078. }
  8079. /*!
  8080. @brief Writes a BSON element with key @a name and array @a value
  8081. */
  8082. void write_bson_array(const string_t& name,
  8083. const typename BasicJsonType::array_t& value)
  8084. {
  8085. write_bson_entry_header(name, 0x04); // array
  8086. write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
  8087. std::size_t array_index = 0ul;
  8088. for (const auto& el : value)
  8089. {
  8090. write_bson_element(std::to_string(array_index++), el);
  8091. }
  8092. oa->write_character(to_char_type(0x00));
  8093. }
  8094. /*!
  8095. @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
  8096. @return The calculated size for the BSON document entry for @a j with the given @a name.
  8097. */
  8098. static std::size_t calc_bson_element_size(const string_t& name,
  8099. const BasicJsonType& j)
  8100. {
  8101. const auto header_size = calc_bson_entry_header_size(name);
  8102. switch (j.type())
  8103. {
  8104. case value_t::object:
  8105. return header_size + calc_bson_object_size(*j.m_value.object);
  8106. case value_t::array:
  8107. return header_size + calc_bson_array_size(*j.m_value.array);
  8108. case value_t::boolean:
  8109. return header_size + 1ul;
  8110. case value_t::number_float:
  8111. return header_size + 8ul;
  8112. case value_t::number_integer:
  8113. return header_size + calc_bson_integer_size(j.m_value.number_integer);
  8114. case value_t::number_unsigned:
  8115. return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
  8116. case value_t::string:
  8117. return header_size + calc_bson_string_size(*j.m_value.string);
  8118. case value_t::null:
  8119. return header_size + 0ul;
  8120. // LCOV_EXCL_START
  8121. default:
  8122. assert(false);
  8123. return 0ul;
  8124. // LCOV_EXCL_STOP
  8125. };
  8126. }
  8127. /*!
  8128. @brief Serializes the JSON value @a j to BSON and associates it with the
  8129. key @a name.
  8130. @param name The name to associate with the JSON entity @a j within the
  8131. current BSON document
  8132. @return The size of the BSON entry
  8133. */
  8134. void write_bson_element(const string_t& name,
  8135. const BasicJsonType& j)
  8136. {
  8137. switch (j.type())
  8138. {
  8139. case value_t::object:
  8140. return write_bson_object_entry(name, *j.m_value.object);
  8141. case value_t::array:
  8142. return write_bson_array(name, *j.m_value.array);
  8143. case value_t::boolean:
  8144. return write_bson_boolean(name, j.m_value.boolean);
  8145. case value_t::number_float:
  8146. return write_bson_double(name, j.m_value.number_float);
  8147. case value_t::number_integer:
  8148. return write_bson_integer(name, j.m_value.number_integer);
  8149. case value_t::number_unsigned:
  8150. return write_bson_unsigned(name, j.m_value.number_unsigned);
  8151. case value_t::string:
  8152. return write_bson_string(name, *j.m_value.string);
  8153. case value_t::null:
  8154. return write_bson_null(name);
  8155. // LCOV_EXCL_START
  8156. default:
  8157. assert(false);
  8158. return;
  8159. // LCOV_EXCL_STOP
  8160. };
  8161. }
  8162. /*!
  8163. @brief Calculates the size of the BSON serialization of the given
  8164. JSON-object @a j.
  8165. @param[in] j JSON value to serialize
  8166. @pre j.type() == value_t::object
  8167. */
  8168. static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
  8169. {
  8170. std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
  8171. [](size_t result, const typename BasicJsonType::object_t::value_type & el)
  8172. {
  8173. return result += calc_bson_element_size(el.first, el.second);
  8174. });
  8175. return sizeof(std::int32_t) + document_size + 1ul;
  8176. }
  8177. /*!
  8178. @param[in] j JSON value to serialize
  8179. @pre j.type() == value_t::object
  8180. */
  8181. void write_bson_object(const typename BasicJsonType::object_t& value)
  8182. {
  8183. write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
  8184. for (const auto& el : value)
  8185. {
  8186. write_bson_element(el.first, el.second);
  8187. }
  8188. oa->write_character(to_char_type(0x00));
  8189. }
  8190. //////////
  8191. // CBOR //
  8192. //////////
  8193. static constexpr CharType get_cbor_float_prefix(float /*unused*/)
  8194. {
  8195. return to_char_type(0xFA); // Single-Precision Float
  8196. }
  8197. static constexpr CharType get_cbor_float_prefix(double /*unused*/)
  8198. {
  8199. return to_char_type(0xFB); // Double-Precision Float
  8200. }
  8201. /////////////
  8202. // MsgPack //
  8203. /////////////
  8204. static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
  8205. {
  8206. return to_char_type(0xCA); // float 32
  8207. }
  8208. static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
  8209. {
  8210. return to_char_type(0xCB); // float 64
  8211. }
  8212. ////////////
  8213. // UBJSON //
  8214. ////////////
  8215. // UBJSON: write number (floating point)
  8216. template<typename NumberType, typename std::enable_if<
  8217. std::is_floating_point<NumberType>::value, int>::type = 0>
  8218. void write_number_with_ubjson_prefix(const NumberType n,
  8219. const bool add_prefix)
  8220. {
  8221. if (add_prefix)
  8222. {
  8223. oa->write_character(get_ubjson_float_prefix(n));
  8224. }
  8225. write_number(n);
  8226. }
  8227. // UBJSON: write number (unsigned integer)
  8228. template<typename NumberType, typename std::enable_if<
  8229. std::is_unsigned<NumberType>::value, int>::type = 0>
  8230. void write_number_with_ubjson_prefix(const NumberType n,
  8231. const bool add_prefix)
  8232. {
  8233. if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
  8234. {
  8235. if (add_prefix)
  8236. {
  8237. oa->write_character(to_char_type('i')); // int8
  8238. }
  8239. write_number(static_cast<uint8_t>(n));
  8240. }
  8241. else if (n <= (std::numeric_limits<uint8_t>::max)())
  8242. {
  8243. if (add_prefix)
  8244. {
  8245. oa->write_character(to_char_type('U')); // uint8
  8246. }
  8247. write_number(static_cast<uint8_t>(n));
  8248. }
  8249. else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
  8250. {
  8251. if (add_prefix)
  8252. {
  8253. oa->write_character(to_char_type('I')); // int16
  8254. }
  8255. write_number(static_cast<int16_t>(n));
  8256. }
  8257. else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
  8258. {
  8259. if (add_prefix)
  8260. {
  8261. oa->write_character(to_char_type('l')); // int32
  8262. }
  8263. write_number(static_cast<int32_t>(n));
  8264. }
  8265. else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
  8266. {
  8267. if (add_prefix)
  8268. {
  8269. oa->write_character(to_char_type('L')); // int64
  8270. }
  8271. write_number(static_cast<int64_t>(n));
  8272. }
  8273. else
  8274. {
  8275. JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
  8276. }
  8277. }
  8278. // UBJSON: write number (signed integer)
  8279. template<typename NumberType, typename std::enable_if<
  8280. std::is_signed<NumberType>::value and
  8281. not std::is_floating_point<NumberType>::value, int>::type = 0>
  8282. void write_number_with_ubjson_prefix(const NumberType n,
  8283. const bool add_prefix)
  8284. {
  8285. if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
  8286. {
  8287. if (add_prefix)
  8288. {
  8289. oa->write_character(to_char_type('i')); // int8
  8290. }
  8291. write_number(static_cast<int8_t>(n));
  8292. }
  8293. else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
  8294. {
  8295. if (add_prefix)
  8296. {
  8297. oa->write_character(to_char_type('U')); // uint8
  8298. }
  8299. write_number(static_cast<uint8_t>(n));
  8300. }
  8301. else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
  8302. {
  8303. if (add_prefix)
  8304. {
  8305. oa->write_character(to_char_type('I')); // int16
  8306. }
  8307. write_number(static_cast<int16_t>(n));
  8308. }
  8309. else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
  8310. {
  8311. if (add_prefix)
  8312. {
  8313. oa->write_character(to_char_type('l')); // int32
  8314. }
  8315. write_number(static_cast<int32_t>(n));
  8316. }
  8317. else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
  8318. {
  8319. if (add_prefix)
  8320. {
  8321. oa->write_character(to_char_type('L')); // int64
  8322. }
  8323. write_number(static_cast<int64_t>(n));
  8324. }
  8325. // LCOV_EXCL_START
  8326. else
  8327. {
  8328. JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
  8329. }
  8330. // LCOV_EXCL_STOP
  8331. }
  8332. /*!
  8333. @brief determine the type prefix of container values
  8334. @note This function does not need to be 100% accurate when it comes to
  8335. integer limits. In case a number exceeds the limits of int64_t,
  8336. this will be detected by a later call to function
  8337. write_number_with_ubjson_prefix. Therefore, we return 'L' for any
  8338. value that does not fit the previous limits.
  8339. */
  8340. CharType ubjson_prefix(const BasicJsonType& j) const noexcept
  8341. {
  8342. switch (j.type())
  8343. {
  8344. case value_t::null:
  8345. return 'Z';
  8346. case value_t::boolean:
  8347. return j.m_value.boolean ? 'T' : 'F';
  8348. case value_t::number_integer:
  8349. {
  8350. if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
  8351. {
  8352. return 'i';
  8353. }
  8354. if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
  8355. {
  8356. return 'U';
  8357. }
  8358. if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
  8359. {
  8360. return 'I';
  8361. }
  8362. if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
  8363. {
  8364. return 'l';
  8365. }
  8366. // no check and assume int64_t (see note above)
  8367. return 'L';
  8368. }
  8369. case value_t::number_unsigned:
  8370. {
  8371. if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
  8372. {
  8373. return 'i';
  8374. }
  8375. if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
  8376. {
  8377. return 'U';
  8378. }
  8379. if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
  8380. {
  8381. return 'I';
  8382. }
  8383. if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
  8384. {
  8385. return 'l';
  8386. }
  8387. // no check and assume int64_t (see note above)
  8388. return 'L';
  8389. }
  8390. case value_t::number_float:
  8391. return get_ubjson_float_prefix(j.m_value.number_float);
  8392. case value_t::string:
  8393. return 'S';
  8394. case value_t::array:
  8395. return '[';
  8396. case value_t::object:
  8397. return '{';
  8398. default: // discarded values
  8399. return 'N';
  8400. }
  8401. }
  8402. static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
  8403. {
  8404. return 'd'; // float 32
  8405. }
  8406. static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
  8407. {
  8408. return 'D'; // float 64
  8409. }
  8410. ///////////////////////
  8411. // Utility functions //
  8412. ///////////////////////
  8413. /*
  8414. @brief write a number to output input
  8415. @param[in] n number of type @a NumberType
  8416. @tparam NumberType the type of the number
  8417. @tparam OutputIsLittleEndian Set to true if output data is
  8418. required to be little endian
  8419. @note This function needs to respect the system's endianess, because bytes
  8420. in CBOR, MessagePack, and UBJSON are stored in network order (big
  8421. endian) and therefore need reordering on little endian systems.
  8422. */
  8423. template<typename NumberType, bool OutputIsLittleEndian = false>
  8424. void write_number(const NumberType n)
  8425. {
  8426. // step 1: write number to array of length NumberType
  8427. std::array<CharType, sizeof(NumberType)> vec;
  8428. std::memcpy(vec.data(), &n, sizeof(NumberType));
  8429. // step 2: write array to output (with possible reordering)
  8430. if (is_little_endian and not OutputIsLittleEndian)
  8431. {
  8432. // reverse byte order prior to conversion if necessary
  8433. std::reverse(vec.begin(), vec.end());
  8434. }
  8435. oa->write_characters(vec.data(), sizeof(NumberType));
  8436. }
  8437. public:
  8438. // The following to_char_type functions are implement the conversion
  8439. // between uint8_t and CharType. In case CharType is not unsigned,
  8440. // such a conversion is required to allow values greater than 128.
  8441. // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
  8442. template < typename C = CharType,
  8443. enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
  8444. static constexpr CharType to_char_type(std::uint8_t x) noexcept
  8445. {
  8446. return *reinterpret_cast<char*>(&x);
  8447. }
  8448. template < typename C = CharType,
  8449. enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
  8450. static CharType to_char_type(std::uint8_t x) noexcept
  8451. {
  8452. static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
  8453. static_assert(std::is_pod<CharType>::value, "CharType must be POD");
  8454. CharType result;
  8455. std::memcpy(&result, &x, sizeof(x));
  8456. return result;
  8457. }
  8458. template<typename C = CharType,
  8459. enable_if_t<std::is_unsigned<C>::value>* = nullptr>
  8460. static constexpr CharType to_char_type(std::uint8_t x) noexcept
  8461. {
  8462. return x;
  8463. }
  8464. template < typename InputCharType, typename C = CharType,
  8465. enable_if_t <
  8466. std::is_signed<C>::value and
  8467. std::is_signed<char>::value and
  8468. std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
  8469. > * = nullptr >
  8470. static constexpr CharType to_char_type(InputCharType x) noexcept
  8471. {
  8472. return x;
  8473. }
  8474. private:
  8475. /// whether we can assume little endianess
  8476. const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
  8477. /// the output
  8478. output_adapter_t<CharType> oa = nullptr;
  8479. };
  8480. } // namespace detail
  8481. } // namespace nlohmann
  8482. // #include <nlohmann/detail/output/serializer.hpp>
  8483. #include <algorithm> // reverse, remove, fill, find, none_of
  8484. #include <array> // array
  8485. #include <cassert> // assert
  8486. #include <ciso646> // and, or
  8487. #include <clocale> // localeconv, lconv
  8488. #include <cmath> // labs, isfinite, isnan, signbit
  8489. #include <cstddef> // size_t, ptrdiff_t
  8490. #include <cstdint> // uint8_t
  8491. #include <cstdio> // snprintf
  8492. #include <limits> // numeric_limits
  8493. #include <string> // string
  8494. #include <type_traits> // is_same
  8495. // #include <nlohmann/detail/exceptions.hpp>
  8496. // #include <nlohmann/detail/conversions/to_chars.hpp>
  8497. #include <cassert> // assert
  8498. #include <ciso646> // or, and, not
  8499. #include <cmath> // signbit, isfinite
  8500. #include <cstdint> // intN_t, uintN_t
  8501. #include <cstring> // memcpy, memmove
  8502. namespace nlohmann
  8503. {
  8504. namespace detail
  8505. {
  8506. /*!
  8507. @brief implements the Grisu2 algorithm for binary to decimal floating-point
  8508. conversion.
  8509. This implementation is a slightly modified version of the reference
  8510. implementation which may be obtained from
  8511. http://florian.loitsch.com/publications (bench.tar.gz).
  8512. The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
  8513. For a detailed description of the algorithm see:
  8514. [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
  8515. Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
  8516. Language Design and Implementation, PLDI 2010
  8517. [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
  8518. Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
  8519. Design and Implementation, PLDI 1996
  8520. */
  8521. namespace dtoa_impl
  8522. {
  8523. template <typename Target, typename Source>
  8524. Target reinterpret_bits(const Source source)
  8525. {
  8526. static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
  8527. Target target;
  8528. std::memcpy(&target, &source, sizeof(Source));
  8529. return target;
  8530. }
  8531. struct diyfp // f * 2^e
  8532. {
  8533. static constexpr int kPrecision = 64; // = q
  8534. uint64_t f = 0;
  8535. int e = 0;
  8536. constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
  8537. /*!
  8538. @brief returns x - y
  8539. @pre x.e == y.e and x.f >= y.f
  8540. */
  8541. static diyfp sub(const diyfp& x, const diyfp& y) noexcept
  8542. {
  8543. assert(x.e == y.e);
  8544. assert(x.f >= y.f);
  8545. return {x.f - y.f, x.e};
  8546. }
  8547. /*!
  8548. @brief returns x * y
  8549. @note The result is rounded. (Only the upper q bits are returned.)
  8550. */
  8551. static diyfp mul(const diyfp& x, const diyfp& y) noexcept
  8552. {
  8553. static_assert(kPrecision == 64, "internal error");
  8554. // Computes:
  8555. // f = round((x.f * y.f) / 2^q)
  8556. // e = x.e + y.e + q
  8557. // Emulate the 64-bit * 64-bit multiplication:
  8558. //
  8559. // p = u * v
  8560. // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
  8561. // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
  8562. // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
  8563. // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
  8564. // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
  8565. // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
  8566. // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
  8567. //
  8568. // (Since Q might be larger than 2^32 - 1)
  8569. //
  8570. // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
  8571. //
  8572. // (Q_hi + H does not overflow a 64-bit int)
  8573. //
  8574. // = p_lo + 2^64 p_hi
  8575. const uint64_t u_lo = x.f & 0xFFFFFFFF;
  8576. const uint64_t u_hi = x.f >> 32;
  8577. const uint64_t v_lo = y.f & 0xFFFFFFFF;
  8578. const uint64_t v_hi = y.f >> 32;
  8579. const uint64_t p0 = u_lo * v_lo;
  8580. const uint64_t p1 = u_lo * v_hi;
  8581. const uint64_t p2 = u_hi * v_lo;
  8582. const uint64_t p3 = u_hi * v_hi;
  8583. const uint64_t p0_hi = p0 >> 32;
  8584. const uint64_t p1_lo = p1 & 0xFFFFFFFF;
  8585. const uint64_t p1_hi = p1 >> 32;
  8586. const uint64_t p2_lo = p2 & 0xFFFFFFFF;
  8587. const uint64_t p2_hi = p2 >> 32;
  8588. uint64_t Q = p0_hi + p1_lo + p2_lo;
  8589. // The full product might now be computed as
  8590. //
  8591. // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
  8592. // p_lo = p0_lo + (Q << 32)
  8593. //
  8594. // But in this particular case here, the full p_lo is not required.
  8595. // Effectively we only need to add the highest bit in p_lo to p_hi (and
  8596. // Q_hi + 1 does not overflow).
  8597. Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
  8598. const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
  8599. return {h, x.e + y.e + 64};
  8600. }
  8601. /*!
  8602. @brief normalize x such that the significand is >= 2^(q-1)
  8603. @pre x.f != 0
  8604. */
  8605. static diyfp normalize(diyfp x) noexcept
  8606. {
  8607. assert(x.f != 0);
  8608. while ((x.f >> 63) == 0)
  8609. {
  8610. x.f <<= 1;
  8611. x.e--;
  8612. }
  8613. return x;
  8614. }
  8615. /*!
  8616. @brief normalize x such that the result has the exponent E
  8617. @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
  8618. */
  8619. static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
  8620. {
  8621. const int delta = x.e - target_exponent;
  8622. assert(delta >= 0);
  8623. assert(((x.f << delta) >> delta) == x.f);
  8624. return {x.f << delta, target_exponent};
  8625. }
  8626. };
  8627. struct boundaries
  8628. {
  8629. diyfp w;
  8630. diyfp minus;
  8631. diyfp plus;
  8632. };
  8633. /*!
  8634. Compute the (normalized) diyfp representing the input number 'value' and its
  8635. boundaries.
  8636. @pre value must be finite and positive
  8637. */
  8638. template <typename FloatType>
  8639. boundaries compute_boundaries(FloatType value)
  8640. {
  8641. assert(std::isfinite(value));
  8642. assert(value > 0);
  8643. // Convert the IEEE representation into a diyfp.
  8644. //
  8645. // If v is denormal:
  8646. // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
  8647. // If v is normalized:
  8648. // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
  8649. static_assert(std::numeric_limits<FloatType>::is_iec559,
  8650. "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
  8651. constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
  8652. constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
  8653. constexpr int kMinExp = 1 - kBias;
  8654. constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
  8655. using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
  8656. const uint64_t bits = reinterpret_bits<bits_type>(value);
  8657. const uint64_t E = bits >> (kPrecision - 1);
  8658. const uint64_t F = bits & (kHiddenBit - 1);
  8659. const bool is_denormal = (E == 0);
  8660. const diyfp v = is_denormal
  8661. ? diyfp(F, kMinExp)
  8662. : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
  8663. // Compute the boundaries m- and m+ of the floating-point value
  8664. // v = f * 2^e.
  8665. //
  8666. // Determine v- and v+, the floating-point predecessor and successor if v,
  8667. // respectively.
  8668. //
  8669. // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
  8670. // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
  8671. //
  8672. // v+ = v + 2^e
  8673. //
  8674. // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
  8675. // between m- and m+ round to v, regardless of how the input rounding
  8676. // algorithm breaks ties.
  8677. //
  8678. // ---+-------------+-------------+-------------+-------------+--- (A)
  8679. // v- m- v m+ v+
  8680. //
  8681. // -----------------+------+------+-------------+-------------+--- (B)
  8682. // v- m- v m+ v+
  8683. const bool lower_boundary_is_closer = (F == 0 and E > 1);
  8684. const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
  8685. const diyfp m_minus = lower_boundary_is_closer
  8686. ? diyfp(4 * v.f - 1, v.e - 2) // (B)
  8687. : diyfp(2 * v.f - 1, v.e - 1); // (A)
  8688. // Determine the normalized w+ = m+.
  8689. const diyfp w_plus = diyfp::normalize(m_plus);
  8690. // Determine w- = m- such that e_(w-) = e_(w+).
  8691. const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
  8692. return {diyfp::normalize(v), w_minus, w_plus};
  8693. }
  8694. // Given normalized diyfp w, Grisu needs to find a (normalized) cached
  8695. // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
  8696. // within a certain range [alpha, gamma] (Definition 3.2 from [1])
  8697. //
  8698. // alpha <= e = e_c + e_w + q <= gamma
  8699. //
  8700. // or
  8701. //
  8702. // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
  8703. // <= f_c * f_w * 2^gamma
  8704. //
  8705. // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
  8706. //
  8707. // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
  8708. //
  8709. // or
  8710. //
  8711. // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
  8712. //
  8713. // The choice of (alpha,gamma) determines the size of the table and the form of
  8714. // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
  8715. // in practice:
  8716. //
  8717. // The idea is to cut the number c * w = f * 2^e into two parts, which can be
  8718. // processed independently: An integral part p1, and a fractional part p2:
  8719. //
  8720. // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
  8721. // = (f div 2^-e) + (f mod 2^-e) * 2^e
  8722. // = p1 + p2 * 2^e
  8723. //
  8724. // The conversion of p1 into decimal form requires a series of divisions and
  8725. // modulos by (a power of) 10. These operations are faster for 32-bit than for
  8726. // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
  8727. // achieved by choosing
  8728. //
  8729. // -e >= 32 or e <= -32 := gamma
  8730. //
  8731. // In order to convert the fractional part
  8732. //
  8733. // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
  8734. //
  8735. // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
  8736. // d[-i] are extracted in order:
  8737. //
  8738. // (10 * p2) div 2^-e = d[-1]
  8739. // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
  8740. //
  8741. // The multiplication by 10 must not overflow. It is sufficient to choose
  8742. //
  8743. // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
  8744. //
  8745. // Since p2 = f mod 2^-e < 2^-e,
  8746. //
  8747. // -e <= 60 or e >= -60 := alpha
  8748. constexpr int kAlpha = -60;
  8749. constexpr int kGamma = -32;
  8750. struct cached_power // c = f * 2^e ~= 10^k
  8751. {
  8752. uint64_t f;
  8753. int e;
  8754. int k;
  8755. };
  8756. /*!
  8757. For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
  8758. power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
  8759. satisfies (Definition 3.2 from [1])
  8760. alpha <= e_c + e + q <= gamma.
  8761. */
  8762. inline cached_power get_cached_power_for_binary_exponent(int e)
  8763. {
  8764. // Now
  8765. //
  8766. // alpha <= e_c + e + q <= gamma (1)
  8767. // ==> f_c * 2^alpha <= c * 2^e * 2^q
  8768. //
  8769. // and since the c's are normalized, 2^(q-1) <= f_c,
  8770. //
  8771. // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
  8772. // ==> 2^(alpha - e - 1) <= c
  8773. //
  8774. // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
  8775. //
  8776. // k = ceil( log_10( 2^(alpha - e - 1) ) )
  8777. // = ceil( (alpha - e - 1) * log_10(2) )
  8778. //
  8779. // From the paper:
  8780. // "In theory the result of the procedure could be wrong since c is rounded,
  8781. // and the computation itself is approximated [...]. In practice, however,
  8782. // this simple function is sufficient."
  8783. //
  8784. // For IEEE double precision floating-point numbers converted into
  8785. // normalized diyfp's w = f * 2^e, with q = 64,
  8786. //
  8787. // e >= -1022 (min IEEE exponent)
  8788. // -52 (p - 1)
  8789. // -52 (p - 1, possibly normalize denormal IEEE numbers)
  8790. // -11 (normalize the diyfp)
  8791. // = -1137
  8792. //
  8793. // and
  8794. //
  8795. // e <= +1023 (max IEEE exponent)
  8796. // -52 (p - 1)
  8797. // -11 (normalize the diyfp)
  8798. // = 960
  8799. //
  8800. // This binary exponent range [-1137,960] results in a decimal exponent
  8801. // range [-307,324]. One does not need to store a cached power for each
  8802. // k in this range. For each such k it suffices to find a cached power
  8803. // such that the exponent of the product lies in [alpha,gamma].
  8804. // This implies that the difference of the decimal exponents of adjacent
  8805. // table entries must be less than or equal to
  8806. //
  8807. // floor( (gamma - alpha) * log_10(2) ) = 8.
  8808. //
  8809. // (A smaller distance gamma-alpha would require a larger table.)
  8810. // NB:
  8811. // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
  8812. constexpr int kCachedPowersSize = 79;
  8813. constexpr int kCachedPowersMinDecExp = -300;
  8814. constexpr int kCachedPowersDecStep = 8;
  8815. static constexpr cached_power kCachedPowers[] =
  8816. {
  8817. { 0xAB70FE17C79AC6CA, -1060, -300 },
  8818. { 0xFF77B1FCBEBCDC4F, -1034, -292 },
  8819. { 0xBE5691EF416BD60C, -1007, -284 },
  8820. { 0x8DD01FAD907FFC3C, -980, -276 },
  8821. { 0xD3515C2831559A83, -954, -268 },
  8822. { 0x9D71AC8FADA6C9B5, -927, -260 },
  8823. { 0xEA9C227723EE8BCB, -901, -252 },
  8824. { 0xAECC49914078536D, -874, -244 },
  8825. { 0x823C12795DB6CE57, -847, -236 },
  8826. { 0xC21094364DFB5637, -821, -228 },
  8827. { 0x9096EA6F3848984F, -794, -220 },
  8828. { 0xD77485CB25823AC7, -768, -212 },
  8829. { 0xA086CFCD97BF97F4, -741, -204 },
  8830. { 0xEF340A98172AACE5, -715, -196 },
  8831. { 0xB23867FB2A35B28E, -688, -188 },
  8832. { 0x84C8D4DFD2C63F3B, -661, -180 },
  8833. { 0xC5DD44271AD3CDBA, -635, -172 },
  8834. { 0x936B9FCEBB25C996, -608, -164 },
  8835. { 0xDBAC6C247D62A584, -582, -156 },
  8836. { 0xA3AB66580D5FDAF6, -555, -148 },
  8837. { 0xF3E2F893DEC3F126, -529, -140 },
  8838. { 0xB5B5ADA8AAFF80B8, -502, -132 },
  8839. { 0x87625F056C7C4A8B, -475, -124 },
  8840. { 0xC9BCFF6034C13053, -449, -116 },
  8841. { 0x964E858C91BA2655, -422, -108 },
  8842. { 0xDFF9772470297EBD, -396, -100 },
  8843. { 0xA6DFBD9FB8E5B88F, -369, -92 },
  8844. { 0xF8A95FCF88747D94, -343, -84 },
  8845. { 0xB94470938FA89BCF, -316, -76 },
  8846. { 0x8A08F0F8BF0F156B, -289, -68 },
  8847. { 0xCDB02555653131B6, -263, -60 },
  8848. { 0x993FE2C6D07B7FAC, -236, -52 },
  8849. { 0xE45C10C42A2B3B06, -210, -44 },
  8850. { 0xAA242499697392D3, -183, -36 },
  8851. { 0xFD87B5F28300CA0E, -157, -28 },
  8852. { 0xBCE5086492111AEB, -130, -20 },
  8853. { 0x8CBCCC096F5088CC, -103, -12 },
  8854. { 0xD1B71758E219652C, -77, -4 },
  8855. { 0x9C40000000000000, -50, 4 },
  8856. { 0xE8D4A51000000000, -24, 12 },
  8857. { 0xAD78EBC5AC620000, 3, 20 },
  8858. { 0x813F3978F8940984, 30, 28 },
  8859. { 0xC097CE7BC90715B3, 56, 36 },
  8860. { 0x8F7E32CE7BEA5C70, 83, 44 },
  8861. { 0xD5D238A4ABE98068, 109, 52 },
  8862. { 0x9F4F2726179A2245, 136, 60 },
  8863. { 0xED63A231D4C4FB27, 162, 68 },
  8864. { 0xB0DE65388CC8ADA8, 189, 76 },
  8865. { 0x83C7088E1AAB65DB, 216, 84 },
  8866. { 0xC45D1DF942711D9A, 242, 92 },
  8867. { 0x924D692CA61BE758, 269, 100 },
  8868. { 0xDA01EE641A708DEA, 295, 108 },
  8869. { 0xA26DA3999AEF774A, 322, 116 },
  8870. { 0xF209787BB47D6B85, 348, 124 },
  8871. { 0xB454E4A179DD1877, 375, 132 },
  8872. { 0x865B86925B9BC5C2, 402, 140 },
  8873. { 0xC83553C5C8965D3D, 428, 148 },
  8874. { 0x952AB45CFA97A0B3, 455, 156 },
  8875. { 0xDE469FBD99A05FE3, 481, 164 },
  8876. { 0xA59BC234DB398C25, 508, 172 },
  8877. { 0xF6C69A72A3989F5C, 534, 180 },
  8878. { 0xB7DCBF5354E9BECE, 561, 188 },
  8879. { 0x88FCF317F22241E2, 588, 196 },
  8880. { 0xCC20CE9BD35C78A5, 614, 204 },
  8881. { 0x98165AF37B2153DF, 641, 212 },
  8882. { 0xE2A0B5DC971F303A, 667, 220 },
  8883. { 0xA8D9D1535CE3B396, 694, 228 },
  8884. { 0xFB9B7CD9A4A7443C, 720, 236 },
  8885. { 0xBB764C4CA7A44410, 747, 244 },
  8886. { 0x8BAB8EEFB6409C1A, 774, 252 },
  8887. { 0xD01FEF10A657842C, 800, 260 },
  8888. { 0x9B10A4E5E9913129, 827, 268 },
  8889. { 0xE7109BFBA19C0C9D, 853, 276 },
  8890. { 0xAC2820D9623BF429, 880, 284 },
  8891. { 0x80444B5E7AA7CF85, 907, 292 },
  8892. { 0xBF21E44003ACDD2D, 933, 300 },
  8893. { 0x8E679C2F5E44FF8F, 960, 308 },
  8894. { 0xD433179D9C8CB841, 986, 316 },
  8895. { 0x9E19DB92B4E31BA9, 1013, 324 },
  8896. };
  8897. // This computation gives exactly the same results for k as
  8898. // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
  8899. // for |e| <= 1500, but doesn't require floating-point operations.
  8900. // NB: log_10(2) ~= 78913 / 2^18
  8901. assert(e >= -1500);
  8902. assert(e <= 1500);
  8903. const int f = kAlpha - e - 1;
  8904. const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
  8905. const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
  8906. assert(index >= 0);
  8907. assert(index < kCachedPowersSize);
  8908. static_cast<void>(kCachedPowersSize); // Fix warning.
  8909. const cached_power cached = kCachedPowers[index];
  8910. assert(kAlpha <= cached.e + e + 64);
  8911. assert(kGamma >= cached.e + e + 64);
  8912. return cached;
  8913. }
  8914. /*!
  8915. For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
  8916. For n == 0, returns 1 and sets pow10 := 1.
  8917. */
  8918. inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
  8919. {
  8920. // LCOV_EXCL_START
  8921. if (n >= 1000000000)
  8922. {
  8923. pow10 = 1000000000;
  8924. return 10;
  8925. }
  8926. // LCOV_EXCL_STOP
  8927. else if (n >= 100000000)
  8928. {
  8929. pow10 = 100000000;
  8930. return 9;
  8931. }
  8932. else if (n >= 10000000)
  8933. {
  8934. pow10 = 10000000;
  8935. return 8;
  8936. }
  8937. else if (n >= 1000000)
  8938. {
  8939. pow10 = 1000000;
  8940. return 7;
  8941. }
  8942. else if (n >= 100000)
  8943. {
  8944. pow10 = 100000;
  8945. return 6;
  8946. }
  8947. else if (n >= 10000)
  8948. {
  8949. pow10 = 10000;
  8950. return 5;
  8951. }
  8952. else if (n >= 1000)
  8953. {
  8954. pow10 = 1000;
  8955. return 4;
  8956. }
  8957. else if (n >= 100)
  8958. {
  8959. pow10 = 100;
  8960. return 3;
  8961. }
  8962. else if (n >= 10)
  8963. {
  8964. pow10 = 10;
  8965. return 2;
  8966. }
  8967. else
  8968. {
  8969. pow10 = 1;
  8970. return 1;
  8971. }
  8972. }
  8973. inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
  8974. uint64_t rest, uint64_t ten_k)
  8975. {
  8976. assert(len >= 1);
  8977. assert(dist <= delta);
  8978. assert(rest <= delta);
  8979. assert(ten_k > 0);
  8980. // <--------------------------- delta ---->
  8981. // <---- dist --------->
  8982. // --------------[------------------+-------------------]--------------
  8983. // M- w M+
  8984. //
  8985. // ten_k
  8986. // <------>
  8987. // <---- rest ---->
  8988. // --------------[------------------+----+--------------]--------------
  8989. // w V
  8990. // = buf * 10^k
  8991. //
  8992. // ten_k represents a unit-in-the-last-place in the decimal representation
  8993. // stored in buf.
  8994. // Decrement buf by ten_k while this takes buf closer to w.
  8995. // The tests are written in this order to avoid overflow in unsigned
  8996. // integer arithmetic.
  8997. while (rest < dist
  8998. and delta - rest >= ten_k
  8999. and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
  9000. {
  9001. assert(buf[len - 1] != '0');
  9002. buf[len - 1]--;
  9003. rest += ten_k;
  9004. }
  9005. }
  9006. /*!
  9007. Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
  9008. M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
  9009. */
  9010. inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
  9011. diyfp M_minus, diyfp w, diyfp M_plus)
  9012. {
  9013. static_assert(kAlpha >= -60, "internal error");
  9014. static_assert(kGamma <= -32, "internal error");
  9015. // Generates the digits (and the exponent) of a decimal floating-point
  9016. // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
  9017. // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
  9018. //
  9019. // <--------------------------- delta ---->
  9020. // <---- dist --------->
  9021. // --------------[------------------+-------------------]--------------
  9022. // M- w M+
  9023. //
  9024. // Grisu2 generates the digits of M+ from left to right and stops as soon as
  9025. // V is in [M-,M+].
  9026. assert(M_plus.e >= kAlpha);
  9027. assert(M_plus.e <= kGamma);
  9028. uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
  9029. uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
  9030. // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
  9031. //
  9032. // M+ = f * 2^e
  9033. // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
  9034. // = ((p1 ) * 2^-e + (p2 )) * 2^e
  9035. // = p1 + p2 * 2^e
  9036. const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
  9037. auto p1 = static_cast<uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
  9038. uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
  9039. // 1)
  9040. //
  9041. // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
  9042. assert(p1 > 0);
  9043. uint32_t pow10;
  9044. const int k = find_largest_pow10(p1, pow10);
  9045. // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
  9046. //
  9047. // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
  9048. // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
  9049. //
  9050. // M+ = p1 + p2 * 2^e
  9051. // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
  9052. // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
  9053. // = d[k-1] * 10^(k-1) + ( rest) * 2^e
  9054. //
  9055. // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
  9056. //
  9057. // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
  9058. //
  9059. // but stop as soon as
  9060. //
  9061. // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
  9062. int n = k;
  9063. while (n > 0)
  9064. {
  9065. // Invariants:
  9066. // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
  9067. // pow10 = 10^(n-1) <= p1 < 10^n
  9068. //
  9069. const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
  9070. const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
  9071. //
  9072. // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
  9073. // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
  9074. //
  9075. assert(d <= 9);
  9076. buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
  9077. //
  9078. // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
  9079. //
  9080. p1 = r;
  9081. n--;
  9082. //
  9083. // M+ = buffer * 10^n + (p1 + p2 * 2^e)
  9084. // pow10 = 10^n
  9085. //
  9086. // Now check if enough digits have been generated.
  9087. // Compute
  9088. //
  9089. // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
  9090. //
  9091. // Note:
  9092. // Since rest and delta share the same exponent e, it suffices to
  9093. // compare the significands.
  9094. const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
  9095. if (rest <= delta)
  9096. {
  9097. // V = buffer * 10^n, with M- <= V <= M+.
  9098. decimal_exponent += n;
  9099. // We may now just stop. But instead look if the buffer could be
  9100. // decremented to bring V closer to w.
  9101. //
  9102. // pow10 = 10^n is now 1 ulp in the decimal representation V.
  9103. // The rounding procedure works with diyfp's with an implicit
  9104. // exponent of e.
  9105. //
  9106. // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
  9107. //
  9108. const uint64_t ten_n = uint64_t{pow10} << -one.e;
  9109. grisu2_round(buffer, length, dist, delta, rest, ten_n);
  9110. return;
  9111. }
  9112. pow10 /= 10;
  9113. //
  9114. // pow10 = 10^(n-1) <= p1 < 10^n
  9115. // Invariants restored.
  9116. }
  9117. // 2)
  9118. //
  9119. // The digits of the integral part have been generated:
  9120. //
  9121. // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
  9122. // = buffer + p2 * 2^e
  9123. //
  9124. // Now generate the digits of the fractional part p2 * 2^e.
  9125. //
  9126. // Note:
  9127. // No decimal point is generated: the exponent is adjusted instead.
  9128. //
  9129. // p2 actually represents the fraction
  9130. //
  9131. // p2 * 2^e
  9132. // = p2 / 2^-e
  9133. // = d[-1] / 10^1 + d[-2] / 10^2 + ...
  9134. //
  9135. // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
  9136. //
  9137. // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
  9138. // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
  9139. //
  9140. // using
  9141. //
  9142. // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
  9143. // = ( d) * 2^-e + ( r)
  9144. //
  9145. // or
  9146. // 10^m * p2 * 2^e = d + r * 2^e
  9147. //
  9148. // i.e.
  9149. //
  9150. // M+ = buffer + p2 * 2^e
  9151. // = buffer + 10^-m * (d + r * 2^e)
  9152. // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
  9153. //
  9154. // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
  9155. assert(p2 > delta);
  9156. int m = 0;
  9157. for (;;)
  9158. {
  9159. // Invariant:
  9160. // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
  9161. // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
  9162. // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
  9163. // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
  9164. //
  9165. assert(p2 <= UINT64_MAX / 10);
  9166. p2 *= 10;
  9167. const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
  9168. const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
  9169. //
  9170. // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
  9171. // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
  9172. // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
  9173. //
  9174. assert(d <= 9);
  9175. buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
  9176. //
  9177. // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
  9178. //
  9179. p2 = r;
  9180. m++;
  9181. //
  9182. // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
  9183. // Invariant restored.
  9184. // Check if enough digits have been generated.
  9185. //
  9186. // 10^-m * p2 * 2^e <= delta * 2^e
  9187. // p2 * 2^e <= 10^m * delta * 2^e
  9188. // p2 <= 10^m * delta
  9189. delta *= 10;
  9190. dist *= 10;
  9191. if (p2 <= delta)
  9192. {
  9193. break;
  9194. }
  9195. }
  9196. // V = buffer * 10^-m, with M- <= V <= M+.
  9197. decimal_exponent -= m;
  9198. // 1 ulp in the decimal representation is now 10^-m.
  9199. // Since delta and dist are now scaled by 10^m, we need to do the
  9200. // same with ulp in order to keep the units in sync.
  9201. //
  9202. // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
  9203. //
  9204. const uint64_t ten_m = one.f;
  9205. grisu2_round(buffer, length, dist, delta, p2, ten_m);
  9206. // By construction this algorithm generates the shortest possible decimal
  9207. // number (Loitsch, Theorem 6.2) which rounds back to w.
  9208. // For an input number of precision p, at least
  9209. //
  9210. // N = 1 + ceil(p * log_10(2))
  9211. //
  9212. // decimal digits are sufficient to identify all binary floating-point
  9213. // numbers (Matula, "In-and-Out conversions").
  9214. // This implies that the algorithm does not produce more than N decimal
  9215. // digits.
  9216. //
  9217. // N = 17 for p = 53 (IEEE double precision)
  9218. // N = 9 for p = 24 (IEEE single precision)
  9219. }
  9220. /*!
  9221. v = buf * 10^decimal_exponent
  9222. len is the length of the buffer (number of decimal digits)
  9223. The buffer must be large enough, i.e. >= max_digits10.
  9224. */
  9225. inline void grisu2(char* buf, int& len, int& decimal_exponent,
  9226. diyfp m_minus, diyfp v, diyfp m_plus)
  9227. {
  9228. assert(m_plus.e == m_minus.e);
  9229. assert(m_plus.e == v.e);
  9230. // --------(-----------------------+-----------------------)-------- (A)
  9231. // m- v m+
  9232. //
  9233. // --------------------(-----------+-----------------------)-------- (B)
  9234. // m- v m+
  9235. //
  9236. // First scale v (and m- and m+) such that the exponent is in the range
  9237. // [alpha, gamma].
  9238. const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
  9239. const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
  9240. // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
  9241. const diyfp w = diyfp::mul(v, c_minus_k);
  9242. const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
  9243. const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
  9244. // ----(---+---)---------------(---+---)---------------(---+---)----
  9245. // w- w w+
  9246. // = c*m- = c*v = c*m+
  9247. //
  9248. // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
  9249. // w+ are now off by a small amount.
  9250. // In fact:
  9251. //
  9252. // w - v * 10^k < 1 ulp
  9253. //
  9254. // To account for this inaccuracy, add resp. subtract 1 ulp.
  9255. //
  9256. // --------+---[---------------(---+---)---------------]---+--------
  9257. // w- M- w M+ w+
  9258. //
  9259. // Now any number in [M-, M+] (bounds included) will round to w when input,
  9260. // regardless of how the input rounding algorithm breaks ties.
  9261. //
  9262. // And digit_gen generates the shortest possible such number in [M-, M+].
  9263. // Note that this does not mean that Grisu2 always generates the shortest
  9264. // possible number in the interval (m-, m+).
  9265. const diyfp M_minus(w_minus.f + 1, w_minus.e);
  9266. const diyfp M_plus (w_plus.f - 1, w_plus.e );
  9267. decimal_exponent = -cached.k; // = -(-k) = k
  9268. grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
  9269. }
  9270. /*!
  9271. v = buf * 10^decimal_exponent
  9272. len is the length of the buffer (number of decimal digits)
  9273. The buffer must be large enough, i.e. >= max_digits10.
  9274. */
  9275. template <typename FloatType>
  9276. void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
  9277. {
  9278. static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
  9279. "internal error: not enough precision");
  9280. assert(std::isfinite(value));
  9281. assert(value > 0);
  9282. // If the neighbors (and boundaries) of 'value' are always computed for double-precision
  9283. // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
  9284. // decimal representations are not exactly "short".
  9285. //
  9286. // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
  9287. // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
  9288. // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
  9289. // does.
  9290. // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
  9291. // representation using the corresponding std::from_chars function recovers value exactly". That
  9292. // indicates that single precision floating-point numbers should be recovered using
  9293. // 'std::strtof'.
  9294. //
  9295. // NB: If the neighbors are computed for single-precision numbers, there is a single float
  9296. // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
  9297. // value is off by 1 ulp.
  9298. #if 0
  9299. const boundaries w = compute_boundaries(static_cast<double>(value));
  9300. #else
  9301. const boundaries w = compute_boundaries(value);
  9302. #endif
  9303. grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
  9304. }
  9305. /*!
  9306. @brief appends a decimal representation of e to buf
  9307. @return a pointer to the element following the exponent.
  9308. @pre -1000 < e < 1000
  9309. */
  9310. inline char* append_exponent(char* buf, int e)
  9311. {
  9312. assert(e > -1000);
  9313. assert(e < 1000);
  9314. if (e < 0)
  9315. {
  9316. e = -e;
  9317. *buf++ = '-';
  9318. }
  9319. else
  9320. {
  9321. *buf++ = '+';
  9322. }
  9323. auto k = static_cast<uint32_t>(e);
  9324. if (k < 10)
  9325. {
  9326. // Always print at least two digits in the exponent.
  9327. // This is for compatibility with printf("%g").
  9328. *buf++ = '0';
  9329. *buf++ = static_cast<char>('0' + k);
  9330. }
  9331. else if (k < 100)
  9332. {
  9333. *buf++ = static_cast<char>('0' + k / 10);
  9334. k %= 10;
  9335. *buf++ = static_cast<char>('0' + k);
  9336. }
  9337. else
  9338. {
  9339. *buf++ = static_cast<char>('0' + k / 100);
  9340. k %= 100;
  9341. *buf++ = static_cast<char>('0' + k / 10);
  9342. k %= 10;
  9343. *buf++ = static_cast<char>('0' + k);
  9344. }
  9345. return buf;
  9346. }
  9347. /*!
  9348. @brief prettify v = buf * 10^decimal_exponent
  9349. If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
  9350. notation. Otherwise it will be printed in exponential notation.
  9351. @pre min_exp < 0
  9352. @pre max_exp > 0
  9353. */
  9354. inline char* format_buffer(char* buf, int len, int decimal_exponent,
  9355. int min_exp, int max_exp)
  9356. {
  9357. assert(min_exp < 0);
  9358. assert(max_exp > 0);
  9359. const int k = len;
  9360. const int n = len + decimal_exponent;
  9361. // v = buf * 10^(n-k)
  9362. // k is the length of the buffer (number of decimal digits)
  9363. // n is the position of the decimal point relative to the start of the buffer.
  9364. if (k <= n and n <= max_exp)
  9365. {
  9366. // digits[000]
  9367. // len <= max_exp + 2
  9368. std::memset(buf + k, '0', static_cast<size_t>(n - k));
  9369. // Make it look like a floating-point number (#362, #378)
  9370. buf[n + 0] = '.';
  9371. buf[n + 1] = '0';
  9372. return buf + (n + 2);
  9373. }
  9374. if (0 < n and n <= max_exp)
  9375. {
  9376. // dig.its
  9377. // len <= max_digits10 + 1
  9378. assert(k > n);
  9379. std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
  9380. buf[n] = '.';
  9381. return buf + (k + 1);
  9382. }
  9383. if (min_exp < n and n <= 0)
  9384. {
  9385. // 0.[000]digits
  9386. // len <= 2 + (-min_exp - 1) + max_digits10
  9387. std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
  9388. buf[0] = '0';
  9389. buf[1] = '.';
  9390. std::memset(buf + 2, '0', static_cast<size_t>(-n));
  9391. return buf + (2 + (-n) + k);
  9392. }
  9393. if (k == 1)
  9394. {
  9395. // dE+123
  9396. // len <= 1 + 5
  9397. buf += 1;
  9398. }
  9399. else
  9400. {
  9401. // d.igitsE+123
  9402. // len <= max_digits10 + 1 + 5
  9403. std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
  9404. buf[1] = '.';
  9405. buf += 1 + k;
  9406. }
  9407. *buf++ = 'e';
  9408. return append_exponent(buf, n - 1);
  9409. }
  9410. } // namespace dtoa_impl
  9411. /*!
  9412. @brief generates a decimal representation of the floating-point number value in [first, last).
  9413. The format of the resulting decimal representation is similar to printf's %g
  9414. format. Returns an iterator pointing past-the-end of the decimal representation.
  9415. @note The input number must be finite, i.e. NaN's and Inf's are not supported.
  9416. @note The buffer must be large enough.
  9417. @note The result is NOT null-terminated.
  9418. */
  9419. template <typename FloatType>
  9420. char* to_chars(char* first, const char* last, FloatType value)
  9421. {
  9422. static_cast<void>(last); // maybe unused - fix warning
  9423. assert(std::isfinite(value));
  9424. // Use signbit(value) instead of (value < 0) since signbit works for -0.
  9425. if (std::signbit(value))
  9426. {
  9427. value = -value;
  9428. *first++ = '-';
  9429. }
  9430. if (value == 0) // +-0
  9431. {
  9432. *first++ = '0';
  9433. // Make it look like a floating-point number (#362, #378)
  9434. *first++ = '.';
  9435. *first++ = '0';
  9436. return first;
  9437. }
  9438. assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
  9439. // Compute v = buffer * 10^decimal_exponent.
  9440. // The decimal digits are stored in the buffer, which needs to be interpreted
  9441. // as an unsigned decimal integer.
  9442. // len is the length of the buffer, i.e. the number of decimal digits.
  9443. int len = 0;
  9444. int decimal_exponent = 0;
  9445. dtoa_impl::grisu2(first, len, decimal_exponent, value);
  9446. assert(len <= std::numeric_limits<FloatType>::max_digits10);
  9447. // Format the buffer like printf("%.*g", prec, value)
  9448. constexpr int kMinExp = -4;
  9449. // Use digits10 here to increase compatibility with version 2.
  9450. constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
  9451. assert(last - first >= kMaxExp + 2);
  9452. assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
  9453. assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
  9454. return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
  9455. }
  9456. } // namespace detail
  9457. } // namespace nlohmann
  9458. // #include <nlohmann/detail/macro_scope.hpp>
  9459. // #include <nlohmann/detail/meta/cpp_future.hpp>
  9460. // #include <nlohmann/detail/output/binary_writer.hpp>
  9461. // #include <nlohmann/detail/output/output_adapters.hpp>
  9462. // #include <nlohmann/detail/value_t.hpp>
  9463. namespace nlohmann
  9464. {
  9465. namespace detail
  9466. {
  9467. ///////////////////
  9468. // serialization //
  9469. ///////////////////
  9470. /// how to treat decoding errors
  9471. enum class error_handler_t
  9472. {
  9473. strict, ///< throw a type_error exception in case of invalid UTF-8
  9474. replace, ///< replace invalid UTF-8 sequences with U+FFFD
  9475. ignore ///< ignore invalid UTF-8 sequences
  9476. };
  9477. template<typename BasicJsonType>
  9478. class serializer
  9479. {
  9480. using string_t = typename BasicJsonType::string_t;
  9481. using number_float_t = typename BasicJsonType::number_float_t;
  9482. using number_integer_t = typename BasicJsonType::number_integer_t;
  9483. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  9484. static constexpr uint8_t UTF8_ACCEPT = 0;
  9485. static constexpr uint8_t UTF8_REJECT = 1;
  9486. public:
  9487. /*!
  9488. @param[in] s output stream to serialize to
  9489. @param[in] ichar indentation character to use
  9490. @param[in] error_handler_ how to react on decoding errors
  9491. */
  9492. serializer(output_adapter_t<char> s, const char ichar,
  9493. error_handler_t error_handler_ = error_handler_t::strict)
  9494. : o(std::move(s))
  9495. , loc(std::localeconv())
  9496. , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
  9497. , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
  9498. , indent_char(ichar)
  9499. , indent_string(512, indent_char)
  9500. , error_handler(error_handler_)
  9501. {}
  9502. // delete because of pointer members
  9503. serializer(const serializer&) = delete;
  9504. serializer& operator=(const serializer&) = delete;
  9505. serializer(serializer&&) = delete;
  9506. serializer& operator=(serializer&&) = delete;
  9507. ~serializer() = default;
  9508. /*!
  9509. @brief internal implementation of the serialization function
  9510. This function is called by the public member function dump and organizes
  9511. the serialization internally. The indentation level is propagated as
  9512. additional parameter. In case of arrays and objects, the function is
  9513. called recursively.
  9514. - strings and object keys are escaped using `escape_string()`
  9515. - integer numbers are converted implicitly via `operator<<`
  9516. - floating-point numbers are converted to a string using `"%g"` format
  9517. @param[in] val value to serialize
  9518. @param[in] pretty_print whether the output shall be pretty-printed
  9519. @param[in] indent_step the indent level
  9520. @param[in] current_indent the current indent level (only used internally)
  9521. */
  9522. void dump(const BasicJsonType& val, const bool pretty_print,
  9523. const bool ensure_ascii,
  9524. const unsigned int indent_step,
  9525. const unsigned int current_indent = 0)
  9526. {
  9527. switch (val.m_type)
  9528. {
  9529. case value_t::object:
  9530. {
  9531. if (val.m_value.object->empty())
  9532. {
  9533. o->write_characters("{}", 2);
  9534. return;
  9535. }
  9536. if (pretty_print)
  9537. {
  9538. o->write_characters("{\n", 2);
  9539. // variable to hold indentation for recursive calls
  9540. const auto new_indent = current_indent + indent_step;
  9541. if (JSON_UNLIKELY(indent_string.size() < new_indent))
  9542. {
  9543. indent_string.resize(indent_string.size() * 2, ' ');
  9544. }
  9545. // first n-1 elements
  9546. auto i = val.m_value.object->cbegin();
  9547. for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
  9548. {
  9549. o->write_characters(indent_string.c_str(), new_indent);
  9550. o->write_character('\"');
  9551. dump_escaped(i->first, ensure_ascii);
  9552. o->write_characters("\": ", 3);
  9553. dump(i->second, true, ensure_ascii, indent_step, new_indent);
  9554. o->write_characters(",\n", 2);
  9555. }
  9556. // last element
  9557. assert(i != val.m_value.object->cend());
  9558. assert(std::next(i) == val.m_value.object->cend());
  9559. o->write_characters(indent_string.c_str(), new_indent);
  9560. o->write_character('\"');
  9561. dump_escaped(i->first, ensure_ascii);
  9562. o->write_characters("\": ", 3);
  9563. dump(i->second, true, ensure_ascii, indent_step, new_indent);
  9564. o->write_character('\n');
  9565. o->write_characters(indent_string.c_str(), current_indent);
  9566. o->write_character('}');
  9567. }
  9568. else
  9569. {
  9570. o->write_character('{');
  9571. // first n-1 elements
  9572. auto i = val.m_value.object->cbegin();
  9573. for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
  9574. {
  9575. o->write_character('\"');
  9576. dump_escaped(i->first, ensure_ascii);
  9577. o->write_characters("\":", 2);
  9578. dump(i->second, false, ensure_ascii, indent_step, current_indent);
  9579. o->write_character(',');
  9580. }
  9581. // last element
  9582. assert(i != val.m_value.object->cend());
  9583. assert(std::next(i) == val.m_value.object->cend());
  9584. o->write_character('\"');
  9585. dump_escaped(i->first, ensure_ascii);
  9586. o->write_characters("\":", 2);
  9587. dump(i->second, false, ensure_ascii, indent_step, current_indent);
  9588. o->write_character('}');
  9589. }
  9590. return;
  9591. }
  9592. case value_t::array:
  9593. {
  9594. if (val.m_value.array->empty())
  9595. {
  9596. o->write_characters("[]", 2);
  9597. return;
  9598. }
  9599. if (pretty_print)
  9600. {
  9601. o->write_characters("[\n", 2);
  9602. // variable to hold indentation for recursive calls
  9603. const auto new_indent = current_indent + indent_step;
  9604. if (JSON_UNLIKELY(indent_string.size() < new_indent))
  9605. {
  9606. indent_string.resize(indent_string.size() * 2, ' ');
  9607. }
  9608. // first n-1 elements
  9609. for (auto i = val.m_value.array->cbegin();
  9610. i != val.m_value.array->cend() - 1; ++i)
  9611. {
  9612. o->write_characters(indent_string.c_str(), new_indent);
  9613. dump(*i, true, ensure_ascii, indent_step, new_indent);
  9614. o->write_characters(",\n", 2);
  9615. }
  9616. // last element
  9617. assert(not val.m_value.array->empty());
  9618. o->write_characters(indent_string.c_str(), new_indent);
  9619. dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
  9620. o->write_character('\n');
  9621. o->write_characters(indent_string.c_str(), current_indent);
  9622. o->write_character(']');
  9623. }
  9624. else
  9625. {
  9626. o->write_character('[');
  9627. // first n-1 elements
  9628. for (auto i = val.m_value.array->cbegin();
  9629. i != val.m_value.array->cend() - 1; ++i)
  9630. {
  9631. dump(*i, false, ensure_ascii, indent_step, current_indent);
  9632. o->write_character(',');
  9633. }
  9634. // last element
  9635. assert(not val.m_value.array->empty());
  9636. dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
  9637. o->write_character(']');
  9638. }
  9639. return;
  9640. }
  9641. case value_t::string:
  9642. {
  9643. o->write_character('\"');
  9644. dump_escaped(*val.m_value.string, ensure_ascii);
  9645. o->write_character('\"');
  9646. return;
  9647. }
  9648. case value_t::boolean:
  9649. {
  9650. if (val.m_value.boolean)
  9651. {
  9652. o->write_characters("true", 4);
  9653. }
  9654. else
  9655. {
  9656. o->write_characters("false", 5);
  9657. }
  9658. return;
  9659. }
  9660. case value_t::number_integer:
  9661. {
  9662. dump_integer(val.m_value.number_integer);
  9663. return;
  9664. }
  9665. case value_t::number_unsigned:
  9666. {
  9667. dump_integer(val.m_value.number_unsigned);
  9668. return;
  9669. }
  9670. case value_t::number_float:
  9671. {
  9672. dump_float(val.m_value.number_float);
  9673. return;
  9674. }
  9675. case value_t::discarded:
  9676. {
  9677. o->write_characters("<discarded>", 11);
  9678. return;
  9679. }
  9680. case value_t::null:
  9681. {
  9682. o->write_characters("null", 4);
  9683. return;
  9684. }
  9685. }
  9686. }
  9687. private:
  9688. /*!
  9689. @brief dump escaped string
  9690. Escape a string by replacing certain special characters by a sequence of an
  9691. escape character (backslash) and another character and other control
  9692. characters by a sequence of "\u" followed by a four-digit hex
  9693. representation. The escaped string is written to output stream @a o.
  9694. @param[in] s the string to escape
  9695. @param[in] ensure_ascii whether to escape non-ASCII characters with
  9696. \uXXXX sequences
  9697. @complexity Linear in the length of string @a s.
  9698. */
  9699. void dump_escaped(const string_t& s, const bool ensure_ascii)
  9700. {
  9701. uint32_t codepoint;
  9702. uint8_t state = UTF8_ACCEPT;
  9703. std::size_t bytes = 0; // number of bytes written to string_buffer
  9704. // number of bytes written at the point of the last valid byte
  9705. std::size_t bytes_after_last_accept = 0;
  9706. std::size_t undumped_chars = 0;
  9707. for (std::size_t i = 0; i < s.size(); ++i)
  9708. {
  9709. const auto byte = static_cast<uint8_t>(s[i]);
  9710. switch (decode(state, codepoint, byte))
  9711. {
  9712. case UTF8_ACCEPT: // decode found a new code point
  9713. {
  9714. switch (codepoint)
  9715. {
  9716. case 0x08: // backspace
  9717. {
  9718. string_buffer[bytes++] = '\\';
  9719. string_buffer[bytes++] = 'b';
  9720. break;
  9721. }
  9722. case 0x09: // horizontal tab
  9723. {
  9724. string_buffer[bytes++] = '\\';
  9725. string_buffer[bytes++] = 't';
  9726. break;
  9727. }
  9728. case 0x0A: // newline
  9729. {
  9730. string_buffer[bytes++] = '\\';
  9731. string_buffer[bytes++] = 'n';
  9732. break;
  9733. }
  9734. case 0x0C: // formfeed
  9735. {
  9736. string_buffer[bytes++] = '\\';
  9737. string_buffer[bytes++] = 'f';
  9738. break;
  9739. }
  9740. case 0x0D: // carriage return
  9741. {
  9742. string_buffer[bytes++] = '\\';
  9743. string_buffer[bytes++] = 'r';
  9744. break;
  9745. }
  9746. case 0x22: // quotation mark
  9747. {
  9748. string_buffer[bytes++] = '\\';
  9749. string_buffer[bytes++] = '\"';
  9750. break;
  9751. }
  9752. case 0x5C: // reverse solidus
  9753. {
  9754. string_buffer[bytes++] = '\\';
  9755. string_buffer[bytes++] = '\\';
  9756. break;
  9757. }
  9758. default:
  9759. {
  9760. // escape control characters (0x00..0x1F) or, if
  9761. // ensure_ascii parameter is used, non-ASCII characters
  9762. if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
  9763. {
  9764. if (codepoint <= 0xFFFF)
  9765. {
  9766. (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
  9767. static_cast<uint16_t>(codepoint));
  9768. bytes += 6;
  9769. }
  9770. else
  9771. {
  9772. (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
  9773. static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
  9774. static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
  9775. bytes += 12;
  9776. }
  9777. }
  9778. else
  9779. {
  9780. // copy byte to buffer (all previous bytes
  9781. // been copied have in default case above)
  9782. string_buffer[bytes++] = s[i];
  9783. }
  9784. break;
  9785. }
  9786. }
  9787. // write buffer and reset index; there must be 13 bytes
  9788. // left, as this is the maximal number of bytes to be
  9789. // written ("\uxxxx\uxxxx\0") for one code point
  9790. if (string_buffer.size() - bytes < 13)
  9791. {
  9792. o->write_characters(string_buffer.data(), bytes);
  9793. bytes = 0;
  9794. }
  9795. // remember the byte position of this accept
  9796. bytes_after_last_accept = bytes;
  9797. undumped_chars = 0;
  9798. break;
  9799. }
  9800. case UTF8_REJECT: // decode found invalid UTF-8 byte
  9801. {
  9802. switch (error_handler)
  9803. {
  9804. case error_handler_t::strict:
  9805. {
  9806. std::string sn(3, '\0');
  9807. (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
  9808. JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
  9809. }
  9810. case error_handler_t::ignore:
  9811. case error_handler_t::replace:
  9812. {
  9813. // in case we saw this character the first time, we
  9814. // would like to read it again, because the byte
  9815. // may be OK for itself, but just not OK for the
  9816. // previous sequence
  9817. if (undumped_chars > 0)
  9818. {
  9819. --i;
  9820. }
  9821. // reset length buffer to the last accepted index;
  9822. // thus removing/ignoring the invalid characters
  9823. bytes = bytes_after_last_accept;
  9824. if (error_handler == error_handler_t::replace)
  9825. {
  9826. // add a replacement character
  9827. if (ensure_ascii)
  9828. {
  9829. string_buffer[bytes++] = '\\';
  9830. string_buffer[bytes++] = 'u';
  9831. string_buffer[bytes++] = 'f';
  9832. string_buffer[bytes++] = 'f';
  9833. string_buffer[bytes++] = 'f';
  9834. string_buffer[bytes++] = 'd';
  9835. }
  9836. else
  9837. {
  9838. string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
  9839. string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
  9840. string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
  9841. }
  9842. bytes_after_last_accept = bytes;
  9843. }
  9844. undumped_chars = 0;
  9845. // continue processing the string
  9846. state = UTF8_ACCEPT;
  9847. break;
  9848. }
  9849. }
  9850. break;
  9851. }
  9852. default: // decode found yet incomplete multi-byte code point
  9853. {
  9854. if (not ensure_ascii)
  9855. {
  9856. // code point will not be escaped - copy byte to buffer
  9857. string_buffer[bytes++] = s[i];
  9858. }
  9859. ++undumped_chars;
  9860. break;
  9861. }
  9862. }
  9863. }
  9864. // we finished processing the string
  9865. if (JSON_LIKELY(state == UTF8_ACCEPT))
  9866. {
  9867. // write buffer
  9868. if (bytes > 0)
  9869. {
  9870. o->write_characters(string_buffer.data(), bytes);
  9871. }
  9872. }
  9873. else
  9874. {
  9875. // we finish reading, but do not accept: string was incomplete
  9876. switch (error_handler)
  9877. {
  9878. case error_handler_t::strict:
  9879. {
  9880. std::string sn(3, '\0');
  9881. (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
  9882. JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
  9883. }
  9884. case error_handler_t::ignore:
  9885. {
  9886. // write all accepted bytes
  9887. o->write_characters(string_buffer.data(), bytes_after_last_accept);
  9888. break;
  9889. }
  9890. case error_handler_t::replace:
  9891. {
  9892. // write all accepted bytes
  9893. o->write_characters(string_buffer.data(), bytes_after_last_accept);
  9894. // add a replacement character
  9895. if (ensure_ascii)
  9896. {
  9897. o->write_characters("\\ufffd", 6);
  9898. }
  9899. else
  9900. {
  9901. o->write_characters("\xEF\xBF\xBD", 3);
  9902. }
  9903. break;
  9904. }
  9905. }
  9906. }
  9907. }
  9908. /*!
  9909. @brief dump an integer
  9910. Dump a given integer to output stream @a o. Works internally with
  9911. @a number_buffer.
  9912. @param[in] x integer number (signed or unsigned) to dump
  9913. @tparam NumberType either @a number_integer_t or @a number_unsigned_t
  9914. */
  9915. template<typename NumberType, detail::enable_if_t<
  9916. std::is_same<NumberType, number_unsigned_t>::value or
  9917. std::is_same<NumberType, number_integer_t>::value,
  9918. int> = 0>
  9919. void dump_integer(NumberType x)
  9920. {
  9921. // special case for "0"
  9922. if (x == 0)
  9923. {
  9924. o->write_character('0');
  9925. return;
  9926. }
  9927. const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0); // see issue #755
  9928. std::size_t i = 0;
  9929. while (x != 0)
  9930. {
  9931. // spare 1 byte for '\0'
  9932. assert(i < number_buffer.size() - 1);
  9933. const auto digit = std::labs(static_cast<long>(x % 10));
  9934. number_buffer[i++] = static_cast<char>('0' + digit);
  9935. x /= 10;
  9936. }
  9937. if (is_negative)
  9938. {
  9939. // make sure there is capacity for the '-'
  9940. assert(i < number_buffer.size() - 2);
  9941. number_buffer[i++] = '-';
  9942. }
  9943. std::reverse(number_buffer.begin(), number_buffer.begin() + i);
  9944. o->write_characters(number_buffer.data(), i);
  9945. }
  9946. /*!
  9947. @brief dump a floating-point number
  9948. Dump a given floating-point number to output stream @a o. Works internally
  9949. with @a number_buffer.
  9950. @param[in] x floating-point number to dump
  9951. */
  9952. void dump_float(number_float_t x)
  9953. {
  9954. // NaN / inf
  9955. if (not std::isfinite(x))
  9956. {
  9957. o->write_characters("null", 4);
  9958. return;
  9959. }
  9960. // If number_float_t is an IEEE-754 single or double precision number,
  9961. // use the Grisu2 algorithm to produce short numbers which are
  9962. // guaranteed to round-trip, using strtof and strtod, resp.
  9963. //
  9964. // NB: The test below works if <long double> == <double>.
  9965. static constexpr bool is_ieee_single_or_double
  9966. = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
  9967. (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
  9968. dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
  9969. }
  9970. void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
  9971. {
  9972. char* begin = number_buffer.data();
  9973. char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
  9974. o->write_characters(begin, static_cast<size_t>(end - begin));
  9975. }
  9976. void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
  9977. {
  9978. // get number of digits for a float -> text -> float round-trip
  9979. static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
  9980. // the actual conversion
  9981. std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
  9982. // negative value indicates an error
  9983. assert(len > 0);
  9984. // check if buffer was large enough
  9985. assert(static_cast<std::size_t>(len) < number_buffer.size());
  9986. // erase thousands separator
  9987. if (thousands_sep != '\0')
  9988. {
  9989. const auto end = std::remove(number_buffer.begin(),
  9990. number_buffer.begin() + len, thousands_sep);
  9991. std::fill(end, number_buffer.end(), '\0');
  9992. assert((end - number_buffer.begin()) <= len);
  9993. len = (end - number_buffer.begin());
  9994. }
  9995. // convert decimal point to '.'
  9996. if (decimal_point != '\0' and decimal_point != '.')
  9997. {
  9998. const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
  9999. if (dec_pos != number_buffer.end())
  10000. {
  10001. *dec_pos = '.';
  10002. }
  10003. }
  10004. o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
  10005. // determine if need to append ".0"
  10006. const bool value_is_int_like =
  10007. std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
  10008. [](char c)
  10009. {
  10010. return (c == '.' or c == 'e');
  10011. });
  10012. if (value_is_int_like)
  10013. {
  10014. o->write_characters(".0", 2);
  10015. }
  10016. }
  10017. /*!
  10018. @brief check whether a string is UTF-8 encoded
  10019. The function checks each byte of a string whether it is UTF-8 encoded. The
  10020. result of the check is stored in the @a state parameter. The function must
  10021. be called initially with state 0 (accept). State 1 means the string must
  10022. be rejected, because the current byte is not allowed. If the string is
  10023. completely processed, but the state is non-zero, the string ended
  10024. prematurely; that is, the last byte indicated more bytes should have
  10025. followed.
  10026. @param[in,out] state the state of the decoding
  10027. @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
  10028. @param[in] byte next byte to decode
  10029. @return new state
  10030. @note The function has been edited: a std::array is used.
  10031. @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <[email protected]>
  10032. @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
  10033. */
  10034. static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
  10035. {
  10036. static const std::array<uint8_t, 400> utf8d =
  10037. {
  10038. {
  10039. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
  10040. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
  10041. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
  10042. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
  10043. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
  10044. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
  10045. 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
  10046. 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
  10047. 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
  10048. 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
  10049. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
  10050. 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
  10051. 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
  10052. 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
  10053. }
  10054. };
  10055. const uint8_t type = utf8d[byte];
  10056. codep = (state != UTF8_ACCEPT)
  10057. ? (byte & 0x3fu) | (codep << 6)
  10058. : static_cast<uint32_t>(0xff >> type) & (byte);
  10059. state = utf8d[256u + state * 16u + type];
  10060. return state;
  10061. }
  10062. private:
  10063. /// the output of the serializer
  10064. output_adapter_t<char> o = nullptr;
  10065. /// a (hopefully) large enough character buffer
  10066. std::array<char, 64> number_buffer{{}};
  10067. /// the locale
  10068. const std::lconv* loc = nullptr;
  10069. /// the locale's thousand separator character
  10070. const char thousands_sep = '\0';
  10071. /// the locale's decimal point character
  10072. const char decimal_point = '\0';
  10073. /// string buffer
  10074. std::array<char, 512> string_buffer{{}};
  10075. /// the indentation character
  10076. const char indent_char;
  10077. /// the indentation string
  10078. string_t indent_string;
  10079. /// error_handler how to react on decoding errors
  10080. const error_handler_t error_handler;
  10081. };
  10082. } // namespace detail
  10083. } // namespace nlohmann
  10084. // #include <nlohmann/detail/json_ref.hpp>
  10085. #include <initializer_list>
  10086. #include <utility>
  10087. // #include <nlohmann/detail/meta/type_traits.hpp>
  10088. namespace nlohmann
  10089. {
  10090. namespace detail
  10091. {
  10092. template<typename BasicJsonType>
  10093. class json_ref
  10094. {
  10095. public:
  10096. using value_type = BasicJsonType;
  10097. json_ref(value_type&& value)
  10098. : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
  10099. {}
  10100. json_ref(const value_type& value)
  10101. : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
  10102. {}
  10103. json_ref(std::initializer_list<json_ref> init)
  10104. : owned_value(init), value_ref(&owned_value), is_rvalue(true)
  10105. {}
  10106. template <
  10107. class... Args,
  10108. enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
  10109. json_ref(Args && ... args)
  10110. : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
  10111. is_rvalue(true) {}
  10112. // class should be movable only
  10113. json_ref(json_ref&&) = default;
  10114. json_ref(const json_ref&) = delete;
  10115. json_ref& operator=(const json_ref&) = delete;
  10116. json_ref& operator=(json_ref&&) = delete;
  10117. ~json_ref() = default;
  10118. value_type moved_or_copied() const
  10119. {
  10120. if (is_rvalue)
  10121. {
  10122. return std::move(*value_ref);
  10123. }
  10124. return *value_ref;
  10125. }
  10126. value_type const& operator*() const
  10127. {
  10128. return *static_cast<value_type const*>(value_ref);
  10129. }
  10130. value_type const* operator->() const
  10131. {
  10132. return static_cast<value_type const*>(value_ref);
  10133. }
  10134. private:
  10135. mutable value_type owned_value = nullptr;
  10136. value_type* value_ref = nullptr;
  10137. const bool is_rvalue;
  10138. };
  10139. } // namespace detail
  10140. } // namespace nlohmann
  10141. // #include <nlohmann/detail/json_pointer.hpp>
  10142. #include <cassert> // assert
  10143. #include <numeric> // accumulate
  10144. #include <string> // string
  10145. #include <vector> // vector
  10146. // #include <nlohmann/detail/macro_scope.hpp>
  10147. // #include <nlohmann/detail/exceptions.hpp>
  10148. // #include <nlohmann/detail/value_t.hpp>
  10149. namespace nlohmann
  10150. {
  10151. template<typename BasicJsonType>
  10152. class json_pointer
  10153. {
  10154. // allow basic_json to access private members
  10155. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  10156. friend class basic_json;
  10157. public:
  10158. /*!
  10159. @brief create JSON pointer
  10160. Create a JSON pointer according to the syntax described in
  10161. [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
  10162. @param[in] s string representing the JSON pointer; if omitted, the empty
  10163. string is assumed which references the whole JSON value
  10164. @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
  10165. not begin with a slash (`/`); see example below
  10166. @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
  10167. not followed by `0` (representing `~`) or `1` (representing `/`); see
  10168. example below
  10169. @liveexample{The example shows the construction several valid JSON pointers
  10170. as well as the exceptional behavior.,json_pointer}
  10171. @since version 2.0.0
  10172. */
  10173. explicit json_pointer(const std::string& s = "")
  10174. : reference_tokens(split(s))
  10175. {}
  10176. /*!
  10177. @brief return a string representation of the JSON pointer
  10178. @invariant For each JSON pointer `ptr`, it holds:
  10179. @code {.cpp}
  10180. ptr == json_pointer(ptr.to_string());
  10181. @endcode
  10182. @return a string representation of the JSON pointer
  10183. @liveexample{The example shows the result of `to_string`.,
  10184. json_pointer__to_string}
  10185. @since version 2.0.0
  10186. */
  10187. std::string to_string() const
  10188. {
  10189. return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
  10190. std::string{},
  10191. [](const std::string & a, const std::string & b)
  10192. {
  10193. return a + "/" + escape(b);
  10194. });
  10195. }
  10196. /// @copydoc to_string()
  10197. operator std::string() const
  10198. {
  10199. return to_string();
  10200. }
  10201. /*!
  10202. @param[in] s reference token to be converted into an array index
  10203. @return integer representation of @a s
  10204. @throw out_of_range.404 if string @a s could not be converted to an integer
  10205. */
  10206. static int array_index(const std::string& s)
  10207. {
  10208. std::size_t processed_chars = 0;
  10209. const int res = std::stoi(s, &processed_chars);
  10210. // check if the string was completely read
  10211. if (JSON_UNLIKELY(processed_chars != s.size()))
  10212. {
  10213. JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
  10214. }
  10215. return res;
  10216. }
  10217. private:
  10218. /*!
  10219. @brief remove and return last reference pointer
  10220. @throw out_of_range.405 if JSON pointer has no parent
  10221. */
  10222. std::string pop_back()
  10223. {
  10224. if (JSON_UNLIKELY(is_root()))
  10225. {
  10226. JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
  10227. }
  10228. auto last = reference_tokens.back();
  10229. reference_tokens.pop_back();
  10230. return last;
  10231. }
  10232. /// return whether pointer points to the root document
  10233. bool is_root() const noexcept
  10234. {
  10235. return reference_tokens.empty();
  10236. }
  10237. json_pointer top() const
  10238. {
  10239. if (JSON_UNLIKELY(is_root()))
  10240. {
  10241. JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
  10242. }
  10243. json_pointer result = *this;
  10244. result.reference_tokens = {reference_tokens[0]};
  10245. return result;
  10246. }
  10247. /*!
  10248. @brief create and return a reference to the pointed to value
  10249. @complexity Linear in the number of reference tokens.
  10250. @throw parse_error.109 if array index is not a number
  10251. @throw type_error.313 if value cannot be unflattened
  10252. */
  10253. BasicJsonType& get_and_create(BasicJsonType& j) const
  10254. {
  10255. using size_type = typename BasicJsonType::size_type;
  10256. auto result = &j;
  10257. // in case no reference tokens exist, return a reference to the JSON value
  10258. // j which will be overwritten by a primitive value
  10259. for (const auto& reference_token : reference_tokens)
  10260. {
  10261. switch (result->m_type)
  10262. {
  10263. case detail::value_t::null:
  10264. {
  10265. if (reference_token == "0")
  10266. {
  10267. // start a new array if reference token is 0
  10268. result = &result->operator[](0);
  10269. }
  10270. else
  10271. {
  10272. // start a new object otherwise
  10273. result = &result->operator[](reference_token);
  10274. }
  10275. break;
  10276. }
  10277. case detail::value_t::object:
  10278. {
  10279. // create an entry in the object
  10280. result = &result->operator[](reference_token);
  10281. break;
  10282. }
  10283. case detail::value_t::array:
  10284. {
  10285. // create an entry in the array
  10286. JSON_TRY
  10287. {
  10288. result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
  10289. }
  10290. JSON_CATCH(std::invalid_argument&)
  10291. {
  10292. JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
  10293. }
  10294. break;
  10295. }
  10296. /*
  10297. The following code is only reached if there exists a reference
  10298. token _and_ the current value is primitive. In this case, we have
  10299. an error situation, because primitive values may only occur as
  10300. single value; that is, with an empty list of reference tokens.
  10301. */
  10302. default:
  10303. JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
  10304. }
  10305. }
  10306. return *result;
  10307. }
  10308. /*!
  10309. @brief return a reference to the pointed to value
  10310. @note This version does not throw if a value is not present, but tries to
  10311. create nested values instead. For instance, calling this function
  10312. with pointer `"/this/that"` on a null value is equivalent to calling
  10313. `operator[]("this").operator[]("that")` on that value, effectively
  10314. changing the null value to an object.
  10315. @param[in] ptr a JSON value
  10316. @return reference to the JSON value pointed to by the JSON pointer
  10317. @complexity Linear in the length of the JSON pointer.
  10318. @throw parse_error.106 if an array index begins with '0'
  10319. @throw parse_error.109 if an array index was not a number
  10320. @throw out_of_range.404 if the JSON pointer can not be resolved
  10321. */
  10322. BasicJsonType& get_unchecked(BasicJsonType* ptr) const
  10323. {
  10324. using size_type = typename BasicJsonType::size_type;
  10325. for (const auto& reference_token : reference_tokens)
  10326. {
  10327. // convert null values to arrays or objects before continuing
  10328. if (ptr->m_type == detail::value_t::null)
  10329. {
  10330. // check if reference token is a number
  10331. const bool nums =
  10332. std::all_of(reference_token.begin(), reference_token.end(),
  10333. [](const char x)
  10334. {
  10335. return (x >= '0' and x <= '9');
  10336. });
  10337. // change value to array for numbers or "-" or to object otherwise
  10338. *ptr = (nums or reference_token == "-")
  10339. ? detail::value_t::array
  10340. : detail::value_t::object;
  10341. }
  10342. switch (ptr->m_type)
  10343. {
  10344. case detail::value_t::object:
  10345. {
  10346. // use unchecked object access
  10347. ptr = &ptr->operator[](reference_token);
  10348. break;
  10349. }
  10350. case detail::value_t::array:
  10351. {
  10352. // error condition (cf. RFC 6901, Sect. 4)
  10353. if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
  10354. {
  10355. JSON_THROW(detail::parse_error::create(106, 0,
  10356. "array index '" + reference_token +
  10357. "' must not begin with '0'"));
  10358. }
  10359. if (reference_token == "-")
  10360. {
  10361. // explicitly treat "-" as index beyond the end
  10362. ptr = &ptr->operator[](ptr->m_value.array->size());
  10363. }
  10364. else
  10365. {
  10366. // convert array index to number; unchecked access
  10367. JSON_TRY
  10368. {
  10369. ptr = &ptr->operator[](
  10370. static_cast<size_type>(array_index(reference_token)));
  10371. }
  10372. JSON_CATCH(std::invalid_argument&)
  10373. {
  10374. JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
  10375. }
  10376. }
  10377. break;
  10378. }
  10379. default:
  10380. JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
  10381. }
  10382. }
  10383. return *ptr;
  10384. }
  10385. /*!
  10386. @throw parse_error.106 if an array index begins with '0'
  10387. @throw parse_error.109 if an array index was not a number
  10388. @throw out_of_range.402 if the array index '-' is used
  10389. @throw out_of_range.404 if the JSON pointer can not be resolved
  10390. */
  10391. BasicJsonType& get_checked(BasicJsonType* ptr) const
  10392. {
  10393. using size_type = typename BasicJsonType::size_type;
  10394. for (const auto& reference_token : reference_tokens)
  10395. {
  10396. switch (ptr->m_type)
  10397. {
  10398. case detail::value_t::object:
  10399. {
  10400. // note: at performs range check
  10401. ptr = &ptr->at(reference_token);
  10402. break;
  10403. }
  10404. case detail::value_t::array:
  10405. {
  10406. if (JSON_UNLIKELY(reference_token == "-"))
  10407. {
  10408. // "-" always fails the range check
  10409. JSON_THROW(detail::out_of_range::create(402,
  10410. "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
  10411. ") is out of range"));
  10412. }
  10413. // error condition (cf. RFC 6901, Sect. 4)
  10414. if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
  10415. {
  10416. JSON_THROW(detail::parse_error::create(106, 0,
  10417. "array index '" + reference_token +
  10418. "' must not begin with '0'"));
  10419. }
  10420. // note: at performs range check
  10421. JSON_TRY
  10422. {
  10423. ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
  10424. }
  10425. JSON_CATCH(std::invalid_argument&)
  10426. {
  10427. JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
  10428. }
  10429. break;
  10430. }
  10431. default:
  10432. JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
  10433. }
  10434. }
  10435. return *ptr;
  10436. }
  10437. /*!
  10438. @brief return a const reference to the pointed to value
  10439. @param[in] ptr a JSON value
  10440. @return const reference to the JSON value pointed to by the JSON
  10441. pointer
  10442. @throw parse_error.106 if an array index begins with '0'
  10443. @throw parse_error.109 if an array index was not a number
  10444. @throw out_of_range.402 if the array index '-' is used
  10445. @throw out_of_range.404 if the JSON pointer can not be resolved
  10446. */
  10447. const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
  10448. {
  10449. using size_type = typename BasicJsonType::size_type;
  10450. for (const auto& reference_token : reference_tokens)
  10451. {
  10452. switch (ptr->m_type)
  10453. {
  10454. case detail::value_t::object:
  10455. {
  10456. // use unchecked object access
  10457. ptr = &ptr->operator[](reference_token);
  10458. break;
  10459. }
  10460. case detail::value_t::array:
  10461. {
  10462. if (JSON_UNLIKELY(reference_token == "-"))
  10463. {
  10464. // "-" cannot be used for const access
  10465. JSON_THROW(detail::out_of_range::create(402,
  10466. "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
  10467. ") is out of range"));
  10468. }
  10469. // error condition (cf. RFC 6901, Sect. 4)
  10470. if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
  10471. {
  10472. JSON_THROW(detail::parse_error::create(106, 0,
  10473. "array index '" + reference_token +
  10474. "' must not begin with '0'"));
  10475. }
  10476. // use unchecked array access
  10477. JSON_TRY
  10478. {
  10479. ptr = &ptr->operator[](
  10480. static_cast<size_type>(array_index(reference_token)));
  10481. }
  10482. JSON_CATCH(std::invalid_argument&)
  10483. {
  10484. JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
  10485. }
  10486. break;
  10487. }
  10488. default:
  10489. JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
  10490. }
  10491. }
  10492. return *ptr;
  10493. }
  10494. /*!
  10495. @throw parse_error.106 if an array index begins with '0'
  10496. @throw parse_error.109 if an array index was not a number
  10497. @throw out_of_range.402 if the array index '-' is used
  10498. @throw out_of_range.404 if the JSON pointer can not be resolved
  10499. */
  10500. const BasicJsonType& get_checked(const BasicJsonType* ptr) const
  10501. {
  10502. using size_type = typename BasicJsonType::size_type;
  10503. for (const auto& reference_token : reference_tokens)
  10504. {
  10505. switch (ptr->m_type)
  10506. {
  10507. case detail::value_t::object:
  10508. {
  10509. // note: at performs range check
  10510. ptr = &ptr->at(reference_token);
  10511. break;
  10512. }
  10513. case detail::value_t::array:
  10514. {
  10515. if (JSON_UNLIKELY(reference_token == "-"))
  10516. {
  10517. // "-" always fails the range check
  10518. JSON_THROW(detail::out_of_range::create(402,
  10519. "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
  10520. ") is out of range"));
  10521. }
  10522. // error condition (cf. RFC 6901, Sect. 4)
  10523. if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
  10524. {
  10525. JSON_THROW(detail::parse_error::create(106, 0,
  10526. "array index '" + reference_token +
  10527. "' must not begin with '0'"));
  10528. }
  10529. // note: at performs range check
  10530. JSON_TRY
  10531. {
  10532. ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
  10533. }
  10534. JSON_CATCH(std::invalid_argument&)
  10535. {
  10536. JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
  10537. }
  10538. break;
  10539. }
  10540. default:
  10541. JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
  10542. }
  10543. }
  10544. return *ptr;
  10545. }
  10546. /*!
  10547. @brief split the string input to reference tokens
  10548. @note This function is only called by the json_pointer constructor.
  10549. All exceptions below are documented there.
  10550. @throw parse_error.107 if the pointer is not empty or begins with '/'
  10551. @throw parse_error.108 if character '~' is not followed by '0' or '1'
  10552. */
  10553. static std::vector<std::string> split(const std::string& reference_string)
  10554. {
  10555. std::vector<std::string> result;
  10556. // special case: empty reference string -> no reference tokens
  10557. if (reference_string.empty())
  10558. {
  10559. return result;
  10560. }
  10561. // check if nonempty reference string begins with slash
  10562. if (JSON_UNLIKELY(reference_string[0] != '/'))
  10563. {
  10564. JSON_THROW(detail::parse_error::create(107, 1,
  10565. "JSON pointer must be empty or begin with '/' - was: '" +
  10566. reference_string + "'"));
  10567. }
  10568. // extract the reference tokens:
  10569. // - slash: position of the last read slash (or end of string)
  10570. // - start: position after the previous slash
  10571. for (
  10572. // search for the first slash after the first character
  10573. std::size_t slash = reference_string.find_first_of('/', 1),
  10574. // set the beginning of the first reference token
  10575. start = 1;
  10576. // we can stop if start == 0 (if slash == std::string::npos)
  10577. start != 0;
  10578. // set the beginning of the next reference token
  10579. // (will eventually be 0 if slash == std::string::npos)
  10580. start = (slash == std::string::npos) ? 0 : slash + 1,
  10581. // find next slash
  10582. slash = reference_string.find_first_of('/', start))
  10583. {
  10584. // use the text between the beginning of the reference token
  10585. // (start) and the last slash (slash).
  10586. auto reference_token = reference_string.substr(start, slash - start);
  10587. // check reference tokens are properly escaped
  10588. for (std::size_t pos = reference_token.find_first_of('~');
  10589. pos != std::string::npos;
  10590. pos = reference_token.find_first_of('~', pos + 1))
  10591. {
  10592. assert(reference_token[pos] == '~');
  10593. // ~ must be followed by 0 or 1
  10594. if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
  10595. (reference_token[pos + 1] != '0' and
  10596. reference_token[pos + 1] != '1')))
  10597. {
  10598. JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
  10599. }
  10600. }
  10601. // finally, store the reference token
  10602. unescape(reference_token);
  10603. result.push_back(reference_token);
  10604. }
  10605. return result;
  10606. }
  10607. /*!
  10608. @brief replace all occurrences of a substring by another string
  10609. @param[in,out] s the string to manipulate; changed so that all
  10610. occurrences of @a f are replaced with @a t
  10611. @param[in] f the substring to replace with @a t
  10612. @param[in] t the string to replace @a f
  10613. @pre The search string @a f must not be empty. **This precondition is
  10614. enforced with an assertion.**
  10615. @since version 2.0.0
  10616. */
  10617. static void replace_substring(std::string& s, const std::string& f,
  10618. const std::string& t)
  10619. {
  10620. assert(not f.empty());
  10621. for (auto pos = s.find(f); // find first occurrence of f
  10622. pos != std::string::npos; // make sure f was found
  10623. s.replace(pos, f.size(), t), // replace with t, and
  10624. pos = s.find(f, pos + t.size())) // find next occurrence of f
  10625. {}
  10626. }
  10627. /// escape "~" to "~0" and "/" to "~1"
  10628. static std::string escape(std::string s)
  10629. {
  10630. replace_substring(s, "~", "~0");
  10631. replace_substring(s, "/", "~1");
  10632. return s;
  10633. }
  10634. /// unescape "~1" to tilde and "~0" to slash (order is important!)
  10635. static void unescape(std::string& s)
  10636. {
  10637. replace_substring(s, "~1", "/");
  10638. replace_substring(s, "~0", "~");
  10639. }
  10640. /*!
  10641. @param[in] reference_string the reference string to the current value
  10642. @param[in] value the value to consider
  10643. @param[in,out] result the result object to insert values to
  10644. @note Empty objects or arrays are flattened to `null`.
  10645. */
  10646. static void flatten(const std::string& reference_string,
  10647. const BasicJsonType& value,
  10648. BasicJsonType& result)
  10649. {
  10650. switch (value.m_type)
  10651. {
  10652. case detail::value_t::array:
  10653. {
  10654. if (value.m_value.array->empty())
  10655. {
  10656. // flatten empty array as null
  10657. result[reference_string] = nullptr;
  10658. }
  10659. else
  10660. {
  10661. // iterate array and use index as reference string
  10662. for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
  10663. {
  10664. flatten(reference_string + "/" + std::to_string(i),
  10665. value.m_value.array->operator[](i), result);
  10666. }
  10667. }
  10668. break;
  10669. }
  10670. case detail::value_t::object:
  10671. {
  10672. if (value.m_value.object->empty())
  10673. {
  10674. // flatten empty object as null
  10675. result[reference_string] = nullptr;
  10676. }
  10677. else
  10678. {
  10679. // iterate object and use keys as reference string
  10680. for (const auto& element : *value.m_value.object)
  10681. {
  10682. flatten(reference_string + "/" + escape(element.first), element.second, result);
  10683. }
  10684. }
  10685. break;
  10686. }
  10687. default:
  10688. {
  10689. // add primitive value with its reference string
  10690. result[reference_string] = value;
  10691. break;
  10692. }
  10693. }
  10694. }
  10695. /*!
  10696. @param[in] value flattened JSON
  10697. @return unflattened JSON
  10698. @throw parse_error.109 if array index is not a number
  10699. @throw type_error.314 if value is not an object
  10700. @throw type_error.315 if object values are not primitive
  10701. @throw type_error.313 if value cannot be unflattened
  10702. */
  10703. static BasicJsonType
  10704. unflatten(const BasicJsonType& value)
  10705. {
  10706. if (JSON_UNLIKELY(not value.is_object()))
  10707. {
  10708. JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
  10709. }
  10710. BasicJsonType result;
  10711. // iterate the JSON object values
  10712. for (const auto& element : *value.m_value.object)
  10713. {
  10714. if (JSON_UNLIKELY(not element.second.is_primitive()))
  10715. {
  10716. JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
  10717. }
  10718. // assign value to reference pointed to by JSON pointer; Note that if
  10719. // the JSON pointer is "" (i.e., points to the whole value), function
  10720. // get_and_create returns a reference to result itself. An assignment
  10721. // will then create a primitive value.
  10722. json_pointer(element.first).get_and_create(result) = element.second;
  10723. }
  10724. return result;
  10725. }
  10726. friend bool operator==(json_pointer const& lhs,
  10727. json_pointer const& rhs) noexcept
  10728. {
  10729. return (lhs.reference_tokens == rhs.reference_tokens);
  10730. }
  10731. friend bool operator!=(json_pointer const& lhs,
  10732. json_pointer const& rhs) noexcept
  10733. {
  10734. return not (lhs == rhs);
  10735. }
  10736. /// the reference tokens
  10737. std::vector<std::string> reference_tokens;
  10738. };
  10739. } // namespace nlohmann
  10740. // #include <nlohmann/adl_serializer.hpp>
  10741. #include <utility>
  10742. // #include <nlohmann/detail/conversions/from_json.hpp>
  10743. // #include <nlohmann/detail/conversions/to_json.hpp>
  10744. namespace nlohmann
  10745. {
  10746. template<typename, typename>
  10747. struct adl_serializer
  10748. {
  10749. /*!
  10750. @brief convert a JSON value to any value type
  10751. This function is usually called by the `get()` function of the
  10752. @ref basic_json class (either explicit or via conversion operators).
  10753. @param[in] j JSON value to read from
  10754. @param[in,out] val value to write to
  10755. */
  10756. template<typename BasicJsonType, typename ValueType>
  10757. static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
  10758. noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
  10759. -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
  10760. {
  10761. ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
  10762. }
  10763. /*!
  10764. @brief convert any value type to a JSON value
  10765. This function is usually called by the constructors of the @ref basic_json
  10766. class.
  10767. @param[in,out] j JSON value to write to
  10768. @param[in] val value to read from
  10769. */
  10770. template <typename BasicJsonType, typename ValueType>
  10771. static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
  10772. noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
  10773. -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
  10774. {
  10775. ::nlohmann::to_json(j, std::forward<ValueType>(val));
  10776. }
  10777. };
  10778. } // namespace nlohmann
  10779. /*!
  10780. @brief namespace for Niels Lohmann
  10781. @see https://github.com/nlohmann
  10782. @since version 1.0.0
  10783. */
  10784. namespace nlohmann
  10785. {
  10786. /*!
  10787. @brief a class to store JSON values
  10788. @tparam ObjectType type for JSON objects (`std::map` by default; will be used
  10789. in @ref object_t)
  10790. @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
  10791. in @ref array_t)
  10792. @tparam StringType type for JSON strings and object keys (`std::string` by
  10793. default; will be used in @ref string_t)
  10794. @tparam BooleanType type for JSON booleans (`bool` by default; will be used
  10795. in @ref boolean_t)
  10796. @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
  10797. default; will be used in @ref number_integer_t)
  10798. @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
  10799. `uint64_t` by default; will be used in @ref number_unsigned_t)
  10800. @tparam NumberFloatType type for JSON floating-point numbers (`double` by
  10801. default; will be used in @ref number_float_t)
  10802. @tparam AllocatorType type of the allocator to use (`std::allocator` by
  10803. default)
  10804. @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
  10805. and `from_json()` (@ref adl_serializer by default)
  10806. @requirement The class satisfies the following concept requirements:
  10807. - Basic
  10808. - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
  10809. JSON values can be default constructed. The result will be a JSON null
  10810. value.
  10811. - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
  10812. A JSON value can be constructed from an rvalue argument.
  10813. - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
  10814. A JSON value can be copy-constructed from an lvalue expression.
  10815. - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
  10816. A JSON value van be assigned from an rvalue argument.
  10817. - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
  10818. A JSON value can be copy-assigned from an lvalue expression.
  10819. - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
  10820. JSON values can be destructed.
  10821. - Layout
  10822. - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
  10823. JSON values have
  10824. [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
  10825. All non-static data members are private and standard layout types, the
  10826. class has no virtual functions or (virtual) base classes.
  10827. - Library-wide
  10828. - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
  10829. JSON values can be compared with `==`, see @ref
  10830. operator==(const_reference,const_reference).
  10831. - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
  10832. JSON values can be compared with `<`, see @ref
  10833. operator<(const_reference,const_reference).
  10834. - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
  10835. Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
  10836. other compatible types, using unqualified function call @ref swap().
  10837. - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
  10838. JSON values can be compared against `std::nullptr_t` objects which are used
  10839. to model the `null` value.
  10840. - Container
  10841. - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
  10842. JSON values can be used like STL containers and provide iterator access.
  10843. - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
  10844. JSON values can be used like STL containers and provide reverse iterator
  10845. access.
  10846. @invariant The member variables @a m_value and @a m_type have the following
  10847. relationship:
  10848. - If `m_type == value_t::object`, then `m_value.object != nullptr`.
  10849. - If `m_type == value_t::array`, then `m_value.array != nullptr`.
  10850. - If `m_type == value_t::string`, then `m_value.string != nullptr`.
  10851. The invariants are checked by member function assert_invariant().
  10852. @internal
  10853. @note ObjectType trick from http://stackoverflow.com/a/9860911
  10854. @endinternal
  10855. @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
  10856. Format](http://rfc7159.net/rfc7159)
  10857. @since version 1.0.0
  10858. @nosubgrouping
  10859. */
  10860. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  10861. class basic_json
  10862. {
  10863. private:
  10864. template<detail::value_t> friend struct detail::external_constructor;
  10865. friend ::nlohmann::json_pointer<basic_json>;
  10866. friend ::nlohmann::detail::parser<basic_json>;
  10867. friend ::nlohmann::detail::serializer<basic_json>;
  10868. template<typename BasicJsonType>
  10869. friend class ::nlohmann::detail::iter_impl;
  10870. template<typename BasicJsonType, typename CharType>
  10871. friend class ::nlohmann::detail::binary_writer;
  10872. template<typename BasicJsonType, typename SAX>
  10873. friend class ::nlohmann::detail::binary_reader;
  10874. template<typename BasicJsonType>
  10875. friend class ::nlohmann::detail::json_sax_dom_parser;
  10876. template<typename BasicJsonType>
  10877. friend class ::nlohmann::detail::json_sax_dom_callback_parser;
  10878. /// workaround type for MSVC
  10879. using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
  10880. // convenience aliases for types residing in namespace detail;
  10881. using lexer = ::nlohmann::detail::lexer<basic_json>;
  10882. using parser = ::nlohmann::detail::parser<basic_json>;
  10883. using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
  10884. template<typename BasicJsonType>
  10885. using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
  10886. template<typename BasicJsonType>
  10887. using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
  10888. template<typename Iterator>
  10889. using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
  10890. template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
  10891. template<typename CharType>
  10892. using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
  10893. using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
  10894. template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
  10895. using serializer = ::nlohmann::detail::serializer<basic_json>;
  10896. public:
  10897. using value_t = detail::value_t;
  10898. /// JSON Pointer, see @ref nlohmann::json_pointer
  10899. using json_pointer = ::nlohmann::json_pointer<basic_json>;
  10900. template<typename T, typename SFINAE>
  10901. using json_serializer = JSONSerializer<T, SFINAE>;
  10902. /// how to treat decoding errors
  10903. using error_handler_t = detail::error_handler_t;
  10904. /// helper type for initializer lists of basic_json values
  10905. using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
  10906. using input_format_t = detail::input_format_t;
  10907. /// SAX interface type, see @ref nlohmann::json_sax
  10908. using json_sax_t = json_sax<basic_json>;
  10909. ////////////////
  10910. // exceptions //
  10911. ////////////////
  10912. /// @name exceptions
  10913. /// Classes to implement user-defined exceptions.
  10914. /// @{
  10915. /// @copydoc detail::exception
  10916. using exception = detail::exception;
  10917. /// @copydoc detail::parse_error
  10918. using parse_error = detail::parse_error;
  10919. /// @copydoc detail::invalid_iterator
  10920. using invalid_iterator = detail::invalid_iterator;
  10921. /// @copydoc detail::type_error
  10922. using type_error = detail::type_error;
  10923. /// @copydoc detail::out_of_range
  10924. using out_of_range = detail::out_of_range;
  10925. /// @copydoc detail::other_error
  10926. using other_error = detail::other_error;
  10927. /// @}
  10928. /////////////////////
  10929. // container types //
  10930. /////////////////////
  10931. /// @name container types
  10932. /// The canonic container types to use @ref basic_json like any other STL
  10933. /// container.
  10934. /// @{
  10935. /// the type of elements in a basic_json container
  10936. using value_type = basic_json;
  10937. /// the type of an element reference
  10938. using reference = value_type&;
  10939. /// the type of an element const reference
  10940. using const_reference = const value_type&;
  10941. /// a type to represent differences between iterators
  10942. using difference_type = std::ptrdiff_t;
  10943. /// a type to represent container sizes
  10944. using size_type = std::size_t;
  10945. /// the allocator type
  10946. using allocator_type = AllocatorType<basic_json>;
  10947. /// the type of an element pointer
  10948. using pointer = typename std::allocator_traits<allocator_type>::pointer;
  10949. /// the type of an element const pointer
  10950. using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
  10951. /// an iterator for a basic_json container
  10952. using iterator = iter_impl<basic_json>;
  10953. /// a const iterator for a basic_json container
  10954. using const_iterator = iter_impl<const basic_json>;
  10955. /// a reverse iterator for a basic_json container
  10956. using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
  10957. /// a const reverse iterator for a basic_json container
  10958. using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
  10959. /// @}
  10960. /*!
  10961. @brief returns the allocator associated with the container
  10962. */
  10963. static allocator_type get_allocator()
  10964. {
  10965. return allocator_type();
  10966. }
  10967. /*!
  10968. @brief returns version information on the library
  10969. This function returns a JSON object with information about the library,
  10970. including the version number and information on the platform and compiler.
  10971. @return JSON object holding version information
  10972. key | description
  10973. ----------- | ---------------
  10974. `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
  10975. `copyright` | The copyright line for the library as string.
  10976. `name` | The name of the library as string.
  10977. `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
  10978. `url` | The URL of the project as string.
  10979. `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
  10980. @liveexample{The following code shows an example output of the `meta()`
  10981. function.,meta}
  10982. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  10983. changes to any JSON value.
  10984. @complexity Constant.
  10985. @since 2.1.0
  10986. */
  10987. static basic_json meta()
  10988. {
  10989. basic_json result;
  10990. result["copyright"] = "(C) 2013-2017 Niels Lohmann";
  10991. result["name"] = "JSON for Modern C++";
  10992. result["url"] = "https://github.com/nlohmann/json";
  10993. result["version"]["string"] =
  10994. std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
  10995. std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
  10996. std::to_string(NLOHMANN_JSON_VERSION_PATCH);
  10997. result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
  10998. result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
  10999. result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
  11000. #ifdef _WIN32
  11001. result["platform"] = "win32";
  11002. #elif defined __linux__
  11003. result["platform"] = "linux";
  11004. #elif defined __APPLE__
  11005. result["platform"] = "apple";
  11006. #elif defined __unix__
  11007. result["platform"] = "unix";
  11008. #else
  11009. result["platform"] = "unknown";
  11010. #endif
  11011. #if defined(__ICC) || defined(__INTEL_COMPILER)
  11012. result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
  11013. #elif defined(__clang__)
  11014. result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
  11015. #elif defined(__GNUC__) || defined(__GNUG__)
  11016. result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
  11017. #elif defined(__HP_cc) || defined(__HP_aCC)
  11018. result["compiler"] = "hp"
  11019. #elif defined(__IBMCPP__)
  11020. result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
  11021. #elif defined(_MSC_VER)
  11022. result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
  11023. #elif defined(__PGI)
  11024. result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
  11025. #elif defined(__SUNPRO_CC)
  11026. result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
  11027. #else
  11028. result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
  11029. #endif
  11030. #ifdef __cplusplus
  11031. result["compiler"]["c++"] = std::to_string(__cplusplus);
  11032. #else
  11033. result["compiler"]["c++"] = "unknown";
  11034. #endif
  11035. return result;
  11036. }
  11037. ///////////////////////////
  11038. // JSON value data types //
  11039. ///////////////////////////
  11040. /// @name JSON value data types
  11041. /// The data types to store a JSON value. These types are derived from
  11042. /// the template arguments passed to class @ref basic_json.
  11043. /// @{
  11044. #if defined(JSON_HAS_CPP_14)
  11045. // Use transparent comparator if possible, combined with perfect forwarding
  11046. // on find() and count() calls prevents unnecessary string construction.
  11047. using object_comparator_t = std::less<>;
  11048. #else
  11049. using object_comparator_t = std::less<StringType>;
  11050. #endif
  11051. /*!
  11052. @brief a type for an object
  11053. [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
  11054. > An object is an unordered collection of zero or more name/value pairs,
  11055. > where a name is a string and a value is a string, number, boolean, null,
  11056. > object, or array.
  11057. To store objects in C++, a type is defined by the template parameters
  11058. described below.
  11059. @tparam ObjectType the container to store objects (e.g., `std::map` or
  11060. `std::unordered_map`)
  11061. @tparam StringType the type of the keys or names (e.g., `std::string`).
  11062. The comparison function `std::less<StringType>` is used to order elements
  11063. inside the container.
  11064. @tparam AllocatorType the allocator to use for objects (e.g.,
  11065. `std::allocator`)
  11066. #### Default type
  11067. With the default values for @a ObjectType (`std::map`), @a StringType
  11068. (`std::string`), and @a AllocatorType (`std::allocator`), the default
  11069. value for @a object_t is:
  11070. @code {.cpp}
  11071. std::map<
  11072. std::string, // key_type
  11073. basic_json, // value_type
  11074. std::less<std::string>, // key_compare
  11075. std::allocator<std::pair<const std::string, basic_json>> // allocator_type
  11076. >
  11077. @endcode
  11078. #### Behavior
  11079. The choice of @a object_t influences the behavior of the JSON class. With
  11080. the default type, objects have the following behavior:
  11081. - When all names are unique, objects will be interoperable in the sense
  11082. that all software implementations receiving that object will agree on
  11083. the name-value mappings.
  11084. - When the names within an object are not unique, it is unspecified which
  11085. one of the values for a given key will be chosen. For instance,
  11086. `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
  11087. `{"key": 2}`.
  11088. - Internally, name/value pairs are stored in lexicographical order of the
  11089. names. Objects will also be serialized (see @ref dump) in this order.
  11090. For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
  11091. and serialized as `{"a": 2, "b": 1}`.
  11092. - When comparing objects, the order of the name/value pairs is irrelevant.
  11093. This makes objects interoperable in the sense that they will not be
  11094. affected by these differences. For instance, `{"b": 1, "a": 2}` and
  11095. `{"a": 2, "b": 1}` will be treated as equal.
  11096. #### Limits
  11097. [RFC 7159](http://rfc7159.net/rfc7159) specifies:
  11098. > An implementation may set limits on the maximum depth of nesting.
  11099. In this class, the object's limit of nesting is not explicitly constrained.
  11100. However, a maximum depth of nesting may be introduced by the compiler or
  11101. runtime environment. A theoretical limit can be queried by calling the
  11102. @ref max_size function of a JSON object.
  11103. #### Storage
  11104. Objects are stored as pointers in a @ref basic_json type. That is, for any
  11105. access to object values, a pointer of type `object_t*` must be
  11106. dereferenced.
  11107. @sa @ref array_t -- type for an array value
  11108. @since version 1.0.0
  11109. @note The order name/value pairs are added to the object is *not*
  11110. preserved by the library. Therefore, iterating an object may return
  11111. name/value pairs in a different order than they were originally stored. In
  11112. fact, keys will be traversed in alphabetical order as `std::map` with
  11113. `std::less` is used by default. Please note this behavior conforms to [RFC
  11114. 7159](http://rfc7159.net/rfc7159), because any order implements the
  11115. specified "unordered" nature of JSON objects.
  11116. */
  11117. using object_t = ObjectType<StringType,
  11118. basic_json,
  11119. object_comparator_t,
  11120. AllocatorType<std::pair<const StringType,
  11121. basic_json>>>;
  11122. /*!
  11123. @brief a type for an array
  11124. [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
  11125. > An array is an ordered sequence of zero or more values.
  11126. To store objects in C++, a type is defined by the template parameters
  11127. explained below.
  11128. @tparam ArrayType container type to store arrays (e.g., `std::vector` or
  11129. `std::list`)
  11130. @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
  11131. #### Default type
  11132. With the default values for @a ArrayType (`std::vector`) and @a
  11133. AllocatorType (`std::allocator`), the default value for @a array_t is:
  11134. @code {.cpp}
  11135. std::vector<
  11136. basic_json, // value_type
  11137. std::allocator<basic_json> // allocator_type
  11138. >
  11139. @endcode
  11140. #### Limits
  11141. [RFC 7159](http://rfc7159.net/rfc7159) specifies:
  11142. > An implementation may set limits on the maximum depth of nesting.
  11143. In this class, the array's limit of nesting is not explicitly constrained.
  11144. However, a maximum depth of nesting may be introduced by the compiler or
  11145. runtime environment. A theoretical limit can be queried by calling the
  11146. @ref max_size function of a JSON array.
  11147. #### Storage
  11148. Arrays are stored as pointers in a @ref basic_json type. That is, for any
  11149. access to array values, a pointer of type `array_t*` must be dereferenced.
  11150. @sa @ref object_t -- type for an object value
  11151. @since version 1.0.0
  11152. */
  11153. using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
  11154. /*!
  11155. @brief a type for a string
  11156. [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
  11157. > A string is a sequence of zero or more Unicode characters.
  11158. To store objects in C++, a type is defined by the template parameter
  11159. described below. Unicode values are split by the JSON class into
  11160. byte-sized characters during deserialization.
  11161. @tparam StringType the container to store strings (e.g., `std::string`).
  11162. Note this container is used for keys/names in objects, see @ref object_t.
  11163. #### Default type
  11164. With the default values for @a StringType (`std::string`), the default
  11165. value for @a string_t is:
  11166. @code {.cpp}
  11167. std::string
  11168. @endcode
  11169. #### Encoding
  11170. Strings are stored in UTF-8 encoding. Therefore, functions like
  11171. `std::string::size()` or `std::string::length()` return the number of
  11172. bytes in the string rather than the number of characters or glyphs.
  11173. #### String comparison
  11174. [RFC 7159](http://rfc7159.net/rfc7159) states:
  11175. > Software implementations are typically required to test names of object
  11176. > members for equality. Implementations that transform the textual
  11177. > representation into sequences of Unicode code units and then perform the
  11178. > comparison numerically, code unit by code unit, are interoperable in the
  11179. > sense that implementations will agree in all cases on equality or
  11180. > inequality of two strings. For example, implementations that compare
  11181. > strings with escaped characters unconverted may incorrectly find that
  11182. > `"a\\b"` and `"a\u005Cb"` are not equal.
  11183. This implementation is interoperable as it does compare strings code unit
  11184. by code unit.
  11185. #### Storage
  11186. String values are stored as pointers in a @ref basic_json type. That is,
  11187. for any access to string values, a pointer of type `string_t*` must be
  11188. dereferenced.
  11189. @since version 1.0.0
  11190. */
  11191. using string_t = StringType;
  11192. /*!
  11193. @brief a type for a boolean
  11194. [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
  11195. type which differentiates the two literals `true` and `false`.
  11196. To store objects in C++, a type is defined by the template parameter @a
  11197. BooleanType which chooses the type to use.
  11198. #### Default type
  11199. With the default values for @a BooleanType (`bool`), the default value for
  11200. @a boolean_t is:
  11201. @code {.cpp}
  11202. bool
  11203. @endcode
  11204. #### Storage
  11205. Boolean values are stored directly inside a @ref basic_json type.
  11206. @since version 1.0.0
  11207. */
  11208. using boolean_t = BooleanType;
  11209. /*!
  11210. @brief a type for a number (integer)
  11211. [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
  11212. > The representation of numbers is similar to that used in most
  11213. > programming languages. A number is represented in base 10 using decimal
  11214. > digits. It contains an integer component that may be prefixed with an
  11215. > optional minus sign, which may be followed by a fraction part and/or an
  11216. > exponent part. Leading zeros are not allowed. (...) Numeric values that
  11217. > cannot be represented in the grammar below (such as Infinity and NaN)
  11218. > are not permitted.
  11219. This description includes both integer and floating-point numbers.
  11220. However, C++ allows more precise storage if it is known whether the number
  11221. is a signed integer, an unsigned integer or a floating-point number.
  11222. Therefore, three different types, @ref number_integer_t, @ref
  11223. number_unsigned_t and @ref number_float_t are used.
  11224. To store integer numbers in C++, a type is defined by the template
  11225. parameter @a NumberIntegerType which chooses the type to use.
  11226. #### Default type
  11227. With the default values for @a NumberIntegerType (`int64_t`), the default
  11228. value for @a number_integer_t is:
  11229. @code {.cpp}
  11230. int64_t
  11231. @endcode
  11232. #### Default behavior
  11233. - The restrictions about leading zeros is not enforced in C++. Instead,
  11234. leading zeros in integer literals lead to an interpretation as octal
  11235. number. Internally, the value will be stored as decimal number. For
  11236. instance, the C++ integer literal `010` will be serialized to `8`.
  11237. During deserialization, leading zeros yield an error.
  11238. - Not-a-number (NaN) values will be serialized to `null`.
  11239. #### Limits
  11240. [RFC 7159](http://rfc7159.net/rfc7159) specifies:
  11241. > An implementation may set limits on the range and precision of numbers.
  11242. When the default type is used, the maximal integer number that can be
  11243. stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
  11244. that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
  11245. that are out of range will yield over/underflow when used in a
  11246. constructor. During deserialization, too large or small integer numbers
  11247. will be automatically be stored as @ref number_unsigned_t or @ref
  11248. number_float_t.
  11249. [RFC 7159](http://rfc7159.net/rfc7159) further states:
  11250. > Note that when such software is used, numbers that are integers and are
  11251. > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
  11252. > that implementations will agree exactly on their numeric values.
  11253. As this range is a subrange of the exactly supported range [INT64_MIN,
  11254. INT64_MAX], this class's integer type is interoperable.
  11255. #### Storage
  11256. Integer number values are stored directly inside a @ref basic_json type.
  11257. @sa @ref number_float_t -- type for number values (floating-point)
  11258. @sa @ref number_unsigned_t -- type for number values (unsigned integer)
  11259. @since version 1.0.0
  11260. */
  11261. using number_integer_t = NumberIntegerType;
  11262. /*!
  11263. @brief a type for a number (unsigned)
  11264. [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
  11265. > The representation of numbers is similar to that used in most
  11266. > programming languages. A number is represented in base 10 using decimal
  11267. > digits. It contains an integer component that may be prefixed with an
  11268. > optional minus sign, which may be followed by a fraction part and/or an
  11269. > exponent part. Leading zeros are not allowed. (...) Numeric values that
  11270. > cannot be represented in the grammar below (such as Infinity and NaN)
  11271. > are not permitted.
  11272. This description includes both integer and floating-point numbers.
  11273. However, C++ allows more precise storage if it is known whether the number
  11274. is a signed integer, an unsigned integer or a floating-point number.
  11275. Therefore, three different types, @ref number_integer_t, @ref
  11276. number_unsigned_t and @ref number_float_t are used.
  11277. To store unsigned integer numbers in C++, a type is defined by the
  11278. template parameter @a NumberUnsignedType which chooses the type to use.
  11279. #### Default type
  11280. With the default values for @a NumberUnsignedType (`uint64_t`), the
  11281. default value for @a number_unsigned_t is:
  11282. @code {.cpp}
  11283. uint64_t
  11284. @endcode
  11285. #### Default behavior
  11286. - The restrictions about leading zeros is not enforced in C++. Instead,
  11287. leading zeros in integer literals lead to an interpretation as octal
  11288. number. Internally, the value will be stored as decimal number. For
  11289. instance, the C++ integer literal `010` will be serialized to `8`.
  11290. During deserialization, leading zeros yield an error.
  11291. - Not-a-number (NaN) values will be serialized to `null`.
  11292. #### Limits
  11293. [RFC 7159](http://rfc7159.net/rfc7159) specifies:
  11294. > An implementation may set limits on the range and precision of numbers.
  11295. When the default type is used, the maximal integer number that can be
  11296. stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
  11297. number that can be stored is `0`. Integer numbers that are out of range
  11298. will yield over/underflow when used in a constructor. During
  11299. deserialization, too large or small integer numbers will be automatically
  11300. be stored as @ref number_integer_t or @ref number_float_t.
  11301. [RFC 7159](http://rfc7159.net/rfc7159) further states:
  11302. > Note that when such software is used, numbers that are integers and are
  11303. > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
  11304. > that implementations will agree exactly on their numeric values.
  11305. As this range is a subrange (when considered in conjunction with the
  11306. number_integer_t type) of the exactly supported range [0, UINT64_MAX],
  11307. this class's integer type is interoperable.
  11308. #### Storage
  11309. Integer number values are stored directly inside a @ref basic_json type.
  11310. @sa @ref number_float_t -- type for number values (floating-point)
  11311. @sa @ref number_integer_t -- type for number values (integer)
  11312. @since version 2.0.0
  11313. */
  11314. using number_unsigned_t = NumberUnsignedType;
  11315. /*!
  11316. @brief a type for a number (floating-point)
  11317. [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
  11318. > The representation of numbers is similar to that used in most
  11319. > programming languages. A number is represented in base 10 using decimal
  11320. > digits. It contains an integer component that may be prefixed with an
  11321. > optional minus sign, which may be followed by a fraction part and/or an
  11322. > exponent part. Leading zeros are not allowed. (...) Numeric values that
  11323. > cannot be represented in the grammar below (such as Infinity and NaN)
  11324. > are not permitted.
  11325. This description includes both integer and floating-point numbers.
  11326. However, C++ allows more precise storage if it is known whether the number
  11327. is a signed integer, an unsigned integer or a floating-point number.
  11328. Therefore, three different types, @ref number_integer_t, @ref
  11329. number_unsigned_t and @ref number_float_t are used.
  11330. To store floating-point numbers in C++, a type is defined by the template
  11331. parameter @a NumberFloatType which chooses the type to use.
  11332. #### Default type
  11333. With the default values for @a NumberFloatType (`double`), the default
  11334. value for @a number_float_t is:
  11335. @code {.cpp}
  11336. double
  11337. @endcode
  11338. #### Default behavior
  11339. - The restrictions about leading zeros is not enforced in C++. Instead,
  11340. leading zeros in floating-point literals will be ignored. Internally,
  11341. the value will be stored as decimal number. For instance, the C++
  11342. floating-point literal `01.2` will be serialized to `1.2`. During
  11343. deserialization, leading zeros yield an error.
  11344. - Not-a-number (NaN) values will be serialized to `null`.
  11345. #### Limits
  11346. [RFC 7159](http://rfc7159.net/rfc7159) states:
  11347. > This specification allows implementations to set limits on the range and
  11348. > precision of numbers accepted. Since software that implements IEEE
  11349. > 754-2008 binary64 (double precision) numbers is generally available and
  11350. > widely used, good interoperability can be achieved by implementations
  11351. > that expect no more precision or range than these provide, in the sense
  11352. > that implementations will approximate JSON numbers within the expected
  11353. > precision.
  11354. This implementation does exactly follow this approach, as it uses double
  11355. precision floating-point numbers. Note values smaller than
  11356. `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
  11357. will be stored as NaN internally and be serialized to `null`.
  11358. #### Storage
  11359. Floating-point number values are stored directly inside a @ref basic_json
  11360. type.
  11361. @sa @ref number_integer_t -- type for number values (integer)
  11362. @sa @ref number_unsigned_t -- type for number values (unsigned integer)
  11363. @since version 1.0.0
  11364. */
  11365. using number_float_t = NumberFloatType;
  11366. /// @}
  11367. private:
  11368. /// helper for exception-safe object creation
  11369. template<typename T, typename... Args>
  11370. static T* create(Args&& ... args)
  11371. {
  11372. AllocatorType<T> alloc;
  11373. using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
  11374. auto deleter = [&](T * object)
  11375. {
  11376. AllocatorTraits::deallocate(alloc, object, 1);
  11377. };
  11378. std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
  11379. AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
  11380. assert(object != nullptr);
  11381. return object.release();
  11382. }
  11383. ////////////////////////
  11384. // JSON value storage //
  11385. ////////////////////////
  11386. /*!
  11387. @brief a JSON value
  11388. The actual storage for a JSON value of the @ref basic_json class. This
  11389. union combines the different storage types for the JSON value types
  11390. defined in @ref value_t.
  11391. JSON type | value_t type | used type
  11392. --------- | --------------- | ------------------------
  11393. object | object | pointer to @ref object_t
  11394. array | array | pointer to @ref array_t
  11395. string | string | pointer to @ref string_t
  11396. boolean | boolean | @ref boolean_t
  11397. number | number_integer | @ref number_integer_t
  11398. number | number_unsigned | @ref number_unsigned_t
  11399. number | number_float | @ref number_float_t
  11400. null | null | *no value is stored*
  11401. @note Variable-length types (objects, arrays, and strings) are stored as
  11402. pointers. The size of the union should not exceed 64 bits if the default
  11403. value types are used.
  11404. @since version 1.0.0
  11405. */
  11406. union json_value
  11407. {
  11408. /// object (stored with pointer to save storage)
  11409. object_t* object;
  11410. /// array (stored with pointer to save storage)
  11411. array_t* array;
  11412. /// string (stored with pointer to save storage)
  11413. string_t* string;
  11414. /// boolean
  11415. boolean_t boolean;
  11416. /// number (integer)
  11417. number_integer_t number_integer;
  11418. /// number (unsigned integer)
  11419. number_unsigned_t number_unsigned;
  11420. /// number (floating-point)
  11421. number_float_t number_float;
  11422. /// default constructor (for null values)
  11423. json_value() = default;
  11424. /// constructor for booleans
  11425. json_value(boolean_t v) noexcept : boolean(v) {}
  11426. /// constructor for numbers (integer)
  11427. json_value(number_integer_t v) noexcept : number_integer(v) {}
  11428. /// constructor for numbers (unsigned)
  11429. json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
  11430. /// constructor for numbers (floating-point)
  11431. json_value(number_float_t v) noexcept : number_float(v) {}
  11432. /// constructor for empty values of a given type
  11433. json_value(value_t t)
  11434. {
  11435. switch (t)
  11436. {
  11437. case value_t::object:
  11438. {
  11439. object = create<object_t>();
  11440. break;
  11441. }
  11442. case value_t::array:
  11443. {
  11444. array = create<array_t>();
  11445. break;
  11446. }
  11447. case value_t::string:
  11448. {
  11449. string = create<string_t>("");
  11450. break;
  11451. }
  11452. case value_t::boolean:
  11453. {
  11454. boolean = boolean_t(false);
  11455. break;
  11456. }
  11457. case value_t::number_integer:
  11458. {
  11459. number_integer = number_integer_t(0);
  11460. break;
  11461. }
  11462. case value_t::number_unsigned:
  11463. {
  11464. number_unsigned = number_unsigned_t(0);
  11465. break;
  11466. }
  11467. case value_t::number_float:
  11468. {
  11469. number_float = number_float_t(0.0);
  11470. break;
  11471. }
  11472. case value_t::null:
  11473. {
  11474. object = nullptr; // silence warning, see #821
  11475. break;
  11476. }
  11477. default:
  11478. {
  11479. object = nullptr; // silence warning, see #821
  11480. if (JSON_UNLIKELY(t == value_t::null))
  11481. {
  11482. JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.5.0")); // LCOV_EXCL_LINE
  11483. }
  11484. break;
  11485. }
  11486. }
  11487. }
  11488. /// constructor for strings
  11489. json_value(const string_t& value)
  11490. {
  11491. string = create<string_t>(value);
  11492. }
  11493. /// constructor for rvalue strings
  11494. json_value(string_t&& value)
  11495. {
  11496. string = create<string_t>(std::move(value));
  11497. }
  11498. /// constructor for objects
  11499. json_value(const object_t& value)
  11500. {
  11501. object = create<object_t>(value);
  11502. }
  11503. /// constructor for rvalue objects
  11504. json_value(object_t&& value)
  11505. {
  11506. object = create<object_t>(std::move(value));
  11507. }
  11508. /// constructor for arrays
  11509. json_value(const array_t& value)
  11510. {
  11511. array = create<array_t>(value);
  11512. }
  11513. /// constructor for rvalue arrays
  11514. json_value(array_t&& value)
  11515. {
  11516. array = create<array_t>(std::move(value));
  11517. }
  11518. void destroy(value_t t) noexcept
  11519. {
  11520. switch (t)
  11521. {
  11522. case value_t::object:
  11523. {
  11524. AllocatorType<object_t> alloc;
  11525. std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
  11526. std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
  11527. break;
  11528. }
  11529. case value_t::array:
  11530. {
  11531. AllocatorType<array_t> alloc;
  11532. std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
  11533. std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
  11534. break;
  11535. }
  11536. case value_t::string:
  11537. {
  11538. AllocatorType<string_t> alloc;
  11539. std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
  11540. std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
  11541. break;
  11542. }
  11543. default:
  11544. {
  11545. break;
  11546. }
  11547. }
  11548. }
  11549. };
  11550. /*!
  11551. @brief checks the class invariants
  11552. This function asserts the class invariants. It needs to be called at the
  11553. end of every constructor to make sure that created objects respect the
  11554. invariant. Furthermore, it has to be called each time the type of a JSON
  11555. value is changed, because the invariant expresses a relationship between
  11556. @a m_type and @a m_value.
  11557. */
  11558. void assert_invariant() const noexcept
  11559. {
  11560. assert(m_type != value_t::object or m_value.object != nullptr);
  11561. assert(m_type != value_t::array or m_value.array != nullptr);
  11562. assert(m_type != value_t::string or m_value.string != nullptr);
  11563. }
  11564. public:
  11565. //////////////////////////
  11566. // JSON parser callback //
  11567. //////////////////////////
  11568. /*!
  11569. @brief parser event types
  11570. The parser callback distinguishes the following events:
  11571. - `object_start`: the parser read `{` and started to process a JSON object
  11572. - `key`: the parser read a key of a value in an object
  11573. - `object_end`: the parser read `}` and finished processing a JSON object
  11574. - `array_start`: the parser read `[` and started to process a JSON array
  11575. - `array_end`: the parser read `]` and finished processing a JSON array
  11576. - `value`: the parser finished reading a JSON value
  11577. @image html callback_events.png "Example when certain parse events are triggered"
  11578. @sa @ref parser_callback_t for more information and examples
  11579. */
  11580. using parse_event_t = typename parser::parse_event_t;
  11581. /*!
  11582. @brief per-element parser callback type
  11583. With a parser callback function, the result of parsing a JSON text can be
  11584. influenced. When passed to @ref parse, it is called on certain events
  11585. (passed as @ref parse_event_t via parameter @a event) with a set recursion
  11586. depth @a depth and context JSON value @a parsed. The return value of the
  11587. callback function is a boolean indicating whether the element that emitted
  11588. the callback shall be kept or not.
  11589. We distinguish six scenarios (determined by the event type) in which the
  11590. callback function can be called. The following table describes the values
  11591. of the parameters @a depth, @a event, and @a parsed.
  11592. parameter @a event | description | parameter @a depth | parameter @a parsed
  11593. ------------------ | ----------- | ------------------ | -------------------
  11594. parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
  11595. parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
  11596. parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
  11597. parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
  11598. parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
  11599. parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
  11600. @image html callback_events.png "Example when certain parse events are triggered"
  11601. Discarding a value (i.e., returning `false`) has different effects
  11602. depending on the context in which function was called:
  11603. - Discarded values in structured types are skipped. That is, the parser
  11604. will behave as if the discarded value was never read.
  11605. - In case a value outside a structured type is skipped, it is replaced
  11606. with `null`. This case happens if the top-level element is skipped.
  11607. @param[in] depth the depth of the recursion during parsing
  11608. @param[in] event an event of type parse_event_t indicating the context in
  11609. the callback function has been called
  11610. @param[in,out] parsed the current intermediate parse result; note that
  11611. writing to this value has no effect for parse_event_t::key events
  11612. @return Whether the JSON value which called the function during parsing
  11613. should be kept (`true`) or not (`false`). In the latter case, it is either
  11614. skipped completely or replaced by an empty discarded object.
  11615. @sa @ref parse for examples
  11616. @since version 1.0.0
  11617. */
  11618. using parser_callback_t = typename parser::parser_callback_t;
  11619. //////////////////
  11620. // constructors //
  11621. //////////////////
  11622. /// @name constructors and destructors
  11623. /// Constructors of class @ref basic_json, copy/move constructor, copy
  11624. /// assignment, static functions creating objects, and the destructor.
  11625. /// @{
  11626. /*!
  11627. @brief create an empty value with a given type
  11628. Create an empty JSON value with a given type. The value will be default
  11629. initialized with an empty value which depends on the type:
  11630. Value type | initial value
  11631. ----------- | -------------
  11632. null | `null`
  11633. boolean | `false`
  11634. string | `""`
  11635. number | `0`
  11636. object | `{}`
  11637. array | `[]`
  11638. @param[in] v the type of the value to create
  11639. @complexity Constant.
  11640. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  11641. changes to any JSON value.
  11642. @liveexample{The following code shows the constructor for different @ref
  11643. value_t values,basic_json__value_t}
  11644. @sa @ref clear() -- restores the postcondition of this constructor
  11645. @since version 1.0.0
  11646. */
  11647. basic_json(const value_t v)
  11648. : m_type(v), m_value(v)
  11649. {
  11650. assert_invariant();
  11651. }
  11652. /*!
  11653. @brief create a null object
  11654. Create a `null` JSON value. It either takes a null pointer as parameter
  11655. (explicitly creating `null`) or no parameter (implicitly creating `null`).
  11656. The passed null pointer itself is not read -- it is only used to choose
  11657. the right constructor.
  11658. @complexity Constant.
  11659. @exceptionsafety No-throw guarantee: this constructor never throws
  11660. exceptions.
  11661. @liveexample{The following code shows the constructor with and without a
  11662. null pointer parameter.,basic_json__nullptr_t}
  11663. @since version 1.0.0
  11664. */
  11665. basic_json(std::nullptr_t = nullptr) noexcept
  11666. : basic_json(value_t::null)
  11667. {
  11668. assert_invariant();
  11669. }
  11670. /*!
  11671. @brief create a JSON value
  11672. This is a "catch all" constructor for all compatible JSON types; that is,
  11673. types for which a `to_json()` method exists. The constructor forwards the
  11674. parameter @a val to that method (to `json_serializer<U>::to_json` method
  11675. with `U = uncvref_t<CompatibleType>`, to be exact).
  11676. Template type @a CompatibleType includes, but is not limited to, the
  11677. following types:
  11678. - **arrays**: @ref array_t and all kinds of compatible containers such as
  11679. `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
  11680. `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
  11681. `std::multiset`, and `std::unordered_multiset` with a `value_type` from
  11682. which a @ref basic_json value can be constructed.
  11683. - **objects**: @ref object_t and all kinds of compatible associative
  11684. containers such as `std::map`, `std::unordered_map`, `std::multimap`,
  11685. and `std::unordered_multimap` with a `key_type` compatible to
  11686. @ref string_t and a `value_type` from which a @ref basic_json value can
  11687. be constructed.
  11688. - **strings**: @ref string_t, string literals, and all compatible string
  11689. containers can be used.
  11690. - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
  11691. @ref number_float_t, and all convertible number types such as `int`,
  11692. `size_t`, `int64_t`, `float` or `double` can be used.
  11693. - **boolean**: @ref boolean_t / `bool` can be used.
  11694. See the examples below.
  11695. @tparam CompatibleType a type such that:
  11696. - @a CompatibleType is not derived from `std::istream`,
  11697. - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
  11698. constructors),
  11699. - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
  11700. - @a CompatibleType is not a @ref basic_json nested type (e.g.,
  11701. @ref json_pointer, @ref iterator, etc ...)
  11702. - @ref @ref json_serializer<U> has a
  11703. `to_json(basic_json_t&, CompatibleType&&)` method
  11704. @tparam U = `uncvref_t<CompatibleType>`
  11705. @param[in] val the value to be forwarded to the respective constructor
  11706. @complexity Usually linear in the size of the passed @a val, also
  11707. depending on the implementation of the called `to_json()`
  11708. method.
  11709. @exceptionsafety Depends on the called constructor. For types directly
  11710. supported by the library (i.e., all types for which no `to_json()` function
  11711. was provided), strong guarantee holds: if an exception is thrown, there are
  11712. no changes to any JSON value.
  11713. @liveexample{The following code shows the constructor with several
  11714. compatible types.,basic_json__CompatibleType}
  11715. @since version 2.1.0
  11716. */
  11717. template <typename CompatibleType,
  11718. typename U = detail::uncvref_t<CompatibleType>,
  11719. detail::enable_if_t<
  11720. not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
  11721. basic_json(CompatibleType && val) noexcept(noexcept(
  11722. JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
  11723. std::forward<CompatibleType>(val))))
  11724. {
  11725. JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
  11726. assert_invariant();
  11727. }
  11728. /*!
  11729. @brief create a JSON value from an existing one
  11730. This is a constructor for existing @ref basic_json types.
  11731. It does not hijack copy/move constructors, since the parameter has different
  11732. template arguments than the current ones.
  11733. The constructor tries to convert the internal @ref m_value of the parameter.
  11734. @tparam BasicJsonType a type such that:
  11735. - @a BasicJsonType is a @ref basic_json type.
  11736. - @a BasicJsonType has different template arguments than @ref basic_json_t.
  11737. @param[in] val the @ref basic_json value to be converted.
  11738. @complexity Usually linear in the size of the passed @a val, also
  11739. depending on the implementation of the called `to_json()`
  11740. method.
  11741. @exceptionsafety Depends on the called constructor. For types directly
  11742. supported by the library (i.e., all types for which no `to_json()` function
  11743. was provided), strong guarantee holds: if an exception is thrown, there are
  11744. no changes to any JSON value.
  11745. @since version 3.2.0
  11746. */
  11747. template <typename BasicJsonType,
  11748. detail::enable_if_t<
  11749. detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
  11750. basic_json(const BasicJsonType& val)
  11751. {
  11752. using other_boolean_t = typename BasicJsonType::boolean_t;
  11753. using other_number_float_t = typename BasicJsonType::number_float_t;
  11754. using other_number_integer_t = typename BasicJsonType::number_integer_t;
  11755. using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  11756. using other_string_t = typename BasicJsonType::string_t;
  11757. using other_object_t = typename BasicJsonType::object_t;
  11758. using other_array_t = typename BasicJsonType::array_t;
  11759. switch (val.type())
  11760. {
  11761. case value_t::boolean:
  11762. JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
  11763. break;
  11764. case value_t::number_float:
  11765. JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
  11766. break;
  11767. case value_t::number_integer:
  11768. JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
  11769. break;
  11770. case value_t::number_unsigned:
  11771. JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
  11772. break;
  11773. case value_t::string:
  11774. JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
  11775. break;
  11776. case value_t::object:
  11777. JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
  11778. break;
  11779. case value_t::array:
  11780. JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
  11781. break;
  11782. case value_t::null:
  11783. *this = nullptr;
  11784. break;
  11785. case value_t::discarded:
  11786. m_type = value_t::discarded;
  11787. break;
  11788. }
  11789. assert_invariant();
  11790. }
  11791. /*!
  11792. @brief create a container (array or object) from an initializer list
  11793. Creates a JSON value of type array or object from the passed initializer
  11794. list @a init. In case @a type_deduction is `true` (default), the type of
  11795. the JSON value to be created is deducted from the initializer list @a init
  11796. according to the following rules:
  11797. 1. If the list is empty, an empty JSON object value `{}` is created.
  11798. 2. If the list consists of pairs whose first element is a string, a JSON
  11799. object value is created where the first elements of the pairs are
  11800. treated as keys and the second elements are as values.
  11801. 3. In all other cases, an array is created.
  11802. The rules aim to create the best fit between a C++ initializer list and
  11803. JSON values. The rationale is as follows:
  11804. 1. The empty initializer list is written as `{}` which is exactly an empty
  11805. JSON object.
  11806. 2. C++ has no way of describing mapped types other than to list a list of
  11807. pairs. As JSON requires that keys must be of type string, rule 2 is the
  11808. weakest constraint one can pose on initializer lists to interpret them
  11809. as an object.
  11810. 3. In all other cases, the initializer list could not be interpreted as
  11811. JSON object type, so interpreting it as JSON array type is safe.
  11812. With the rules described above, the following JSON values cannot be
  11813. expressed by an initializer list:
  11814. - the empty array (`[]`): use @ref array(initializer_list_t)
  11815. with an empty initializer list in this case
  11816. - arrays whose elements satisfy rule 2: use @ref
  11817. array(initializer_list_t) with the same initializer list
  11818. in this case
  11819. @note When used without parentheses around an empty initializer list, @ref
  11820. basic_json() is called instead of this function, yielding the JSON null
  11821. value.
  11822. @param[in] init initializer list with JSON values
  11823. @param[in] type_deduction internal parameter; when set to `true`, the type
  11824. of the JSON value is deducted from the initializer list @a init; when set
  11825. to `false`, the type provided via @a manual_type is forced. This mode is
  11826. used by the functions @ref array(initializer_list_t) and
  11827. @ref object(initializer_list_t).
  11828. @param[in] manual_type internal parameter; when @a type_deduction is set
  11829. to `false`, the created JSON value will use the provided type (only @ref
  11830. value_t::array and @ref value_t::object are valid); when @a type_deduction
  11831. is set to `true`, this parameter has no effect
  11832. @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
  11833. `value_t::object`, but @a init contains an element which is not a pair
  11834. whose first element is a string. In this case, the constructor could not
  11835. create an object. If @a type_deduction would have be `true`, an array
  11836. would have been created. See @ref object(initializer_list_t)
  11837. for an example.
  11838. @complexity Linear in the size of the initializer list @a init.
  11839. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  11840. changes to any JSON value.
  11841. @liveexample{The example below shows how JSON values are created from
  11842. initializer lists.,basic_json__list_init_t}
  11843. @sa @ref array(initializer_list_t) -- create a JSON array
  11844. value from an initializer list
  11845. @sa @ref object(initializer_list_t) -- create a JSON object
  11846. value from an initializer list
  11847. @since version 1.0.0
  11848. */
  11849. basic_json(initializer_list_t init,
  11850. bool type_deduction = true,
  11851. value_t manual_type = value_t::array)
  11852. {
  11853. // check if each element is an array with two elements whose first
  11854. // element is a string
  11855. bool is_an_object = std::all_of(init.begin(), init.end(),
  11856. [](const detail::json_ref<basic_json>& element_ref)
  11857. {
  11858. return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
  11859. });
  11860. // adjust type if type deduction is not wanted
  11861. if (not type_deduction)
  11862. {
  11863. // if array is wanted, do not create an object though possible
  11864. if (manual_type == value_t::array)
  11865. {
  11866. is_an_object = false;
  11867. }
  11868. // if object is wanted but impossible, throw an exception
  11869. if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
  11870. {
  11871. JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
  11872. }
  11873. }
  11874. if (is_an_object)
  11875. {
  11876. // the initializer list is a list of pairs -> create object
  11877. m_type = value_t::object;
  11878. m_value = value_t::object;
  11879. std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
  11880. {
  11881. auto element = element_ref.moved_or_copied();
  11882. m_value.object->emplace(
  11883. std::move(*((*element.m_value.array)[0].m_value.string)),
  11884. std::move((*element.m_value.array)[1]));
  11885. });
  11886. }
  11887. else
  11888. {
  11889. // the initializer list describes an array -> create array
  11890. m_type = value_t::array;
  11891. m_value.array = create<array_t>(init.begin(), init.end());
  11892. }
  11893. assert_invariant();
  11894. }
  11895. /*!
  11896. @brief explicitly create an array from an initializer list
  11897. Creates a JSON array value from a given initializer list. That is, given a
  11898. list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
  11899. initializer list is empty, the empty array `[]` is created.
  11900. @note This function is only needed to express two edge cases that cannot
  11901. be realized with the initializer list constructor (@ref
  11902. basic_json(initializer_list_t, bool, value_t)). These cases
  11903. are:
  11904. 1. creating an array whose elements are all pairs whose first element is a
  11905. string -- in this case, the initializer list constructor would create an
  11906. object, taking the first elements as keys
  11907. 2. creating an empty array -- passing the empty initializer list to the
  11908. initializer list constructor yields an empty object
  11909. @param[in] init initializer list with JSON values to create an array from
  11910. (optional)
  11911. @return JSON array value
  11912. @complexity Linear in the size of @a init.
  11913. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  11914. changes to any JSON value.
  11915. @liveexample{The following code shows an example for the `array`
  11916. function.,array}
  11917. @sa @ref basic_json(initializer_list_t, bool, value_t) --
  11918. create a JSON value from an initializer list
  11919. @sa @ref object(initializer_list_t) -- create a JSON object
  11920. value from an initializer list
  11921. @since version 1.0.0
  11922. */
  11923. static basic_json array(initializer_list_t init = {})
  11924. {
  11925. return basic_json(init, false, value_t::array);
  11926. }
  11927. /*!
  11928. @brief explicitly create an object from an initializer list
  11929. Creates a JSON object value from a given initializer list. The initializer
  11930. lists elements must be pairs, and their first elements must be strings. If
  11931. the initializer list is empty, the empty object `{}` is created.
  11932. @note This function is only added for symmetry reasons. In contrast to the
  11933. related function @ref array(initializer_list_t), there are
  11934. no cases which can only be expressed by this function. That is, any
  11935. initializer list @a init can also be passed to the initializer list
  11936. constructor @ref basic_json(initializer_list_t, bool, value_t).
  11937. @param[in] init initializer list to create an object from (optional)
  11938. @return JSON object value
  11939. @throw type_error.301 if @a init is not a list of pairs whose first
  11940. elements are strings. In this case, no object can be created. When such a
  11941. value is passed to @ref basic_json(initializer_list_t, bool, value_t),
  11942. an array would have been created from the passed initializer list @a init.
  11943. See example below.
  11944. @complexity Linear in the size of @a init.
  11945. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  11946. changes to any JSON value.
  11947. @liveexample{The following code shows an example for the `object`
  11948. function.,object}
  11949. @sa @ref basic_json(initializer_list_t, bool, value_t) --
  11950. create a JSON value from an initializer list
  11951. @sa @ref array(initializer_list_t) -- create a JSON array
  11952. value from an initializer list
  11953. @since version 1.0.0
  11954. */
  11955. static basic_json object(initializer_list_t init = {})
  11956. {
  11957. return basic_json(init, false, value_t::object);
  11958. }
  11959. /*!
  11960. @brief construct an array with count copies of given value
  11961. Constructs a JSON array value by creating @a cnt copies of a passed value.
  11962. In case @a cnt is `0`, an empty array is created.
  11963. @param[in] cnt the number of JSON copies of @a val to create
  11964. @param[in] val the JSON value to copy
  11965. @post `std::distance(begin(),end()) == cnt` holds.
  11966. @complexity Linear in @a cnt.
  11967. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  11968. changes to any JSON value.
  11969. @liveexample{The following code shows examples for the @ref
  11970. basic_json(size_type\, const basic_json&)
  11971. constructor.,basic_json__size_type_basic_json}
  11972. @since version 1.0.0
  11973. */
  11974. basic_json(size_type cnt, const basic_json& val)
  11975. : m_type(value_t::array)
  11976. {
  11977. m_value.array = create<array_t>(cnt, val);
  11978. assert_invariant();
  11979. }
  11980. /*!
  11981. @brief construct a JSON container given an iterator range
  11982. Constructs the JSON value with the contents of the range `[first, last)`.
  11983. The semantics depends on the different types a JSON value can have:
  11984. - In case of a null type, invalid_iterator.206 is thrown.
  11985. - In case of other primitive types (number, boolean, or string), @a first
  11986. must be `begin()` and @a last must be `end()`. In this case, the value is
  11987. copied. Otherwise, invalid_iterator.204 is thrown.
  11988. - In case of structured types (array, object), the constructor behaves as
  11989. similar versions for `std::vector` or `std::map`; that is, a JSON array
  11990. or object is constructed from the values in the range.
  11991. @tparam InputIT an input iterator type (@ref iterator or @ref
  11992. const_iterator)
  11993. @param[in] first begin of the range to copy from (included)
  11994. @param[in] last end of the range to copy from (excluded)
  11995. @pre Iterators @a first and @a last must be initialized. **This
  11996. precondition is enforced with an assertion (see warning).** If
  11997. assertions are switched off, a violation of this precondition yields
  11998. undefined behavior.
  11999. @pre Range `[first, last)` is valid. Usually, this precondition cannot be
  12000. checked efficiently. Only certain edge cases are detected; see the
  12001. description of the exceptions below. A violation of this precondition
  12002. yields undefined behavior.
  12003. @warning A precondition is enforced with a runtime assertion that will
  12004. result in calling `std::abort` if this precondition is not met.
  12005. Assertions can be disabled by defining `NDEBUG` at compile time.
  12006. See https://en.cppreference.com/w/cpp/error/assert for more
  12007. information.
  12008. @throw invalid_iterator.201 if iterators @a first and @a last are not
  12009. compatible (i.e., do not belong to the same JSON value). In this case,
  12010. the range `[first, last)` is undefined.
  12011. @throw invalid_iterator.204 if iterators @a first and @a last belong to a
  12012. primitive type (number, boolean, or string), but @a first does not point
  12013. to the first element any more. In this case, the range `[first, last)` is
  12014. undefined. See example code below.
  12015. @throw invalid_iterator.206 if iterators @a first and @a last belong to a
  12016. null value. In this case, the range `[first, last)` is undefined.
  12017. @complexity Linear in distance between @a first and @a last.
  12018. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  12019. changes to any JSON value.
  12020. @liveexample{The example below shows several ways to create JSON values by
  12021. specifying a subrange with iterators.,basic_json__InputIt_InputIt}
  12022. @since version 1.0.0
  12023. */
  12024. template<class InputIT, typename std::enable_if<
  12025. std::is_same<InputIT, typename basic_json_t::iterator>::value or
  12026. std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
  12027. basic_json(InputIT first, InputIT last)
  12028. {
  12029. assert(first.m_object != nullptr);
  12030. assert(last.m_object != nullptr);
  12031. // make sure iterator fits the current value
  12032. if (JSON_UNLIKELY(first.m_object != last.m_object))
  12033. {
  12034. JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
  12035. }
  12036. // copy type from first iterator
  12037. m_type = first.m_object->m_type;
  12038. // check if iterator range is complete for primitive values
  12039. switch (m_type)
  12040. {
  12041. case value_t::boolean:
  12042. case value_t::number_float:
  12043. case value_t::number_integer:
  12044. case value_t::number_unsigned:
  12045. case value_t::string:
  12046. {
  12047. if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
  12048. or not last.m_it.primitive_iterator.is_end()))
  12049. {
  12050. JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
  12051. }
  12052. break;
  12053. }
  12054. default:
  12055. break;
  12056. }
  12057. switch (m_type)
  12058. {
  12059. case value_t::number_integer:
  12060. {
  12061. m_value.number_integer = first.m_object->m_value.number_integer;
  12062. break;
  12063. }
  12064. case value_t::number_unsigned:
  12065. {
  12066. m_value.number_unsigned = first.m_object->m_value.number_unsigned;
  12067. break;
  12068. }
  12069. case value_t::number_float:
  12070. {
  12071. m_value.number_float = first.m_object->m_value.number_float;
  12072. break;
  12073. }
  12074. case value_t::boolean:
  12075. {
  12076. m_value.boolean = first.m_object->m_value.boolean;
  12077. break;
  12078. }
  12079. case value_t::string:
  12080. {
  12081. m_value = *first.m_object->m_value.string;
  12082. break;
  12083. }
  12084. case value_t::object:
  12085. {
  12086. m_value.object = create<object_t>(first.m_it.object_iterator,
  12087. last.m_it.object_iterator);
  12088. break;
  12089. }
  12090. case value_t::array:
  12091. {
  12092. m_value.array = create<array_t>(first.m_it.array_iterator,
  12093. last.m_it.array_iterator);
  12094. break;
  12095. }
  12096. default:
  12097. JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
  12098. std::string(first.m_object->type_name())));
  12099. }
  12100. assert_invariant();
  12101. }
  12102. ///////////////////////////////////////
  12103. // other constructors and destructor //
  12104. ///////////////////////////////////////
  12105. /// @private
  12106. basic_json(const detail::json_ref<basic_json>& ref)
  12107. : basic_json(ref.moved_or_copied())
  12108. {}
  12109. /*!
  12110. @brief copy constructor
  12111. Creates a copy of a given JSON value.
  12112. @param[in] other the JSON value to copy
  12113. @post `*this == other`
  12114. @complexity Linear in the size of @a other.
  12115. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  12116. changes to any JSON value.
  12117. @requirement This function helps `basic_json` satisfying the
  12118. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  12119. requirements:
  12120. - The complexity is linear.
  12121. - As postcondition, it holds: `other == basic_json(other)`.
  12122. @liveexample{The following code shows an example for the copy
  12123. constructor.,basic_json__basic_json}
  12124. @since version 1.0.0
  12125. */
  12126. basic_json(const basic_json& other)
  12127. : m_type(other.m_type)
  12128. {
  12129. // check of passed value is valid
  12130. other.assert_invariant();
  12131. switch (m_type)
  12132. {
  12133. case value_t::object:
  12134. {
  12135. m_value = *other.m_value.object;
  12136. break;
  12137. }
  12138. case value_t::array:
  12139. {
  12140. m_value = *other.m_value.array;
  12141. break;
  12142. }
  12143. case value_t::string:
  12144. {
  12145. m_value = *other.m_value.string;
  12146. break;
  12147. }
  12148. case value_t::boolean:
  12149. {
  12150. m_value = other.m_value.boolean;
  12151. break;
  12152. }
  12153. case value_t::number_integer:
  12154. {
  12155. m_value = other.m_value.number_integer;
  12156. break;
  12157. }
  12158. case value_t::number_unsigned:
  12159. {
  12160. m_value = other.m_value.number_unsigned;
  12161. break;
  12162. }
  12163. case value_t::number_float:
  12164. {
  12165. m_value = other.m_value.number_float;
  12166. break;
  12167. }
  12168. default:
  12169. break;
  12170. }
  12171. assert_invariant();
  12172. }
  12173. /*!
  12174. @brief move constructor
  12175. Move constructor. Constructs a JSON value with the contents of the given
  12176. value @a other using move semantics. It "steals" the resources from @a
  12177. other and leaves it as JSON null value.
  12178. @param[in,out] other value to move to this object
  12179. @post `*this` has the same value as @a other before the call.
  12180. @post @a other is a JSON null value.
  12181. @complexity Constant.
  12182. @exceptionsafety No-throw guarantee: this constructor never throws
  12183. exceptions.
  12184. @requirement This function helps `basic_json` satisfying the
  12185. [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
  12186. requirements.
  12187. @liveexample{The code below shows the move constructor explicitly called
  12188. via std::move.,basic_json__moveconstructor}
  12189. @since version 1.0.0
  12190. */
  12191. basic_json(basic_json&& other) noexcept
  12192. : m_type(std::move(other.m_type)),
  12193. m_value(std::move(other.m_value))
  12194. {
  12195. // check that passed value is valid
  12196. other.assert_invariant();
  12197. // invalidate payload
  12198. other.m_type = value_t::null;
  12199. other.m_value = {};
  12200. assert_invariant();
  12201. }
  12202. /*!
  12203. @brief copy assignment
  12204. Copy assignment operator. Copies a JSON value via the "copy and swap"
  12205. strategy: It is expressed in terms of the copy constructor, destructor,
  12206. and the `swap()` member function.
  12207. @param[in] other value to copy from
  12208. @complexity Linear.
  12209. @requirement This function helps `basic_json` satisfying the
  12210. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  12211. requirements:
  12212. - The complexity is linear.
  12213. @liveexample{The code below shows and example for the copy assignment. It
  12214. creates a copy of value `a` which is then swapped with `b`. Finally\, the
  12215. copy of `a` (which is the null value after the swap) is
  12216. destroyed.,basic_json__copyassignment}
  12217. @since version 1.0.0
  12218. */
  12219. basic_json& operator=(basic_json other) noexcept (
  12220. std::is_nothrow_move_constructible<value_t>::value and
  12221. std::is_nothrow_move_assignable<value_t>::value and
  12222. std::is_nothrow_move_constructible<json_value>::value and
  12223. std::is_nothrow_move_assignable<json_value>::value
  12224. )
  12225. {
  12226. // check that passed value is valid
  12227. other.assert_invariant();
  12228. using std::swap;
  12229. swap(m_type, other.m_type);
  12230. swap(m_value, other.m_value);
  12231. assert_invariant();
  12232. return *this;
  12233. }
  12234. /*!
  12235. @brief destructor
  12236. Destroys the JSON value and frees all allocated memory.
  12237. @complexity Linear.
  12238. @requirement This function helps `basic_json` satisfying the
  12239. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  12240. requirements:
  12241. - The complexity is linear.
  12242. - All stored elements are destroyed and all memory is freed.
  12243. @since version 1.0.0
  12244. */
  12245. ~basic_json() noexcept
  12246. {
  12247. assert_invariant();
  12248. m_value.destroy(m_type);
  12249. }
  12250. /// @}
  12251. public:
  12252. ///////////////////////
  12253. // object inspection //
  12254. ///////////////////////
  12255. /// @name object inspection
  12256. /// Functions to inspect the type of a JSON value.
  12257. /// @{
  12258. /*!
  12259. @brief serialization
  12260. Serialization function for JSON values. The function tries to mimic
  12261. Python's `json.dumps()` function, and currently supports its @a indent
  12262. and @a ensure_ascii parameters.
  12263. @param[in] indent If indent is nonnegative, then array elements and object
  12264. members will be pretty-printed with that indent level. An indent level of
  12265. `0` will only insert newlines. `-1` (the default) selects the most compact
  12266. representation.
  12267. @param[in] indent_char The character to use for indentation if @a indent is
  12268. greater than `0`. The default is ` ` (space).
  12269. @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
  12270. in the output are escaped with `\uXXXX` sequences, and the result consists
  12271. of ASCII characters only.
  12272. @param[in] error_handler how to react on decoding errors; there are three
  12273. possible values: `strict` (throws and exception in case a decoding error
  12274. occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
  12275. and `ignore` (ignore invalid UTF-8 sequences during serialization).
  12276. @return string containing the serialization of the JSON value
  12277. @throw type_error.316 if a string stored inside the JSON value is not
  12278. UTF-8 encoded
  12279. @complexity Linear.
  12280. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  12281. changes in the JSON value.
  12282. @liveexample{The following example shows the effect of different @a indent\,
  12283. @a indent_char\, and @a ensure_ascii parameters to the result of the
  12284. serialization.,dump}
  12285. @see https://docs.python.org/2/library/json.html#json.dump
  12286. @since version 1.0.0; indentation character @a indent_char, option
  12287. @a ensure_ascii and exceptions added in version 3.0.0; error
  12288. handlers added in version 3.4.0.
  12289. */
  12290. string_t dump(const int indent = -1,
  12291. const char indent_char = ' ',
  12292. const bool ensure_ascii = false,
  12293. const error_handler_t error_handler = error_handler_t::strict) const
  12294. {
  12295. string_t result;
  12296. serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
  12297. if (indent >= 0)
  12298. {
  12299. s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
  12300. }
  12301. else
  12302. {
  12303. s.dump(*this, false, ensure_ascii, 0);
  12304. }
  12305. return result;
  12306. }
  12307. /*!
  12308. @brief return the type of the JSON value (explicit)
  12309. Return the type of the JSON value as a value from the @ref value_t
  12310. enumeration.
  12311. @return the type of the JSON value
  12312. Value type | return value
  12313. ------------------------- | -------------------------
  12314. null | value_t::null
  12315. boolean | value_t::boolean
  12316. string | value_t::string
  12317. number (integer) | value_t::number_integer
  12318. number (unsigned integer) | value_t::number_unsigned
  12319. number (floating-point) | value_t::number_float
  12320. object | value_t::object
  12321. array | value_t::array
  12322. discarded | value_t::discarded
  12323. @complexity Constant.
  12324. @exceptionsafety No-throw guarantee: this member function never throws
  12325. exceptions.
  12326. @liveexample{The following code exemplifies `type()` for all JSON
  12327. types.,type}
  12328. @sa @ref operator value_t() -- return the type of the JSON value (implicit)
  12329. @sa @ref type_name() -- return the type as string
  12330. @since version 1.0.0
  12331. */
  12332. constexpr value_t type() const noexcept
  12333. {
  12334. return m_type;
  12335. }
  12336. /*!
  12337. @brief return whether type is primitive
  12338. This function returns true if and only if the JSON type is primitive
  12339. (string, number, boolean, or null).
  12340. @return `true` if type is primitive (string, number, boolean, or null),
  12341. `false` otherwise.
  12342. @complexity Constant.
  12343. @exceptionsafety No-throw guarantee: this member function never throws
  12344. exceptions.
  12345. @liveexample{The following code exemplifies `is_primitive()` for all JSON
  12346. types.,is_primitive}
  12347. @sa @ref is_structured() -- returns whether JSON value is structured
  12348. @sa @ref is_null() -- returns whether JSON value is `null`
  12349. @sa @ref is_string() -- returns whether JSON value is a string
  12350. @sa @ref is_boolean() -- returns whether JSON value is a boolean
  12351. @sa @ref is_number() -- returns whether JSON value is a number
  12352. @since version 1.0.0
  12353. */
  12354. constexpr bool is_primitive() const noexcept
  12355. {
  12356. return is_null() or is_string() or is_boolean() or is_number();
  12357. }
  12358. /*!
  12359. @brief return whether type is structured
  12360. This function returns true if and only if the JSON type is structured
  12361. (array or object).
  12362. @return `true` if type is structured (array or object), `false` otherwise.
  12363. @complexity Constant.
  12364. @exceptionsafety No-throw guarantee: this member function never throws
  12365. exceptions.
  12366. @liveexample{The following code exemplifies `is_structured()` for all JSON
  12367. types.,is_structured}
  12368. @sa @ref is_primitive() -- returns whether value is primitive
  12369. @sa @ref is_array() -- returns whether value is an array
  12370. @sa @ref is_object() -- returns whether value is an object
  12371. @since version 1.0.0
  12372. */
  12373. constexpr bool is_structured() const noexcept
  12374. {
  12375. return is_array() or is_object();
  12376. }
  12377. /*!
  12378. @brief return whether value is null
  12379. This function returns true if and only if the JSON value is null.
  12380. @return `true` if type is null, `false` otherwise.
  12381. @complexity Constant.
  12382. @exceptionsafety No-throw guarantee: this member function never throws
  12383. exceptions.
  12384. @liveexample{The following code exemplifies `is_null()` for all JSON
  12385. types.,is_null}
  12386. @since version 1.0.0
  12387. */
  12388. constexpr bool is_null() const noexcept
  12389. {
  12390. return (m_type == value_t::null);
  12391. }
  12392. /*!
  12393. @brief return whether value is a boolean
  12394. This function returns true if and only if the JSON value is a boolean.
  12395. @return `true` if type is boolean, `false` otherwise.
  12396. @complexity Constant.
  12397. @exceptionsafety No-throw guarantee: this member function never throws
  12398. exceptions.
  12399. @liveexample{The following code exemplifies `is_boolean()` for all JSON
  12400. types.,is_boolean}
  12401. @since version 1.0.0
  12402. */
  12403. constexpr bool is_boolean() const noexcept
  12404. {
  12405. return (m_type == value_t::boolean);
  12406. }
  12407. /*!
  12408. @brief return whether value is a number
  12409. This function returns true if and only if the JSON value is a number. This
  12410. includes both integer (signed and unsigned) and floating-point values.
  12411. @return `true` if type is number (regardless whether integer, unsigned
  12412. integer or floating-type), `false` otherwise.
  12413. @complexity Constant.
  12414. @exceptionsafety No-throw guarantee: this member function never throws
  12415. exceptions.
  12416. @liveexample{The following code exemplifies `is_number()` for all JSON
  12417. types.,is_number}
  12418. @sa @ref is_number_integer() -- check if value is an integer or unsigned
  12419. integer number
  12420. @sa @ref is_number_unsigned() -- check if value is an unsigned integer
  12421. number
  12422. @sa @ref is_number_float() -- check if value is a floating-point number
  12423. @since version 1.0.0
  12424. */
  12425. constexpr bool is_number() const noexcept
  12426. {
  12427. return is_number_integer() or is_number_float();
  12428. }
  12429. /*!
  12430. @brief return whether value is an integer number
  12431. This function returns true if and only if the JSON value is a signed or
  12432. unsigned integer number. This excludes floating-point values.
  12433. @return `true` if type is an integer or unsigned integer number, `false`
  12434. otherwise.
  12435. @complexity Constant.
  12436. @exceptionsafety No-throw guarantee: this member function never throws
  12437. exceptions.
  12438. @liveexample{The following code exemplifies `is_number_integer()` for all
  12439. JSON types.,is_number_integer}
  12440. @sa @ref is_number() -- check if value is a number
  12441. @sa @ref is_number_unsigned() -- check if value is an unsigned integer
  12442. number
  12443. @sa @ref is_number_float() -- check if value is a floating-point number
  12444. @since version 1.0.0
  12445. */
  12446. constexpr bool is_number_integer() const noexcept
  12447. {
  12448. return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
  12449. }
  12450. /*!
  12451. @brief return whether value is an unsigned integer number
  12452. This function returns true if and only if the JSON value is an unsigned
  12453. integer number. This excludes floating-point and signed integer values.
  12454. @return `true` if type is an unsigned integer number, `false` otherwise.
  12455. @complexity Constant.
  12456. @exceptionsafety No-throw guarantee: this member function never throws
  12457. exceptions.
  12458. @liveexample{The following code exemplifies `is_number_unsigned()` for all
  12459. JSON types.,is_number_unsigned}
  12460. @sa @ref is_number() -- check if value is a number
  12461. @sa @ref is_number_integer() -- check if value is an integer or unsigned
  12462. integer number
  12463. @sa @ref is_number_float() -- check if value is a floating-point number
  12464. @since version 2.0.0
  12465. */
  12466. constexpr bool is_number_unsigned() const noexcept
  12467. {
  12468. return (m_type == value_t::number_unsigned);
  12469. }
  12470. /*!
  12471. @brief return whether value is a floating-point number
  12472. This function returns true if and only if the JSON value is a
  12473. floating-point number. This excludes signed and unsigned integer values.
  12474. @return `true` if type is a floating-point number, `false` otherwise.
  12475. @complexity Constant.
  12476. @exceptionsafety No-throw guarantee: this member function never throws
  12477. exceptions.
  12478. @liveexample{The following code exemplifies `is_number_float()` for all
  12479. JSON types.,is_number_float}
  12480. @sa @ref is_number() -- check if value is number
  12481. @sa @ref is_number_integer() -- check if value is an integer number
  12482. @sa @ref is_number_unsigned() -- check if value is an unsigned integer
  12483. number
  12484. @since version 1.0.0
  12485. */
  12486. constexpr bool is_number_float() const noexcept
  12487. {
  12488. return (m_type == value_t::number_float);
  12489. }
  12490. /*!
  12491. @brief return whether value is an object
  12492. This function returns true if and only if the JSON value is an object.
  12493. @return `true` if type is object, `false` otherwise.
  12494. @complexity Constant.
  12495. @exceptionsafety No-throw guarantee: this member function never throws
  12496. exceptions.
  12497. @liveexample{The following code exemplifies `is_object()` for all JSON
  12498. types.,is_object}
  12499. @since version 1.0.0
  12500. */
  12501. constexpr bool is_object() const noexcept
  12502. {
  12503. return (m_type == value_t::object);
  12504. }
  12505. /*!
  12506. @brief return whether value is an array
  12507. This function returns true if and only if the JSON value is an array.
  12508. @return `true` if type is array, `false` otherwise.
  12509. @complexity Constant.
  12510. @exceptionsafety No-throw guarantee: this member function never throws
  12511. exceptions.
  12512. @liveexample{The following code exemplifies `is_array()` for all JSON
  12513. types.,is_array}
  12514. @since version 1.0.0
  12515. */
  12516. constexpr bool is_array() const noexcept
  12517. {
  12518. return (m_type == value_t::array);
  12519. }
  12520. /*!
  12521. @brief return whether value is a string
  12522. This function returns true if and only if the JSON value is a string.
  12523. @return `true` if type is string, `false` otherwise.
  12524. @complexity Constant.
  12525. @exceptionsafety No-throw guarantee: this member function never throws
  12526. exceptions.
  12527. @liveexample{The following code exemplifies `is_string()` for all JSON
  12528. types.,is_string}
  12529. @since version 1.0.0
  12530. */
  12531. constexpr bool is_string() const noexcept
  12532. {
  12533. return (m_type == value_t::string);
  12534. }
  12535. /*!
  12536. @brief return whether value is discarded
  12537. This function returns true if and only if the JSON value was discarded
  12538. during parsing with a callback function (see @ref parser_callback_t).
  12539. @note This function will always be `false` for JSON values after parsing.
  12540. That is, discarded values can only occur during parsing, but will be
  12541. removed when inside a structured value or replaced by null in other cases.
  12542. @return `true` if type is discarded, `false` otherwise.
  12543. @complexity Constant.
  12544. @exceptionsafety No-throw guarantee: this member function never throws
  12545. exceptions.
  12546. @liveexample{The following code exemplifies `is_discarded()` for all JSON
  12547. types.,is_discarded}
  12548. @since version 1.0.0
  12549. */
  12550. constexpr bool is_discarded() const noexcept
  12551. {
  12552. return (m_type == value_t::discarded);
  12553. }
  12554. /*!
  12555. @brief return the type of the JSON value (implicit)
  12556. Implicitly return the type of the JSON value as a value from the @ref
  12557. value_t enumeration.
  12558. @return the type of the JSON value
  12559. @complexity Constant.
  12560. @exceptionsafety No-throw guarantee: this member function never throws
  12561. exceptions.
  12562. @liveexample{The following code exemplifies the @ref value_t operator for
  12563. all JSON types.,operator__value_t}
  12564. @sa @ref type() -- return the type of the JSON value (explicit)
  12565. @sa @ref type_name() -- return the type as string
  12566. @since version 1.0.0
  12567. */
  12568. constexpr operator value_t() const noexcept
  12569. {
  12570. return m_type;
  12571. }
  12572. /// @}
  12573. private:
  12574. //////////////////
  12575. // value access //
  12576. //////////////////
  12577. /// get a boolean (explicit)
  12578. boolean_t get_impl(boolean_t* /*unused*/) const
  12579. {
  12580. if (JSON_LIKELY(is_boolean()))
  12581. {
  12582. return m_value.boolean;
  12583. }
  12584. JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
  12585. }
  12586. /// get a pointer to the value (object)
  12587. object_t* get_impl_ptr(object_t* /*unused*/) noexcept
  12588. {
  12589. return is_object() ? m_value.object : nullptr;
  12590. }
  12591. /// get a pointer to the value (object)
  12592. constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
  12593. {
  12594. return is_object() ? m_value.object : nullptr;
  12595. }
  12596. /// get a pointer to the value (array)
  12597. array_t* get_impl_ptr(array_t* /*unused*/) noexcept
  12598. {
  12599. return is_array() ? m_value.array : nullptr;
  12600. }
  12601. /// get a pointer to the value (array)
  12602. constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
  12603. {
  12604. return is_array() ? m_value.array : nullptr;
  12605. }
  12606. /// get a pointer to the value (string)
  12607. string_t* get_impl_ptr(string_t* /*unused*/) noexcept
  12608. {
  12609. return is_string() ? m_value.string : nullptr;
  12610. }
  12611. /// get a pointer to the value (string)
  12612. constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
  12613. {
  12614. return is_string() ? m_value.string : nullptr;
  12615. }
  12616. /// get a pointer to the value (boolean)
  12617. boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
  12618. {
  12619. return is_boolean() ? &m_value.boolean : nullptr;
  12620. }
  12621. /// get a pointer to the value (boolean)
  12622. constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
  12623. {
  12624. return is_boolean() ? &m_value.boolean : nullptr;
  12625. }
  12626. /// get a pointer to the value (integer number)
  12627. number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
  12628. {
  12629. return is_number_integer() ? &m_value.number_integer : nullptr;
  12630. }
  12631. /// get a pointer to the value (integer number)
  12632. constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
  12633. {
  12634. return is_number_integer() ? &m_value.number_integer : nullptr;
  12635. }
  12636. /// get a pointer to the value (unsigned number)
  12637. number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
  12638. {
  12639. return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
  12640. }
  12641. /// get a pointer to the value (unsigned number)
  12642. constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
  12643. {
  12644. return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
  12645. }
  12646. /// get a pointer to the value (floating-point number)
  12647. number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
  12648. {
  12649. return is_number_float() ? &m_value.number_float : nullptr;
  12650. }
  12651. /// get a pointer to the value (floating-point number)
  12652. constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
  12653. {
  12654. return is_number_float() ? &m_value.number_float : nullptr;
  12655. }
  12656. /*!
  12657. @brief helper function to implement get_ref()
  12658. This function helps to implement get_ref() without code duplication for
  12659. const and non-const overloads
  12660. @tparam ThisType will be deduced as `basic_json` or `const basic_json`
  12661. @throw type_error.303 if ReferenceType does not match underlying value
  12662. type of the current JSON
  12663. */
  12664. template<typename ReferenceType, typename ThisType>
  12665. static ReferenceType get_ref_impl(ThisType& obj)
  12666. {
  12667. // delegate the call to get_ptr<>()
  12668. auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
  12669. if (JSON_LIKELY(ptr != nullptr))
  12670. {
  12671. return *ptr;
  12672. }
  12673. JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
  12674. }
  12675. public:
  12676. /// @name value access
  12677. /// Direct access to the stored value of a JSON value.
  12678. /// @{
  12679. /*!
  12680. @brief get special-case overload
  12681. This overloads avoids a lot of template boilerplate, it can be seen as the
  12682. identity method
  12683. @tparam BasicJsonType == @ref basic_json
  12684. @return a copy of *this
  12685. @complexity Constant.
  12686. @since version 2.1.0
  12687. */
  12688. template<typename BasicJsonType, detail::enable_if_t<
  12689. std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
  12690. int> = 0>
  12691. basic_json get() const
  12692. {
  12693. return *this;
  12694. }
  12695. /*!
  12696. @brief get special-case overload
  12697. This overloads converts the current @ref basic_json in a different
  12698. @ref basic_json type
  12699. @tparam BasicJsonType == @ref basic_json
  12700. @return a copy of *this, converted into @tparam BasicJsonType
  12701. @complexity Depending on the implementation of the called `from_json()`
  12702. method.
  12703. @since version 3.2.0
  12704. */
  12705. template<typename BasicJsonType, detail::enable_if_t<
  12706. not std::is_same<BasicJsonType, basic_json>::value and
  12707. detail::is_basic_json<BasicJsonType>::value, int> = 0>
  12708. BasicJsonType get() const
  12709. {
  12710. return *this;
  12711. }
  12712. /*!
  12713. @brief get a value (explicit)
  12714. Explicit type conversion between the JSON value and a compatible value
  12715. which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
  12716. and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
  12717. The value is converted by calling the @ref json_serializer<ValueType>
  12718. `from_json()` method.
  12719. The function is equivalent to executing
  12720. @code {.cpp}
  12721. ValueType ret;
  12722. JSONSerializer<ValueType>::from_json(*this, ret);
  12723. return ret;
  12724. @endcode
  12725. This overloads is chosen if:
  12726. - @a ValueType is not @ref basic_json,
  12727. - @ref json_serializer<ValueType> has a `from_json()` method of the form
  12728. `void from_json(const basic_json&, ValueType&)`, and
  12729. - @ref json_serializer<ValueType> does not have a `from_json()` method of
  12730. the form `ValueType from_json(const basic_json&)`
  12731. @tparam ValueTypeCV the provided value type
  12732. @tparam ValueType the returned value type
  12733. @return copy of the JSON value, converted to @a ValueType
  12734. @throw what @ref json_serializer<ValueType> `from_json()` method throws
  12735. @liveexample{The example below shows several conversions from JSON values
  12736. to other types. There a few things to note: (1) Floating-point numbers can
  12737. be converted to integers\, (2) A JSON array can be converted to a standard
  12738. `std::vector<short>`\, (3) A JSON object can be converted to C++
  12739. associative containers such as `std::unordered_map<std::string\,
  12740. json>`.,get__ValueType_const}
  12741. @since version 2.1.0
  12742. */
  12743. template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
  12744. detail::enable_if_t <
  12745. not detail::is_basic_json<ValueType>::value and
  12746. detail::has_from_json<basic_json_t, ValueType>::value and
  12747. not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
  12748. int> = 0>
  12749. ValueType get() const noexcept(noexcept(
  12750. JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
  12751. {
  12752. // we cannot static_assert on ValueTypeCV being non-const, because
  12753. // there is support for get<const basic_json_t>(), which is why we
  12754. // still need the uncvref
  12755. static_assert(not std::is_reference<ValueTypeCV>::value,
  12756. "get() cannot be used with reference types, you might want to use get_ref()");
  12757. static_assert(std::is_default_constructible<ValueType>::value,
  12758. "types must be DefaultConstructible when used with get()");
  12759. ValueType ret;
  12760. JSONSerializer<ValueType>::from_json(*this, ret);
  12761. return ret;
  12762. }
  12763. /*!
  12764. @brief get a value (explicit); special case
  12765. Explicit type conversion between the JSON value and a compatible value
  12766. which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
  12767. and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
  12768. The value is converted by calling the @ref json_serializer<ValueType>
  12769. `from_json()` method.
  12770. The function is equivalent to executing
  12771. @code {.cpp}
  12772. return JSONSerializer<ValueTypeCV>::from_json(*this);
  12773. @endcode
  12774. This overloads is chosen if:
  12775. - @a ValueType is not @ref basic_json and
  12776. - @ref json_serializer<ValueType> has a `from_json()` method of the form
  12777. `ValueType from_json(const basic_json&)`
  12778. @note If @ref json_serializer<ValueType> has both overloads of
  12779. `from_json()`, this one is chosen.
  12780. @tparam ValueTypeCV the provided value type
  12781. @tparam ValueType the returned value type
  12782. @return copy of the JSON value, converted to @a ValueType
  12783. @throw what @ref json_serializer<ValueType> `from_json()` method throws
  12784. @since version 2.1.0
  12785. */
  12786. template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
  12787. detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
  12788. detail::has_non_default_from_json<basic_json_t, ValueType>::value,
  12789. int> = 0>
  12790. ValueType get() const noexcept(noexcept(
  12791. JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
  12792. {
  12793. static_assert(not std::is_reference<ValueTypeCV>::value,
  12794. "get() cannot be used with reference types, you might want to use get_ref()");
  12795. return JSONSerializer<ValueTypeCV>::from_json(*this);
  12796. }
  12797. /*!
  12798. @brief get a value (explicit)
  12799. Explicit type conversion between the JSON value and a compatible value.
  12800. The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
  12801. `from_json()` method.
  12802. The function is equivalent to executing
  12803. @code {.cpp}
  12804. ValueType v;
  12805. JSONSerializer<ValueType>::from_json(*this, v);
  12806. @endcode
  12807. This overloads is chosen if:
  12808. - @a ValueType is not @ref basic_json,
  12809. - @ref json_serializer<ValueType> has a `from_json()` method of the form
  12810. `void from_json(const basic_json&, ValueType&)`, and
  12811. @tparam ValueType the input parameter type.
  12812. @return the input parameter, allowing chaining calls.
  12813. @throw what @ref json_serializer<ValueType> `from_json()` method throws
  12814. @liveexample{The example below shows several conversions from JSON values
  12815. to other types. There a few things to note: (1) Floating-point numbers can
  12816. be converted to integers\, (2) A JSON array can be converted to a standard
  12817. `std::vector<short>`\, (3) A JSON object can be converted to C++
  12818. associative containers such as `std::unordered_map<std::string\,
  12819. json>`.,get_to}
  12820. @since version 3.3.0
  12821. */
  12822. template<typename ValueType,
  12823. detail::enable_if_t <
  12824. not detail::is_basic_json<ValueType>::value and
  12825. detail::has_from_json<basic_json_t, ValueType>::value,
  12826. int> = 0>
  12827. ValueType & get_to(ValueType& v) const noexcept(noexcept(
  12828. JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
  12829. {
  12830. JSONSerializer<ValueType>::from_json(*this, v);
  12831. return v;
  12832. }
  12833. /*!
  12834. @brief get a pointer value (implicit)
  12835. Implicit pointer access to the internally stored JSON value. No copies are
  12836. made.
  12837. @warning Writing data to the pointee of the result yields an undefined
  12838. state.
  12839. @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
  12840. object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
  12841. @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
  12842. assertion.
  12843. @return pointer to the internally stored JSON value if the requested
  12844. pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
  12845. @complexity Constant.
  12846. @liveexample{The example below shows how pointers to internal values of a
  12847. JSON value can be requested. Note that no type conversions are made and a
  12848. `nullptr` is returned if the value and the requested pointer type does not
  12849. match.,get_ptr}
  12850. @since version 1.0.0
  12851. */
  12852. template<typename PointerType, typename std::enable_if<
  12853. std::is_pointer<PointerType>::value, int>::type = 0>
  12854. auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
  12855. {
  12856. // delegate the call to get_impl_ptr<>()
  12857. return get_impl_ptr(static_cast<PointerType>(nullptr));
  12858. }
  12859. /*!
  12860. @brief get a pointer value (implicit)
  12861. @copydoc get_ptr()
  12862. */
  12863. template<typename PointerType, typename std::enable_if<
  12864. std::is_pointer<PointerType>::value and
  12865. std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
  12866. constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
  12867. {
  12868. // delegate the call to get_impl_ptr<>() const
  12869. return get_impl_ptr(static_cast<PointerType>(nullptr));
  12870. }
  12871. /*!
  12872. @brief get a pointer value (explicit)
  12873. Explicit pointer access to the internally stored JSON value. No copies are
  12874. made.
  12875. @warning The pointer becomes invalid if the underlying JSON object
  12876. changes.
  12877. @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
  12878. object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
  12879. @ref number_unsigned_t, or @ref number_float_t.
  12880. @return pointer to the internally stored JSON value if the requested
  12881. pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
  12882. @complexity Constant.
  12883. @liveexample{The example below shows how pointers to internal values of a
  12884. JSON value can be requested. Note that no type conversions are made and a
  12885. `nullptr` is returned if the value and the requested pointer type does not
  12886. match.,get__PointerType}
  12887. @sa @ref get_ptr() for explicit pointer-member access
  12888. @since version 1.0.0
  12889. */
  12890. template<typename PointerType, typename std::enable_if<
  12891. std::is_pointer<PointerType>::value, int>::type = 0>
  12892. auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
  12893. {
  12894. // delegate the call to get_ptr
  12895. return get_ptr<PointerType>();
  12896. }
  12897. /*!
  12898. @brief get a pointer value (explicit)
  12899. @copydoc get()
  12900. */
  12901. template<typename PointerType, typename std::enable_if<
  12902. std::is_pointer<PointerType>::value, int>::type = 0>
  12903. constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
  12904. {
  12905. // delegate the call to get_ptr
  12906. return get_ptr<PointerType>();
  12907. }
  12908. /*!
  12909. @brief get a reference value (implicit)
  12910. Implicit reference access to the internally stored JSON value. No copies
  12911. are made.
  12912. @warning Writing data to the referee of the result yields an undefined
  12913. state.
  12914. @tparam ReferenceType reference type; must be a reference to @ref array_t,
  12915. @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
  12916. @ref number_float_t. Enforced by static assertion.
  12917. @return reference to the internally stored JSON value if the requested
  12918. reference type @a ReferenceType fits to the JSON value; throws
  12919. type_error.303 otherwise
  12920. @throw type_error.303 in case passed type @a ReferenceType is incompatible
  12921. with the stored JSON value; see example below
  12922. @complexity Constant.
  12923. @liveexample{The example shows several calls to `get_ref()`.,get_ref}
  12924. @since version 1.1.0
  12925. */
  12926. template<typename ReferenceType, typename std::enable_if<
  12927. std::is_reference<ReferenceType>::value, int>::type = 0>
  12928. ReferenceType get_ref()
  12929. {
  12930. // delegate call to get_ref_impl
  12931. return get_ref_impl<ReferenceType>(*this);
  12932. }
  12933. /*!
  12934. @brief get a reference value (implicit)
  12935. @copydoc get_ref()
  12936. */
  12937. template<typename ReferenceType, typename std::enable_if<
  12938. std::is_reference<ReferenceType>::value and
  12939. std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
  12940. ReferenceType get_ref() const
  12941. {
  12942. // delegate call to get_ref_impl
  12943. return get_ref_impl<ReferenceType>(*this);
  12944. }
  12945. /*!
  12946. @brief get a value (implicit)
  12947. Implicit type conversion between the JSON value and a compatible value.
  12948. The call is realized by calling @ref get() const.
  12949. @tparam ValueType non-pointer type compatible to the JSON value, for
  12950. instance `int` for JSON integer numbers, `bool` for JSON booleans, or
  12951. `std::vector` types for JSON arrays. The character type of @ref string_t
  12952. as well as an initializer list of this type is excluded to avoid
  12953. ambiguities as these types implicitly convert to `std::string`.
  12954. @return copy of the JSON value, converted to type @a ValueType
  12955. @throw type_error.302 in case passed type @a ValueType is incompatible
  12956. to the JSON value type (e.g., the JSON value is of type boolean, but a
  12957. string is requested); see example below
  12958. @complexity Linear in the size of the JSON value.
  12959. @liveexample{The example below shows several conversions from JSON values
  12960. to other types. There a few things to note: (1) Floating-point numbers can
  12961. be converted to integers\, (2) A JSON array can be converted to a standard
  12962. `std::vector<short>`\, (3) A JSON object can be converted to C++
  12963. associative containers such as `std::unordered_map<std::string\,
  12964. json>`.,operator__ValueType}
  12965. @since version 1.0.0
  12966. */
  12967. template < typename ValueType, typename std::enable_if <
  12968. not std::is_pointer<ValueType>::value and
  12969. not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
  12970. not std::is_same<ValueType, typename string_t::value_type>::value and
  12971. not detail::is_basic_json<ValueType>::value
  12972. #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
  12973. and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
  12974. #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
  12975. and not std::is_same<ValueType, typename std::string_view>::value
  12976. #endif
  12977. #endif
  12978. and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
  12979. , int >::type = 0 >
  12980. operator ValueType() const
  12981. {
  12982. // delegate the call to get<>() const
  12983. return get<ValueType>();
  12984. }
  12985. /// @}
  12986. ////////////////////
  12987. // element access //
  12988. ////////////////////
  12989. /// @name element access
  12990. /// Access to the JSON value.
  12991. /// @{
  12992. /*!
  12993. @brief access specified array element with bounds checking
  12994. Returns a reference to the element at specified location @a idx, with
  12995. bounds checking.
  12996. @param[in] idx index of the element to access
  12997. @return reference to the element at index @a idx
  12998. @throw type_error.304 if the JSON value is not an array; in this case,
  12999. calling `at` with an index makes no sense. See example below.
  13000. @throw out_of_range.401 if the index @a idx is out of range of the array;
  13001. that is, `idx >= size()`. See example below.
  13002. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  13003. changes in the JSON value.
  13004. @complexity Constant.
  13005. @since version 1.0.0
  13006. @liveexample{The example below shows how array elements can be read and
  13007. written using `at()`. It also demonstrates the different exceptions that
  13008. can be thrown.,at__size_type}
  13009. */
  13010. reference at(size_type idx)
  13011. {
  13012. // at only works for arrays
  13013. if (JSON_LIKELY(is_array()))
  13014. {
  13015. JSON_TRY
  13016. {
  13017. return m_value.array->at(idx);
  13018. }
  13019. JSON_CATCH (std::out_of_range&)
  13020. {
  13021. // create better exception explanation
  13022. JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
  13023. }
  13024. }
  13025. else
  13026. {
  13027. JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
  13028. }
  13029. }
  13030. /*!
  13031. @brief access specified array element with bounds checking
  13032. Returns a const reference to the element at specified location @a idx,
  13033. with bounds checking.
  13034. @param[in] idx index of the element to access
  13035. @return const reference to the element at index @a idx
  13036. @throw type_error.304 if the JSON value is not an array; in this case,
  13037. calling `at` with an index makes no sense. See example below.
  13038. @throw out_of_range.401 if the index @a idx is out of range of the array;
  13039. that is, `idx >= size()`. See example below.
  13040. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  13041. changes in the JSON value.
  13042. @complexity Constant.
  13043. @since version 1.0.0
  13044. @liveexample{The example below shows how array elements can be read using
  13045. `at()`. It also demonstrates the different exceptions that can be thrown.,
  13046. at__size_type_const}
  13047. */
  13048. const_reference at(size_type idx) const
  13049. {
  13050. // at only works for arrays
  13051. if (JSON_LIKELY(is_array()))
  13052. {
  13053. JSON_TRY
  13054. {
  13055. return m_value.array->at(idx);
  13056. }
  13057. JSON_CATCH (std::out_of_range&)
  13058. {
  13059. // create better exception explanation
  13060. JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
  13061. }
  13062. }
  13063. else
  13064. {
  13065. JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
  13066. }
  13067. }
  13068. /*!
  13069. @brief access specified object element with bounds checking
  13070. Returns a reference to the element at with specified key @a key, with
  13071. bounds checking.
  13072. @param[in] key key of the element to access
  13073. @return reference to the element at key @a key
  13074. @throw type_error.304 if the JSON value is not an object; in this case,
  13075. calling `at` with a key makes no sense. See example below.
  13076. @throw out_of_range.403 if the key @a key is is not stored in the object;
  13077. that is, `find(key) == end()`. See example below.
  13078. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  13079. changes in the JSON value.
  13080. @complexity Logarithmic in the size of the container.
  13081. @sa @ref operator[](const typename object_t::key_type&) for unchecked
  13082. access by reference
  13083. @sa @ref value() for access by value with a default value
  13084. @since version 1.0.0
  13085. @liveexample{The example below shows how object elements can be read and
  13086. written using `at()`. It also demonstrates the different exceptions that
  13087. can be thrown.,at__object_t_key_type}
  13088. */
  13089. reference at(const typename object_t::key_type& key)
  13090. {
  13091. // at only works for objects
  13092. if (JSON_LIKELY(is_object()))
  13093. {
  13094. JSON_TRY
  13095. {
  13096. return m_value.object->at(key);
  13097. }
  13098. JSON_CATCH (std::out_of_range&)
  13099. {
  13100. // create better exception explanation
  13101. JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
  13102. }
  13103. }
  13104. else
  13105. {
  13106. JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
  13107. }
  13108. }
  13109. /*!
  13110. @brief access specified object element with bounds checking
  13111. Returns a const reference to the element at with specified key @a key,
  13112. with bounds checking.
  13113. @param[in] key key of the element to access
  13114. @return const reference to the element at key @a key
  13115. @throw type_error.304 if the JSON value is not an object; in this case,
  13116. calling `at` with a key makes no sense. See example below.
  13117. @throw out_of_range.403 if the key @a key is is not stored in the object;
  13118. that is, `find(key) == end()`. See example below.
  13119. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  13120. changes in the JSON value.
  13121. @complexity Logarithmic in the size of the container.
  13122. @sa @ref operator[](const typename object_t::key_type&) for unchecked
  13123. access by reference
  13124. @sa @ref value() for access by value with a default value
  13125. @since version 1.0.0
  13126. @liveexample{The example below shows how object elements can be read using
  13127. `at()`. It also demonstrates the different exceptions that can be thrown.,
  13128. at__object_t_key_type_const}
  13129. */
  13130. const_reference at(const typename object_t::key_type& key) const
  13131. {
  13132. // at only works for objects
  13133. if (JSON_LIKELY(is_object()))
  13134. {
  13135. JSON_TRY
  13136. {
  13137. return m_value.object->at(key);
  13138. }
  13139. JSON_CATCH (std::out_of_range&)
  13140. {
  13141. // create better exception explanation
  13142. JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
  13143. }
  13144. }
  13145. else
  13146. {
  13147. JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
  13148. }
  13149. }
  13150. /*!
  13151. @brief access specified array element
  13152. Returns a reference to the element at specified location @a idx.
  13153. @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
  13154. then the array is silently filled up with `null` values to make `idx` a
  13155. valid reference to the last stored element.
  13156. @param[in] idx index of the element to access
  13157. @return reference to the element at index @a idx
  13158. @throw type_error.305 if the JSON value is not an array or null; in that
  13159. cases, using the [] operator with an index makes no sense.
  13160. @complexity Constant if @a idx is in the range of the array. Otherwise
  13161. linear in `idx - size()`.
  13162. @liveexample{The example below shows how array elements can be read and
  13163. written using `[]` operator. Note the addition of `null`
  13164. values.,operatorarray__size_type}
  13165. @since version 1.0.0
  13166. */
  13167. reference operator[](size_type idx)
  13168. {
  13169. // implicitly convert null value to an empty array
  13170. if (is_null())
  13171. {
  13172. m_type = value_t::array;
  13173. m_value.array = create<array_t>();
  13174. assert_invariant();
  13175. }
  13176. // operator[] only works for arrays
  13177. if (JSON_LIKELY(is_array()))
  13178. {
  13179. // fill up array with null values if given idx is outside range
  13180. if (idx >= m_value.array->size())
  13181. {
  13182. m_value.array->insert(m_value.array->end(),
  13183. idx - m_value.array->size() + 1,
  13184. basic_json());
  13185. }
  13186. return m_value.array->operator[](idx);
  13187. }
  13188. JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
  13189. }
  13190. /*!
  13191. @brief access specified array element
  13192. Returns a const reference to the element at specified location @a idx.
  13193. @param[in] idx index of the element to access
  13194. @return const reference to the element at index @a idx
  13195. @throw type_error.305 if the JSON value is not an array; in that case,
  13196. using the [] operator with an index makes no sense.
  13197. @complexity Constant.
  13198. @liveexample{The example below shows how array elements can be read using
  13199. the `[]` operator.,operatorarray__size_type_const}
  13200. @since version 1.0.0
  13201. */
  13202. const_reference operator[](size_type idx) const
  13203. {
  13204. // const operator[] only works for arrays
  13205. if (JSON_LIKELY(is_array()))
  13206. {
  13207. return m_value.array->operator[](idx);
  13208. }
  13209. JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
  13210. }
  13211. /*!
  13212. @brief access specified object element
  13213. Returns a reference to the element at with specified key @a key.
  13214. @note If @a key is not found in the object, then it is silently added to
  13215. the object and filled with a `null` value to make `key` a valid reference.
  13216. In case the value was `null` before, it is converted to an object.
  13217. @param[in] key key of the element to access
  13218. @return reference to the element at key @a key
  13219. @throw type_error.305 if the JSON value is not an object or null; in that
  13220. cases, using the [] operator with a key makes no sense.
  13221. @complexity Logarithmic in the size of the container.
  13222. @liveexample{The example below shows how object elements can be read and
  13223. written using the `[]` operator.,operatorarray__key_type}
  13224. @sa @ref at(const typename object_t::key_type&) for access by reference
  13225. with range checking
  13226. @sa @ref value() for access by value with a default value
  13227. @since version 1.0.0
  13228. */
  13229. reference operator[](const typename object_t::key_type& key)
  13230. {
  13231. // implicitly convert null value to an empty object
  13232. if (is_null())
  13233. {
  13234. m_type = value_t::object;
  13235. m_value.object = create<object_t>();
  13236. assert_invariant();
  13237. }
  13238. // operator[] only works for objects
  13239. if (JSON_LIKELY(is_object()))
  13240. {
  13241. return m_value.object->operator[](key);
  13242. }
  13243. JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
  13244. }
  13245. /*!
  13246. @brief read-only access specified object element
  13247. Returns a const reference to the element at with specified key @a key. No
  13248. bounds checking is performed.
  13249. @warning If the element with key @a key does not exist, the behavior is
  13250. undefined.
  13251. @param[in] key key of the element to access
  13252. @return const reference to the element at key @a key
  13253. @pre The element with key @a key must exist. **This precondition is
  13254. enforced with an assertion.**
  13255. @throw type_error.305 if the JSON value is not an object; in that case,
  13256. using the [] operator with a key makes no sense.
  13257. @complexity Logarithmic in the size of the container.
  13258. @liveexample{The example below shows how object elements can be read using
  13259. the `[]` operator.,operatorarray__key_type_const}
  13260. @sa @ref at(const typename object_t::key_type&) for access by reference
  13261. with range checking
  13262. @sa @ref value() for access by value with a default value
  13263. @since version 1.0.0
  13264. */
  13265. const_reference operator[](const typename object_t::key_type& key) const
  13266. {
  13267. // const operator[] only works for objects
  13268. if (JSON_LIKELY(is_object()))
  13269. {
  13270. assert(m_value.object->find(key) != m_value.object->end());
  13271. return m_value.object->find(key)->second;
  13272. }
  13273. JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
  13274. }
  13275. /*!
  13276. @brief access specified object element
  13277. Returns a reference to the element at with specified key @a key.
  13278. @note If @a key is not found in the object, then it is silently added to
  13279. the object and filled with a `null` value to make `key` a valid reference.
  13280. In case the value was `null` before, it is converted to an object.
  13281. @param[in] key key of the element to access
  13282. @return reference to the element at key @a key
  13283. @throw type_error.305 if the JSON value is not an object or null; in that
  13284. cases, using the [] operator with a key makes no sense.
  13285. @complexity Logarithmic in the size of the container.
  13286. @liveexample{The example below shows how object elements can be read and
  13287. written using the `[]` operator.,operatorarray__key_type}
  13288. @sa @ref at(const typename object_t::key_type&) for access by reference
  13289. with range checking
  13290. @sa @ref value() for access by value with a default value
  13291. @since version 1.1.0
  13292. */
  13293. template<typename T>
  13294. reference operator[](T* key)
  13295. {
  13296. // implicitly convert null to object
  13297. if (is_null())
  13298. {
  13299. m_type = value_t::object;
  13300. m_value = value_t::object;
  13301. assert_invariant();
  13302. }
  13303. // at only works for objects
  13304. if (JSON_LIKELY(is_object()))
  13305. {
  13306. return m_value.object->operator[](key);
  13307. }
  13308. JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
  13309. }
  13310. /*!
  13311. @brief read-only access specified object element
  13312. Returns a const reference to the element at with specified key @a key. No
  13313. bounds checking is performed.
  13314. @warning If the element with key @a key does not exist, the behavior is
  13315. undefined.
  13316. @param[in] key key of the element to access
  13317. @return const reference to the element at key @a key
  13318. @pre The element with key @a key must exist. **This precondition is
  13319. enforced with an assertion.**
  13320. @throw type_error.305 if the JSON value is not an object; in that case,
  13321. using the [] operator with a key makes no sense.
  13322. @complexity Logarithmic in the size of the container.
  13323. @liveexample{The example below shows how object elements can be read using
  13324. the `[]` operator.,operatorarray__key_type_const}
  13325. @sa @ref at(const typename object_t::key_type&) for access by reference
  13326. with range checking
  13327. @sa @ref value() for access by value with a default value
  13328. @since version 1.1.0
  13329. */
  13330. template<typename T>
  13331. const_reference operator[](T* key) const
  13332. {
  13333. // at only works for objects
  13334. if (JSON_LIKELY(is_object()))
  13335. {
  13336. assert(m_value.object->find(key) != m_value.object->end());
  13337. return m_value.object->find(key)->second;
  13338. }
  13339. JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
  13340. }
  13341. /*!
  13342. @brief access specified object element with default value
  13343. Returns either a copy of an object's element at the specified key @a key
  13344. or a given default value if no element with key @a key exists.
  13345. The function is basically equivalent to executing
  13346. @code {.cpp}
  13347. try {
  13348. return at(key);
  13349. } catch(out_of_range) {
  13350. return default_value;
  13351. }
  13352. @endcode
  13353. @note Unlike @ref at(const typename object_t::key_type&), this function
  13354. does not throw if the given key @a key was not found.
  13355. @note Unlike @ref operator[](const typename object_t::key_type& key), this
  13356. function does not implicitly add an element to the position defined by @a
  13357. key. This function is furthermore also applicable to const objects.
  13358. @param[in] key key of the element to access
  13359. @param[in] default_value the value to return if @a key is not found
  13360. @tparam ValueType type compatible to JSON values, for instance `int` for
  13361. JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
  13362. JSON arrays. Note the type of the expected value at @a key and the default
  13363. value @a default_value must be compatible.
  13364. @return copy of the element at key @a key or @a default_value if @a key
  13365. is not found
  13366. @throw type_error.306 if the JSON value is not an object; in that case,
  13367. using `value()` with a key makes no sense.
  13368. @complexity Logarithmic in the size of the container.
  13369. @liveexample{The example below shows how object elements can be queried
  13370. with a default value.,basic_json__value}
  13371. @sa @ref at(const typename object_t::key_type&) for access by reference
  13372. with range checking
  13373. @sa @ref operator[](const typename object_t::key_type&) for unchecked
  13374. access by reference
  13375. @since version 1.0.0
  13376. */
  13377. template<class ValueType, typename std::enable_if<
  13378. std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
  13379. ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
  13380. {
  13381. // at only works for objects
  13382. if (JSON_LIKELY(is_object()))
  13383. {
  13384. // if key is found, return value and given default value otherwise
  13385. const auto it = find(key);
  13386. if (it != end())
  13387. {
  13388. return *it;
  13389. }
  13390. return default_value;
  13391. }
  13392. JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
  13393. }
  13394. /*!
  13395. @brief overload for a default value of type const char*
  13396. @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
  13397. */
  13398. string_t value(const typename object_t::key_type& key, const char* default_value) const
  13399. {
  13400. return value(key, string_t(default_value));
  13401. }
  13402. /*!
  13403. @brief access specified object element via JSON Pointer with default value
  13404. Returns either a copy of an object's element at the specified key @a key
  13405. or a given default value if no element with key @a key exists.
  13406. The function is basically equivalent to executing
  13407. @code {.cpp}
  13408. try {
  13409. return at(ptr);
  13410. } catch(out_of_range) {
  13411. return default_value;
  13412. }
  13413. @endcode
  13414. @note Unlike @ref at(const json_pointer&), this function does not throw
  13415. if the given key @a key was not found.
  13416. @param[in] ptr a JSON pointer to the element to access
  13417. @param[in] default_value the value to return if @a ptr found no value
  13418. @tparam ValueType type compatible to JSON values, for instance `int` for
  13419. JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
  13420. JSON arrays. Note the type of the expected value at @a key and the default
  13421. value @a default_value must be compatible.
  13422. @return copy of the element at key @a key or @a default_value if @a key
  13423. is not found
  13424. @throw type_error.306 if the JSON value is not an object; in that case,
  13425. using `value()` with a key makes no sense.
  13426. @complexity Logarithmic in the size of the container.
  13427. @liveexample{The example below shows how object elements can be queried
  13428. with a default value.,basic_json__value_ptr}
  13429. @sa @ref operator[](const json_pointer&) for unchecked access by reference
  13430. @since version 2.0.2
  13431. */
  13432. template<class ValueType, typename std::enable_if<
  13433. std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
  13434. ValueType value(const json_pointer& ptr, const ValueType& default_value) const
  13435. {
  13436. // at only works for objects
  13437. if (JSON_LIKELY(is_object()))
  13438. {
  13439. // if pointer resolves a value, return it or use default value
  13440. JSON_TRY
  13441. {
  13442. return ptr.get_checked(this);
  13443. }
  13444. JSON_INTERNAL_CATCH (out_of_range&)
  13445. {
  13446. return default_value;
  13447. }
  13448. }
  13449. JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
  13450. }
  13451. /*!
  13452. @brief overload for a default value of type const char*
  13453. @copydoc basic_json::value(const json_pointer&, ValueType) const
  13454. */
  13455. string_t value(const json_pointer& ptr, const char* default_value) const
  13456. {
  13457. return value(ptr, string_t(default_value));
  13458. }
  13459. /*!
  13460. @brief access the first element
  13461. Returns a reference to the first element in the container. For a JSON
  13462. container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
  13463. @return In case of a structured type (array or object), a reference to the
  13464. first element is returned. In case of number, string, or boolean values, a
  13465. reference to the value is returned.
  13466. @complexity Constant.
  13467. @pre The JSON value must not be `null` (would throw `std::out_of_range`)
  13468. or an empty array or object (undefined behavior, **guarded by
  13469. assertions**).
  13470. @post The JSON value remains unchanged.
  13471. @throw invalid_iterator.214 when called on `null` value
  13472. @liveexample{The following code shows an example for `front()`.,front}
  13473. @sa @ref back() -- access the last element
  13474. @since version 1.0.0
  13475. */
  13476. reference front()
  13477. {
  13478. return *begin();
  13479. }
  13480. /*!
  13481. @copydoc basic_json::front()
  13482. */
  13483. const_reference front() const
  13484. {
  13485. return *cbegin();
  13486. }
  13487. /*!
  13488. @brief access the last element
  13489. Returns a reference to the last element in the container. For a JSON
  13490. container `c`, the expression `c.back()` is equivalent to
  13491. @code {.cpp}
  13492. auto tmp = c.end();
  13493. --tmp;
  13494. return *tmp;
  13495. @endcode
  13496. @return In case of a structured type (array or object), a reference to the
  13497. last element is returned. In case of number, string, or boolean values, a
  13498. reference to the value is returned.
  13499. @complexity Constant.
  13500. @pre The JSON value must not be `null` (would throw `std::out_of_range`)
  13501. or an empty array or object (undefined behavior, **guarded by
  13502. assertions**).
  13503. @post The JSON value remains unchanged.
  13504. @throw invalid_iterator.214 when called on a `null` value. See example
  13505. below.
  13506. @liveexample{The following code shows an example for `back()`.,back}
  13507. @sa @ref front() -- access the first element
  13508. @since version 1.0.0
  13509. */
  13510. reference back()
  13511. {
  13512. auto tmp = end();
  13513. --tmp;
  13514. return *tmp;
  13515. }
  13516. /*!
  13517. @copydoc basic_json::back()
  13518. */
  13519. const_reference back() const
  13520. {
  13521. auto tmp = cend();
  13522. --tmp;
  13523. return *tmp;
  13524. }
  13525. /*!
  13526. @brief remove element given an iterator
  13527. Removes the element specified by iterator @a pos. The iterator @a pos must
  13528. be valid and dereferenceable. Thus the `end()` iterator (which is valid,
  13529. but is not dereferenceable) cannot be used as a value for @a pos.
  13530. If called on a primitive type other than `null`, the resulting JSON value
  13531. will be `null`.
  13532. @param[in] pos iterator to the element to remove
  13533. @return Iterator following the last removed element. If the iterator @a
  13534. pos refers to the last element, the `end()` iterator is returned.
  13535. @tparam IteratorType an @ref iterator or @ref const_iterator
  13536. @post Invalidates iterators and references at or after the point of the
  13537. erase, including the `end()` iterator.
  13538. @throw type_error.307 if called on a `null` value; example: `"cannot use
  13539. erase() with null"`
  13540. @throw invalid_iterator.202 if called on an iterator which does not belong
  13541. to the current JSON value; example: `"iterator does not fit current
  13542. value"`
  13543. @throw invalid_iterator.205 if called on a primitive type with invalid
  13544. iterator (i.e., any iterator which is not `begin()`); example: `"iterator
  13545. out of range"`
  13546. @complexity The complexity depends on the type:
  13547. - objects: amortized constant
  13548. - arrays: linear in distance between @a pos and the end of the container
  13549. - strings: linear in the length of the string
  13550. - other types: constant
  13551. @liveexample{The example shows the result of `erase()` for different JSON
  13552. types.,erase__IteratorType}
  13553. @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
  13554. the given range
  13555. @sa @ref erase(const typename object_t::key_type&) -- removes the element
  13556. from an object at the given key
  13557. @sa @ref erase(const size_type) -- removes the element from an array at
  13558. the given index
  13559. @since version 1.0.0
  13560. */
  13561. template<class IteratorType, typename std::enable_if<
  13562. std::is_same<IteratorType, typename basic_json_t::iterator>::value or
  13563. std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
  13564. = 0>
  13565. IteratorType erase(IteratorType pos)
  13566. {
  13567. // make sure iterator fits the current value
  13568. if (JSON_UNLIKELY(this != pos.m_object))
  13569. {
  13570. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
  13571. }
  13572. IteratorType result = end();
  13573. switch (m_type)
  13574. {
  13575. case value_t::boolean:
  13576. case value_t::number_float:
  13577. case value_t::number_integer:
  13578. case value_t::number_unsigned:
  13579. case value_t::string:
  13580. {
  13581. if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
  13582. {
  13583. JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
  13584. }
  13585. if (is_string())
  13586. {
  13587. AllocatorType<string_t> alloc;
  13588. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
  13589. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
  13590. m_value.string = nullptr;
  13591. }
  13592. m_type = value_t::null;
  13593. assert_invariant();
  13594. break;
  13595. }
  13596. case value_t::object:
  13597. {
  13598. result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
  13599. break;
  13600. }
  13601. case value_t::array:
  13602. {
  13603. result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
  13604. break;
  13605. }
  13606. default:
  13607. JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
  13608. }
  13609. return result;
  13610. }
  13611. /*!
  13612. @brief remove elements given an iterator range
  13613. Removes the element specified by the range `[first; last)`. The iterator
  13614. @a first does not need to be dereferenceable if `first == last`: erasing
  13615. an empty range is a no-op.
  13616. If called on a primitive type other than `null`, the resulting JSON value
  13617. will be `null`.
  13618. @param[in] first iterator to the beginning of the range to remove
  13619. @param[in] last iterator past the end of the range to remove
  13620. @return Iterator following the last removed element. If the iterator @a
  13621. second refers to the last element, the `end()` iterator is returned.
  13622. @tparam IteratorType an @ref iterator or @ref const_iterator
  13623. @post Invalidates iterators and references at or after the point of the
  13624. erase, including the `end()` iterator.
  13625. @throw type_error.307 if called on a `null` value; example: `"cannot use
  13626. erase() with null"`
  13627. @throw invalid_iterator.203 if called on iterators which does not belong
  13628. to the current JSON value; example: `"iterators do not fit current value"`
  13629. @throw invalid_iterator.204 if called on a primitive type with invalid
  13630. iterators (i.e., if `first != begin()` and `last != end()`); example:
  13631. `"iterators out of range"`
  13632. @complexity The complexity depends on the type:
  13633. - objects: `log(size()) + std::distance(first, last)`
  13634. - arrays: linear in the distance between @a first and @a last, plus linear
  13635. in the distance between @a last and end of the container
  13636. - strings: linear in the length of the string
  13637. - other types: constant
  13638. @liveexample{The example shows the result of `erase()` for different JSON
  13639. types.,erase__IteratorType_IteratorType}
  13640. @sa @ref erase(IteratorType) -- removes the element at a given position
  13641. @sa @ref erase(const typename object_t::key_type&) -- removes the element
  13642. from an object at the given key
  13643. @sa @ref erase(const size_type) -- removes the element from an array at
  13644. the given index
  13645. @since version 1.0.0
  13646. */
  13647. template<class IteratorType, typename std::enable_if<
  13648. std::is_same<IteratorType, typename basic_json_t::iterator>::value or
  13649. std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
  13650. = 0>
  13651. IteratorType erase(IteratorType first, IteratorType last)
  13652. {
  13653. // make sure iterator fits the current value
  13654. if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
  13655. {
  13656. JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
  13657. }
  13658. IteratorType result = end();
  13659. switch (m_type)
  13660. {
  13661. case value_t::boolean:
  13662. case value_t::number_float:
  13663. case value_t::number_integer:
  13664. case value_t::number_unsigned:
  13665. case value_t::string:
  13666. {
  13667. if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
  13668. or not last.m_it.primitive_iterator.is_end()))
  13669. {
  13670. JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
  13671. }
  13672. if (is_string())
  13673. {
  13674. AllocatorType<string_t> alloc;
  13675. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
  13676. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
  13677. m_value.string = nullptr;
  13678. }
  13679. m_type = value_t::null;
  13680. assert_invariant();
  13681. break;
  13682. }
  13683. case value_t::object:
  13684. {
  13685. result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
  13686. last.m_it.object_iterator);
  13687. break;
  13688. }
  13689. case value_t::array:
  13690. {
  13691. result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
  13692. last.m_it.array_iterator);
  13693. break;
  13694. }
  13695. default:
  13696. JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
  13697. }
  13698. return result;
  13699. }
  13700. /*!
  13701. @brief remove element from a JSON object given a key
  13702. Removes elements from a JSON object with the key value @a key.
  13703. @param[in] key value of the elements to remove
  13704. @return Number of elements removed. If @a ObjectType is the default
  13705. `std::map` type, the return value will always be `0` (@a key was not
  13706. found) or `1` (@a key was found).
  13707. @post References and iterators to the erased elements are invalidated.
  13708. Other references and iterators are not affected.
  13709. @throw type_error.307 when called on a type other than JSON object;
  13710. example: `"cannot use erase() with null"`
  13711. @complexity `log(size()) + count(key)`
  13712. @liveexample{The example shows the effect of `erase()`.,erase__key_type}
  13713. @sa @ref erase(IteratorType) -- removes the element at a given position
  13714. @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
  13715. the given range
  13716. @sa @ref erase(const size_type) -- removes the element from an array at
  13717. the given index
  13718. @since version 1.0.0
  13719. */
  13720. size_type erase(const typename object_t::key_type& key)
  13721. {
  13722. // this erase only works for objects
  13723. if (JSON_LIKELY(is_object()))
  13724. {
  13725. return m_value.object->erase(key);
  13726. }
  13727. JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
  13728. }
  13729. /*!
  13730. @brief remove element from a JSON array given an index
  13731. Removes element from a JSON array at the index @a idx.
  13732. @param[in] idx index of the element to remove
  13733. @throw type_error.307 when called on a type other than JSON object;
  13734. example: `"cannot use erase() with null"`
  13735. @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
  13736. is out of range"`
  13737. @complexity Linear in distance between @a idx and the end of the container.
  13738. @liveexample{The example shows the effect of `erase()`.,erase__size_type}
  13739. @sa @ref erase(IteratorType) -- removes the element at a given position
  13740. @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
  13741. the given range
  13742. @sa @ref erase(const typename object_t::key_type&) -- removes the element
  13743. from an object at the given key
  13744. @since version 1.0.0
  13745. */
  13746. void erase(const size_type idx)
  13747. {
  13748. // this erase only works for arrays
  13749. if (JSON_LIKELY(is_array()))
  13750. {
  13751. if (JSON_UNLIKELY(idx >= size()))
  13752. {
  13753. JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
  13754. }
  13755. m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
  13756. }
  13757. else
  13758. {
  13759. JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
  13760. }
  13761. }
  13762. /// @}
  13763. ////////////
  13764. // lookup //
  13765. ////////////
  13766. /// @name lookup
  13767. /// @{
  13768. /*!
  13769. @brief find an element in a JSON object
  13770. Finds an element in a JSON object with key equivalent to @a key. If the
  13771. element is not found or the JSON value is not an object, end() is
  13772. returned.
  13773. @note This method always returns @ref end() when executed on a JSON type
  13774. that is not an object.
  13775. @param[in] key key value of the element to search for.
  13776. @return Iterator to an element with key equivalent to @a key. If no such
  13777. element is found or the JSON value is not an object, past-the-end (see
  13778. @ref end()) iterator is returned.
  13779. @complexity Logarithmic in the size of the JSON object.
  13780. @liveexample{The example shows how `find()` is used.,find__key_type}
  13781. @since version 1.0.0
  13782. */
  13783. template<typename KeyT>
  13784. iterator find(KeyT&& key)
  13785. {
  13786. auto result = end();
  13787. if (is_object())
  13788. {
  13789. result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
  13790. }
  13791. return result;
  13792. }
  13793. /*!
  13794. @brief find an element in a JSON object
  13795. @copydoc find(KeyT&&)
  13796. */
  13797. template<typename KeyT>
  13798. const_iterator find(KeyT&& key) const
  13799. {
  13800. auto result = cend();
  13801. if (is_object())
  13802. {
  13803. result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
  13804. }
  13805. return result;
  13806. }
  13807. /*!
  13808. @brief returns the number of occurrences of a key in a JSON object
  13809. Returns the number of elements with key @a key. If ObjectType is the
  13810. default `std::map` type, the return value will always be `0` (@a key was
  13811. not found) or `1` (@a key was found).
  13812. @note This method always returns `0` when executed on a JSON type that is
  13813. not an object.
  13814. @param[in] key key value of the element to count
  13815. @return Number of elements with key @a key. If the JSON value is not an
  13816. object, the return value will be `0`.
  13817. @complexity Logarithmic in the size of the JSON object.
  13818. @liveexample{The example shows how `count()` is used.,count}
  13819. @since version 1.0.0
  13820. */
  13821. template<typename KeyT>
  13822. size_type count(KeyT&& key) const
  13823. {
  13824. // return 0 for all nonobject types
  13825. return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
  13826. }
  13827. /// @}
  13828. ///////////////
  13829. // iterators //
  13830. ///////////////
  13831. /// @name iterators
  13832. /// @{
  13833. /*!
  13834. @brief returns an iterator to the first element
  13835. Returns an iterator to the first element.
  13836. @image html range-begin-end.svg "Illustration from cppreference.com"
  13837. @return iterator to the first element
  13838. @complexity Constant.
  13839. @requirement This function helps `basic_json` satisfying the
  13840. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  13841. requirements:
  13842. - The complexity is constant.
  13843. @liveexample{The following code shows an example for `begin()`.,begin}
  13844. @sa @ref cbegin() -- returns a const iterator to the beginning
  13845. @sa @ref end() -- returns an iterator to the end
  13846. @sa @ref cend() -- returns a const iterator to the end
  13847. @since version 1.0.0
  13848. */
  13849. iterator begin() noexcept
  13850. {
  13851. iterator result(this);
  13852. result.set_begin();
  13853. return result;
  13854. }
  13855. /*!
  13856. @copydoc basic_json::cbegin()
  13857. */
  13858. const_iterator begin() const noexcept
  13859. {
  13860. return cbegin();
  13861. }
  13862. /*!
  13863. @brief returns a const iterator to the first element
  13864. Returns a const iterator to the first element.
  13865. @image html range-begin-end.svg "Illustration from cppreference.com"
  13866. @return const iterator to the first element
  13867. @complexity Constant.
  13868. @requirement This function helps `basic_json` satisfying the
  13869. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  13870. requirements:
  13871. - The complexity is constant.
  13872. - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
  13873. @liveexample{The following code shows an example for `cbegin()`.,cbegin}
  13874. @sa @ref begin() -- returns an iterator to the beginning
  13875. @sa @ref end() -- returns an iterator to the end
  13876. @sa @ref cend() -- returns a const iterator to the end
  13877. @since version 1.0.0
  13878. */
  13879. const_iterator cbegin() const noexcept
  13880. {
  13881. const_iterator result(this);
  13882. result.set_begin();
  13883. return result;
  13884. }
  13885. /*!
  13886. @brief returns an iterator to one past the last element
  13887. Returns an iterator to one past the last element.
  13888. @image html range-begin-end.svg "Illustration from cppreference.com"
  13889. @return iterator one past the last element
  13890. @complexity Constant.
  13891. @requirement This function helps `basic_json` satisfying the
  13892. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  13893. requirements:
  13894. - The complexity is constant.
  13895. @liveexample{The following code shows an example for `end()`.,end}
  13896. @sa @ref cend() -- returns a const iterator to the end
  13897. @sa @ref begin() -- returns an iterator to the beginning
  13898. @sa @ref cbegin() -- returns a const iterator to the beginning
  13899. @since version 1.0.0
  13900. */
  13901. iterator end() noexcept
  13902. {
  13903. iterator result(this);
  13904. result.set_end();
  13905. return result;
  13906. }
  13907. /*!
  13908. @copydoc basic_json::cend()
  13909. */
  13910. const_iterator end() const noexcept
  13911. {
  13912. return cend();
  13913. }
  13914. /*!
  13915. @brief returns a const iterator to one past the last element
  13916. Returns a const iterator to one past the last element.
  13917. @image html range-begin-end.svg "Illustration from cppreference.com"
  13918. @return const iterator one past the last element
  13919. @complexity Constant.
  13920. @requirement This function helps `basic_json` satisfying the
  13921. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  13922. requirements:
  13923. - The complexity is constant.
  13924. - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
  13925. @liveexample{The following code shows an example for `cend()`.,cend}
  13926. @sa @ref end() -- returns an iterator to the end
  13927. @sa @ref begin() -- returns an iterator to the beginning
  13928. @sa @ref cbegin() -- returns a const iterator to the beginning
  13929. @since version 1.0.0
  13930. */
  13931. const_iterator cend() const noexcept
  13932. {
  13933. const_iterator result(this);
  13934. result.set_end();
  13935. return result;
  13936. }
  13937. /*!
  13938. @brief returns an iterator to the reverse-beginning
  13939. Returns an iterator to the reverse-beginning; that is, the last element.
  13940. @image html range-rbegin-rend.svg "Illustration from cppreference.com"
  13941. @complexity Constant.
  13942. @requirement This function helps `basic_json` satisfying the
  13943. [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
  13944. requirements:
  13945. - The complexity is constant.
  13946. - Has the semantics of `reverse_iterator(end())`.
  13947. @liveexample{The following code shows an example for `rbegin()`.,rbegin}
  13948. @sa @ref crbegin() -- returns a const reverse iterator to the beginning
  13949. @sa @ref rend() -- returns a reverse iterator to the end
  13950. @sa @ref crend() -- returns a const reverse iterator to the end
  13951. @since version 1.0.0
  13952. */
  13953. reverse_iterator rbegin() noexcept
  13954. {
  13955. return reverse_iterator(end());
  13956. }
  13957. /*!
  13958. @copydoc basic_json::crbegin()
  13959. */
  13960. const_reverse_iterator rbegin() const noexcept
  13961. {
  13962. return crbegin();
  13963. }
  13964. /*!
  13965. @brief returns an iterator to the reverse-end
  13966. Returns an iterator to the reverse-end; that is, one before the first
  13967. element.
  13968. @image html range-rbegin-rend.svg "Illustration from cppreference.com"
  13969. @complexity Constant.
  13970. @requirement This function helps `basic_json` satisfying the
  13971. [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
  13972. requirements:
  13973. - The complexity is constant.
  13974. - Has the semantics of `reverse_iterator(begin())`.
  13975. @liveexample{The following code shows an example for `rend()`.,rend}
  13976. @sa @ref crend() -- returns a const reverse iterator to the end
  13977. @sa @ref rbegin() -- returns a reverse iterator to the beginning
  13978. @sa @ref crbegin() -- returns a const reverse iterator to the beginning
  13979. @since version 1.0.0
  13980. */
  13981. reverse_iterator rend() noexcept
  13982. {
  13983. return reverse_iterator(begin());
  13984. }
  13985. /*!
  13986. @copydoc basic_json::crend()
  13987. */
  13988. const_reverse_iterator rend() const noexcept
  13989. {
  13990. return crend();
  13991. }
  13992. /*!
  13993. @brief returns a const reverse iterator to the last element
  13994. Returns a const iterator to the reverse-beginning; that is, the last
  13995. element.
  13996. @image html range-rbegin-rend.svg "Illustration from cppreference.com"
  13997. @complexity Constant.
  13998. @requirement This function helps `basic_json` satisfying the
  13999. [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
  14000. requirements:
  14001. - The complexity is constant.
  14002. - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
  14003. @liveexample{The following code shows an example for `crbegin()`.,crbegin}
  14004. @sa @ref rbegin() -- returns a reverse iterator to the beginning
  14005. @sa @ref rend() -- returns a reverse iterator to the end
  14006. @sa @ref crend() -- returns a const reverse iterator to the end
  14007. @since version 1.0.0
  14008. */
  14009. const_reverse_iterator crbegin() const noexcept
  14010. {
  14011. return const_reverse_iterator(cend());
  14012. }
  14013. /*!
  14014. @brief returns a const reverse iterator to one before the first
  14015. Returns a const reverse iterator to the reverse-end; that is, one before
  14016. the first element.
  14017. @image html range-rbegin-rend.svg "Illustration from cppreference.com"
  14018. @complexity Constant.
  14019. @requirement This function helps `basic_json` satisfying the
  14020. [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
  14021. requirements:
  14022. - The complexity is constant.
  14023. - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
  14024. @liveexample{The following code shows an example for `crend()`.,crend}
  14025. @sa @ref rend() -- returns a reverse iterator to the end
  14026. @sa @ref rbegin() -- returns a reverse iterator to the beginning
  14027. @sa @ref crbegin() -- returns a const reverse iterator to the beginning
  14028. @since version 1.0.0
  14029. */
  14030. const_reverse_iterator crend() const noexcept
  14031. {
  14032. return const_reverse_iterator(cbegin());
  14033. }
  14034. public:
  14035. /*!
  14036. @brief wrapper to access iterator member functions in range-based for
  14037. This function allows to access @ref iterator::key() and @ref
  14038. iterator::value() during range-based for loops. In these loops, a
  14039. reference to the JSON values is returned, so there is no access to the
  14040. underlying iterator.
  14041. For loop without iterator_wrapper:
  14042. @code{cpp}
  14043. for (auto it = j_object.begin(); it != j_object.end(); ++it)
  14044. {
  14045. std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
  14046. }
  14047. @endcode
  14048. Range-based for loop without iterator proxy:
  14049. @code{cpp}
  14050. for (auto it : j_object)
  14051. {
  14052. // "it" is of type json::reference and has no key() member
  14053. std::cout << "value: " << it << '\n';
  14054. }
  14055. @endcode
  14056. Range-based for loop with iterator proxy:
  14057. @code{cpp}
  14058. for (auto it : json::iterator_wrapper(j_object))
  14059. {
  14060. std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
  14061. }
  14062. @endcode
  14063. @note When iterating over an array, `key()` will return the index of the
  14064. element as string (see example).
  14065. @param[in] ref reference to a JSON value
  14066. @return iteration proxy object wrapping @a ref with an interface to use in
  14067. range-based for loops
  14068. @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
  14069. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  14070. changes in the JSON value.
  14071. @complexity Constant.
  14072. @note The name of this function is not yet final and may change in the
  14073. future.
  14074. @deprecated This stream operator is deprecated and will be removed in
  14075. future 4.0.0 of the library. Please use @ref items() instead;
  14076. that is, replace `json::iterator_wrapper(j)` with `j.items()`.
  14077. */
  14078. JSON_DEPRECATED
  14079. static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
  14080. {
  14081. return ref.items();
  14082. }
  14083. /*!
  14084. @copydoc iterator_wrapper(reference)
  14085. */
  14086. JSON_DEPRECATED
  14087. static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
  14088. {
  14089. return ref.items();
  14090. }
  14091. /*!
  14092. @brief helper to access iterator member functions in range-based for
  14093. This function allows to access @ref iterator::key() and @ref
  14094. iterator::value() during range-based for loops. In these loops, a
  14095. reference to the JSON values is returned, so there is no access to the
  14096. underlying iterator.
  14097. For loop without `items()` function:
  14098. @code{cpp}
  14099. for (auto it = j_object.begin(); it != j_object.end(); ++it)
  14100. {
  14101. std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
  14102. }
  14103. @endcode
  14104. Range-based for loop without `items()` function:
  14105. @code{cpp}
  14106. for (auto it : j_object)
  14107. {
  14108. // "it" is of type json::reference and has no key() member
  14109. std::cout << "value: " << it << '\n';
  14110. }
  14111. @endcode
  14112. Range-based for loop with `items()` function:
  14113. @code{cpp}
  14114. for (auto& el : j_object.items())
  14115. {
  14116. std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
  14117. }
  14118. @endcode
  14119. The `items()` function also allows to use
  14120. [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
  14121. (C++17):
  14122. @code{cpp}
  14123. for (auto& [key, val] : j_object.items())
  14124. {
  14125. std::cout << "key: " << key << ", value:" << val << '\n';
  14126. }
  14127. @endcode
  14128. @note When iterating over an array, `key()` will return the index of the
  14129. element as string (see example). For primitive types (e.g., numbers),
  14130. `key()` returns an empty string.
  14131. @return iteration proxy object wrapping @a ref with an interface to use in
  14132. range-based for loops
  14133. @liveexample{The following code shows how the function is used.,items}
  14134. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  14135. changes in the JSON value.
  14136. @complexity Constant.
  14137. @since version 3.1.0, structured bindings support since 3.5.0.
  14138. */
  14139. iteration_proxy<iterator> items() noexcept
  14140. {
  14141. return iteration_proxy<iterator>(*this);
  14142. }
  14143. /*!
  14144. @copydoc items()
  14145. */
  14146. iteration_proxy<const_iterator> items() const noexcept
  14147. {
  14148. return iteration_proxy<const_iterator>(*this);
  14149. }
  14150. /// @}
  14151. //////////////
  14152. // capacity //
  14153. //////////////
  14154. /// @name capacity
  14155. /// @{
  14156. /*!
  14157. @brief checks whether the container is empty.
  14158. Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
  14159. @return The return value depends on the different types and is
  14160. defined as follows:
  14161. Value type | return value
  14162. ----------- | -------------
  14163. null | `true`
  14164. boolean | `false`
  14165. string | `false`
  14166. number | `false`
  14167. object | result of function `object_t::empty()`
  14168. array | result of function `array_t::empty()`
  14169. @liveexample{The following code uses `empty()` to check if a JSON
  14170. object contains any elements.,empty}
  14171. @complexity Constant, as long as @ref array_t and @ref object_t satisfy
  14172. the Container concept; that is, their `empty()` functions have constant
  14173. complexity.
  14174. @iterators No changes.
  14175. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  14176. @note This function does not return whether a string stored as JSON value
  14177. is empty - it returns whether the JSON container itself is empty which is
  14178. false in the case of a string.
  14179. @requirement This function helps `basic_json` satisfying the
  14180. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  14181. requirements:
  14182. - The complexity is constant.
  14183. - Has the semantics of `begin() == end()`.
  14184. @sa @ref size() -- returns the number of elements
  14185. @since version 1.0.0
  14186. */
  14187. bool empty() const noexcept
  14188. {
  14189. switch (m_type)
  14190. {
  14191. case value_t::null:
  14192. {
  14193. // null values are empty
  14194. return true;
  14195. }
  14196. case value_t::array:
  14197. {
  14198. // delegate call to array_t::empty()
  14199. return m_value.array->empty();
  14200. }
  14201. case value_t::object:
  14202. {
  14203. // delegate call to object_t::empty()
  14204. return m_value.object->empty();
  14205. }
  14206. default:
  14207. {
  14208. // all other types are nonempty
  14209. return false;
  14210. }
  14211. }
  14212. }
  14213. /*!
  14214. @brief returns the number of elements
  14215. Returns the number of elements in a JSON value.
  14216. @return The return value depends on the different types and is
  14217. defined as follows:
  14218. Value type | return value
  14219. ----------- | -------------
  14220. null | `0`
  14221. boolean | `1`
  14222. string | `1`
  14223. number | `1`
  14224. object | result of function object_t::size()
  14225. array | result of function array_t::size()
  14226. @liveexample{The following code calls `size()` on the different value
  14227. types.,size}
  14228. @complexity Constant, as long as @ref array_t and @ref object_t satisfy
  14229. the Container concept; that is, their size() functions have constant
  14230. complexity.
  14231. @iterators No changes.
  14232. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  14233. @note This function does not return the length of a string stored as JSON
  14234. value - it returns the number of elements in the JSON value which is 1 in
  14235. the case of a string.
  14236. @requirement This function helps `basic_json` satisfying the
  14237. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  14238. requirements:
  14239. - The complexity is constant.
  14240. - Has the semantics of `std::distance(begin(), end())`.
  14241. @sa @ref empty() -- checks whether the container is empty
  14242. @sa @ref max_size() -- returns the maximal number of elements
  14243. @since version 1.0.0
  14244. */
  14245. size_type size() const noexcept
  14246. {
  14247. switch (m_type)
  14248. {
  14249. case value_t::null:
  14250. {
  14251. // null values are empty
  14252. return 0;
  14253. }
  14254. case value_t::array:
  14255. {
  14256. // delegate call to array_t::size()
  14257. return m_value.array->size();
  14258. }
  14259. case value_t::object:
  14260. {
  14261. // delegate call to object_t::size()
  14262. return m_value.object->size();
  14263. }
  14264. default:
  14265. {
  14266. // all other types have size 1
  14267. return 1;
  14268. }
  14269. }
  14270. }
  14271. /*!
  14272. @brief returns the maximum possible number of elements
  14273. Returns the maximum number of elements a JSON value is able to hold due to
  14274. system or library implementation limitations, i.e. `std::distance(begin(),
  14275. end())` for the JSON value.
  14276. @return The return value depends on the different types and is
  14277. defined as follows:
  14278. Value type | return value
  14279. ----------- | -------------
  14280. null | `0` (same as `size()`)
  14281. boolean | `1` (same as `size()`)
  14282. string | `1` (same as `size()`)
  14283. number | `1` (same as `size()`)
  14284. object | result of function `object_t::max_size()`
  14285. array | result of function `array_t::max_size()`
  14286. @liveexample{The following code calls `max_size()` on the different value
  14287. types. Note the output is implementation specific.,max_size}
  14288. @complexity Constant, as long as @ref array_t and @ref object_t satisfy
  14289. the Container concept; that is, their `max_size()` functions have constant
  14290. complexity.
  14291. @iterators No changes.
  14292. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  14293. @requirement This function helps `basic_json` satisfying the
  14294. [Container](https://en.cppreference.com/w/cpp/named_req/Container)
  14295. requirements:
  14296. - The complexity is constant.
  14297. - Has the semantics of returning `b.size()` where `b` is the largest
  14298. possible JSON value.
  14299. @sa @ref size() -- returns the number of elements
  14300. @since version 1.0.0
  14301. */
  14302. size_type max_size() const noexcept
  14303. {
  14304. switch (m_type)
  14305. {
  14306. case value_t::array:
  14307. {
  14308. // delegate call to array_t::max_size()
  14309. return m_value.array->max_size();
  14310. }
  14311. case value_t::object:
  14312. {
  14313. // delegate call to object_t::max_size()
  14314. return m_value.object->max_size();
  14315. }
  14316. default:
  14317. {
  14318. // all other types have max_size() == size()
  14319. return size();
  14320. }
  14321. }
  14322. }
  14323. /// @}
  14324. ///////////////
  14325. // modifiers //
  14326. ///////////////
  14327. /// @name modifiers
  14328. /// @{
  14329. /*!
  14330. @brief clears the contents
  14331. Clears the content of a JSON value and resets it to the default value as
  14332. if @ref basic_json(value_t) would have been called with the current value
  14333. type from @ref type():
  14334. Value type | initial value
  14335. ----------- | -------------
  14336. null | `null`
  14337. boolean | `false`
  14338. string | `""`
  14339. number | `0`
  14340. object | `{}`
  14341. array | `[]`
  14342. @post Has the same effect as calling
  14343. @code {.cpp}
  14344. *this = basic_json(type());
  14345. @endcode
  14346. @liveexample{The example below shows the effect of `clear()` to different
  14347. JSON types.,clear}
  14348. @complexity Linear in the size of the JSON value.
  14349. @iterators All iterators, pointers and references related to this container
  14350. are invalidated.
  14351. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  14352. @sa @ref basic_json(value_t) -- constructor that creates an object with the
  14353. same value than calling `clear()`
  14354. @since version 1.0.0
  14355. */
  14356. void clear() noexcept
  14357. {
  14358. switch (m_type)
  14359. {
  14360. case value_t::number_integer:
  14361. {
  14362. m_value.number_integer = 0;
  14363. break;
  14364. }
  14365. case value_t::number_unsigned:
  14366. {
  14367. m_value.number_unsigned = 0;
  14368. break;
  14369. }
  14370. case value_t::number_float:
  14371. {
  14372. m_value.number_float = 0.0;
  14373. break;
  14374. }
  14375. case value_t::boolean:
  14376. {
  14377. m_value.boolean = false;
  14378. break;
  14379. }
  14380. case value_t::string:
  14381. {
  14382. m_value.string->clear();
  14383. break;
  14384. }
  14385. case value_t::array:
  14386. {
  14387. m_value.array->clear();
  14388. break;
  14389. }
  14390. case value_t::object:
  14391. {
  14392. m_value.object->clear();
  14393. break;
  14394. }
  14395. default:
  14396. break;
  14397. }
  14398. }
  14399. /*!
  14400. @brief add an object to an array
  14401. Appends the given element @a val to the end of the JSON value. If the
  14402. function is called on a JSON null value, an empty array is created before
  14403. appending @a val.
  14404. @param[in] val the value to add to the JSON array
  14405. @throw type_error.308 when called on a type other than JSON array or
  14406. null; example: `"cannot use push_back() with number"`
  14407. @complexity Amortized constant.
  14408. @liveexample{The example shows how `push_back()` and `+=` can be used to
  14409. add elements to a JSON array. Note how the `null` value was silently
  14410. converted to a JSON array.,push_back}
  14411. @since version 1.0.0
  14412. */
  14413. void push_back(basic_json&& val)
  14414. {
  14415. // push_back only works for null objects or arrays
  14416. if (JSON_UNLIKELY(not(is_null() or is_array())))
  14417. {
  14418. JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
  14419. }
  14420. // transform null object into an array
  14421. if (is_null())
  14422. {
  14423. m_type = value_t::array;
  14424. m_value = value_t::array;
  14425. assert_invariant();
  14426. }
  14427. // add element to array (move semantics)
  14428. m_value.array->push_back(std::move(val));
  14429. // invalidate object
  14430. val.m_type = value_t::null;
  14431. }
  14432. /*!
  14433. @brief add an object to an array
  14434. @copydoc push_back(basic_json&&)
  14435. */
  14436. reference operator+=(basic_json&& val)
  14437. {
  14438. push_back(std::move(val));
  14439. return *this;
  14440. }
  14441. /*!
  14442. @brief add an object to an array
  14443. @copydoc push_back(basic_json&&)
  14444. */
  14445. void push_back(const basic_json& val)
  14446. {
  14447. // push_back only works for null objects or arrays
  14448. if (JSON_UNLIKELY(not(is_null() or is_array())))
  14449. {
  14450. JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
  14451. }
  14452. // transform null object into an array
  14453. if (is_null())
  14454. {
  14455. m_type = value_t::array;
  14456. m_value = value_t::array;
  14457. assert_invariant();
  14458. }
  14459. // add element to array
  14460. m_value.array->push_back(val);
  14461. }
  14462. /*!
  14463. @brief add an object to an array
  14464. @copydoc push_back(basic_json&&)
  14465. */
  14466. reference operator+=(const basic_json& val)
  14467. {
  14468. push_back(val);
  14469. return *this;
  14470. }
  14471. /*!
  14472. @brief add an object to an object
  14473. Inserts the given element @a val to the JSON object. If the function is
  14474. called on a JSON null value, an empty object is created before inserting
  14475. @a val.
  14476. @param[in] val the value to add to the JSON object
  14477. @throw type_error.308 when called on a type other than JSON object or
  14478. null; example: `"cannot use push_back() with number"`
  14479. @complexity Logarithmic in the size of the container, O(log(`size()`)).
  14480. @liveexample{The example shows how `push_back()` and `+=` can be used to
  14481. add elements to a JSON object. Note how the `null` value was silently
  14482. converted to a JSON object.,push_back__object_t__value}
  14483. @since version 1.0.0
  14484. */
  14485. void push_back(const typename object_t::value_type& val)
  14486. {
  14487. // push_back only works for null objects or objects
  14488. if (JSON_UNLIKELY(not(is_null() or is_object())))
  14489. {
  14490. JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
  14491. }
  14492. // transform null object into an object
  14493. if (is_null())
  14494. {
  14495. m_type = value_t::object;
  14496. m_value = value_t::object;
  14497. assert_invariant();
  14498. }
  14499. // add element to array
  14500. m_value.object->insert(val);
  14501. }
  14502. /*!
  14503. @brief add an object to an object
  14504. @copydoc push_back(const typename object_t::value_type&)
  14505. */
  14506. reference operator+=(const typename object_t::value_type& val)
  14507. {
  14508. push_back(val);
  14509. return *this;
  14510. }
  14511. /*!
  14512. @brief add an object to an object
  14513. This function allows to use `push_back` with an initializer list. In case
  14514. 1. the current value is an object,
  14515. 2. the initializer list @a init contains only two elements, and
  14516. 3. the first element of @a init is a string,
  14517. @a init is converted into an object element and added using
  14518. @ref push_back(const typename object_t::value_type&). Otherwise, @a init
  14519. is converted to a JSON value and added using @ref push_back(basic_json&&).
  14520. @param[in] init an initializer list
  14521. @complexity Linear in the size of the initializer list @a init.
  14522. @note This function is required to resolve an ambiguous overload error,
  14523. because pairs like `{"key", "value"}` can be both interpreted as
  14524. `object_t::value_type` or `std::initializer_list<basic_json>`, see
  14525. https://github.com/nlohmann/json/issues/235 for more information.
  14526. @liveexample{The example shows how initializer lists are treated as
  14527. objects when possible.,push_back__initializer_list}
  14528. */
  14529. void push_back(initializer_list_t init)
  14530. {
  14531. if (is_object() and init.size() == 2 and (*init.begin())->is_string())
  14532. {
  14533. basic_json&& key = init.begin()->moved_or_copied();
  14534. push_back(typename object_t::value_type(
  14535. std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
  14536. }
  14537. else
  14538. {
  14539. push_back(basic_json(init));
  14540. }
  14541. }
  14542. /*!
  14543. @brief add an object to an object
  14544. @copydoc push_back(initializer_list_t)
  14545. */
  14546. reference operator+=(initializer_list_t init)
  14547. {
  14548. push_back(init);
  14549. return *this;
  14550. }
  14551. /*!
  14552. @brief add an object to an array
  14553. Creates a JSON value from the passed parameters @a args to the end of the
  14554. JSON value. If the function is called on a JSON null value, an empty array
  14555. is created before appending the value created from @a args.
  14556. @param[in] args arguments to forward to a constructor of @ref basic_json
  14557. @tparam Args compatible types to create a @ref basic_json object
  14558. @throw type_error.311 when called on a type other than JSON array or
  14559. null; example: `"cannot use emplace_back() with number"`
  14560. @complexity Amortized constant.
  14561. @liveexample{The example shows how `push_back()` can be used to add
  14562. elements to a JSON array. Note how the `null` value was silently converted
  14563. to a JSON array.,emplace_back}
  14564. @since version 2.0.8
  14565. */
  14566. template<class... Args>
  14567. void emplace_back(Args&& ... args)
  14568. {
  14569. // emplace_back only works for null objects or arrays
  14570. if (JSON_UNLIKELY(not(is_null() or is_array())))
  14571. {
  14572. JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
  14573. }
  14574. // transform null object into an array
  14575. if (is_null())
  14576. {
  14577. m_type = value_t::array;
  14578. m_value = value_t::array;
  14579. assert_invariant();
  14580. }
  14581. // add element to array (perfect forwarding)
  14582. m_value.array->emplace_back(std::forward<Args>(args)...);
  14583. }
  14584. /*!
  14585. @brief add an object to an object if key does not exist
  14586. Inserts a new element into a JSON object constructed in-place with the
  14587. given @a args if there is no element with the key in the container. If the
  14588. function is called on a JSON null value, an empty object is created before
  14589. appending the value created from @a args.
  14590. @param[in] args arguments to forward to a constructor of @ref basic_json
  14591. @tparam Args compatible types to create a @ref basic_json object
  14592. @return a pair consisting of an iterator to the inserted element, or the
  14593. already-existing element if no insertion happened, and a bool
  14594. denoting whether the insertion took place.
  14595. @throw type_error.311 when called on a type other than JSON object or
  14596. null; example: `"cannot use emplace() with number"`
  14597. @complexity Logarithmic in the size of the container, O(log(`size()`)).
  14598. @liveexample{The example shows how `emplace()` can be used to add elements
  14599. to a JSON object. Note how the `null` value was silently converted to a
  14600. JSON object. Further note how no value is added if there was already one
  14601. value stored with the same key.,emplace}
  14602. @since version 2.0.8
  14603. */
  14604. template<class... Args>
  14605. std::pair<iterator, bool> emplace(Args&& ... args)
  14606. {
  14607. // emplace only works for null objects or arrays
  14608. if (JSON_UNLIKELY(not(is_null() or is_object())))
  14609. {
  14610. JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
  14611. }
  14612. // transform null object into an object
  14613. if (is_null())
  14614. {
  14615. m_type = value_t::object;
  14616. m_value = value_t::object;
  14617. assert_invariant();
  14618. }
  14619. // add element to array (perfect forwarding)
  14620. auto res = m_value.object->emplace(std::forward<Args>(args)...);
  14621. // create result iterator and set iterator to the result of emplace
  14622. auto it = begin();
  14623. it.m_it.object_iterator = res.first;
  14624. // return pair of iterator and boolean
  14625. return {it, res.second};
  14626. }
  14627. /// Helper for insertion of an iterator
  14628. /// @note: This uses std::distance to support GCC 4.8,
  14629. /// see https://github.com/nlohmann/json/pull/1257
  14630. template<typename... Args>
  14631. iterator insert_iterator(const_iterator pos, Args&& ... args)
  14632. {
  14633. iterator result(this);
  14634. assert(m_value.array != nullptr);
  14635. auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
  14636. m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
  14637. result.m_it.array_iterator = m_value.array->begin() + insert_pos;
  14638. // This could have been written as:
  14639. // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
  14640. // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
  14641. return result;
  14642. }
  14643. /*!
  14644. @brief inserts element
  14645. Inserts element @a val before iterator @a pos.
  14646. @param[in] pos iterator before which the content will be inserted; may be
  14647. the end() iterator
  14648. @param[in] val element to insert
  14649. @return iterator pointing to the inserted @a val.
  14650. @throw type_error.309 if called on JSON values other than arrays;
  14651. example: `"cannot use insert() with string"`
  14652. @throw invalid_iterator.202 if @a pos is not an iterator of *this;
  14653. example: `"iterator does not fit current value"`
  14654. @complexity Constant plus linear in the distance between @a pos and end of
  14655. the container.
  14656. @liveexample{The example shows how `insert()` is used.,insert}
  14657. @since version 1.0.0
  14658. */
  14659. iterator insert(const_iterator pos, const basic_json& val)
  14660. {
  14661. // insert only works for arrays
  14662. if (JSON_LIKELY(is_array()))
  14663. {
  14664. // check if iterator pos fits to this JSON value
  14665. if (JSON_UNLIKELY(pos.m_object != this))
  14666. {
  14667. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
  14668. }
  14669. // insert to array and return iterator
  14670. return insert_iterator(pos, val);
  14671. }
  14672. JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
  14673. }
  14674. /*!
  14675. @brief inserts element
  14676. @copydoc insert(const_iterator, const basic_json&)
  14677. */
  14678. iterator insert(const_iterator pos, basic_json&& val)
  14679. {
  14680. return insert(pos, val);
  14681. }
  14682. /*!
  14683. @brief inserts elements
  14684. Inserts @a cnt copies of @a val before iterator @a pos.
  14685. @param[in] pos iterator before which the content will be inserted; may be
  14686. the end() iterator
  14687. @param[in] cnt number of copies of @a val to insert
  14688. @param[in] val element to insert
  14689. @return iterator pointing to the first element inserted, or @a pos if
  14690. `cnt==0`
  14691. @throw type_error.309 if called on JSON values other than arrays; example:
  14692. `"cannot use insert() with string"`
  14693. @throw invalid_iterator.202 if @a pos is not an iterator of *this;
  14694. example: `"iterator does not fit current value"`
  14695. @complexity Linear in @a cnt plus linear in the distance between @a pos
  14696. and end of the container.
  14697. @liveexample{The example shows how `insert()` is used.,insert__count}
  14698. @since version 1.0.0
  14699. */
  14700. iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
  14701. {
  14702. // insert only works for arrays
  14703. if (JSON_LIKELY(is_array()))
  14704. {
  14705. // check if iterator pos fits to this JSON value
  14706. if (JSON_UNLIKELY(pos.m_object != this))
  14707. {
  14708. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
  14709. }
  14710. // insert to array and return iterator
  14711. return insert_iterator(pos, cnt, val);
  14712. }
  14713. JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
  14714. }
  14715. /*!
  14716. @brief inserts elements
  14717. Inserts elements from range `[first, last)` before iterator @a pos.
  14718. @param[in] pos iterator before which the content will be inserted; may be
  14719. the end() iterator
  14720. @param[in] first begin of the range of elements to insert
  14721. @param[in] last end of the range of elements to insert
  14722. @throw type_error.309 if called on JSON values other than arrays; example:
  14723. `"cannot use insert() with string"`
  14724. @throw invalid_iterator.202 if @a pos is not an iterator of *this;
  14725. example: `"iterator does not fit current value"`
  14726. @throw invalid_iterator.210 if @a first and @a last do not belong to the
  14727. same JSON value; example: `"iterators do not fit"`
  14728. @throw invalid_iterator.211 if @a first or @a last are iterators into
  14729. container for which insert is called; example: `"passed iterators may not
  14730. belong to container"`
  14731. @return iterator pointing to the first element inserted, or @a pos if
  14732. `first==last`
  14733. @complexity Linear in `std::distance(first, last)` plus linear in the
  14734. distance between @a pos and end of the container.
  14735. @liveexample{The example shows how `insert()` is used.,insert__range}
  14736. @since version 1.0.0
  14737. */
  14738. iterator insert(const_iterator pos, const_iterator first, const_iterator last)
  14739. {
  14740. // insert only works for arrays
  14741. if (JSON_UNLIKELY(not is_array()))
  14742. {
  14743. JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
  14744. }
  14745. // check if iterator pos fits to this JSON value
  14746. if (JSON_UNLIKELY(pos.m_object != this))
  14747. {
  14748. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
  14749. }
  14750. // check if range iterators belong to the same JSON object
  14751. if (JSON_UNLIKELY(first.m_object != last.m_object))
  14752. {
  14753. JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
  14754. }
  14755. if (JSON_UNLIKELY(first.m_object == this))
  14756. {
  14757. JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
  14758. }
  14759. // insert to array and return iterator
  14760. return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
  14761. }
  14762. /*!
  14763. @brief inserts elements
  14764. Inserts elements from initializer list @a ilist before iterator @a pos.
  14765. @param[in] pos iterator before which the content will be inserted; may be
  14766. the end() iterator
  14767. @param[in] ilist initializer list to insert the values from
  14768. @throw type_error.309 if called on JSON values other than arrays; example:
  14769. `"cannot use insert() with string"`
  14770. @throw invalid_iterator.202 if @a pos is not an iterator of *this;
  14771. example: `"iterator does not fit current value"`
  14772. @return iterator pointing to the first element inserted, or @a pos if
  14773. `ilist` is empty
  14774. @complexity Linear in `ilist.size()` plus linear in the distance between
  14775. @a pos and end of the container.
  14776. @liveexample{The example shows how `insert()` is used.,insert__ilist}
  14777. @since version 1.0.0
  14778. */
  14779. iterator insert(const_iterator pos, initializer_list_t ilist)
  14780. {
  14781. // insert only works for arrays
  14782. if (JSON_UNLIKELY(not is_array()))
  14783. {
  14784. JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
  14785. }
  14786. // check if iterator pos fits to this JSON value
  14787. if (JSON_UNLIKELY(pos.m_object != this))
  14788. {
  14789. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
  14790. }
  14791. // insert to array and return iterator
  14792. return insert_iterator(pos, ilist.begin(), ilist.end());
  14793. }
  14794. /*!
  14795. @brief inserts elements
  14796. Inserts elements from range `[first, last)`.
  14797. @param[in] first begin of the range of elements to insert
  14798. @param[in] last end of the range of elements to insert
  14799. @throw type_error.309 if called on JSON values other than objects; example:
  14800. `"cannot use insert() with string"`
  14801. @throw invalid_iterator.202 if iterator @a first or @a last does does not
  14802. point to an object; example: `"iterators first and last must point to
  14803. objects"`
  14804. @throw invalid_iterator.210 if @a first and @a last do not belong to the
  14805. same JSON value; example: `"iterators do not fit"`
  14806. @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
  14807. of elements to insert.
  14808. @liveexample{The example shows how `insert()` is used.,insert__range_object}
  14809. @since version 3.0.0
  14810. */
  14811. void insert(const_iterator first, const_iterator last)
  14812. {
  14813. // insert only works for objects
  14814. if (JSON_UNLIKELY(not is_object()))
  14815. {
  14816. JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
  14817. }
  14818. // check if range iterators belong to the same JSON object
  14819. if (JSON_UNLIKELY(first.m_object != last.m_object))
  14820. {
  14821. JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
  14822. }
  14823. // passed iterators must belong to objects
  14824. if (JSON_UNLIKELY(not first.m_object->is_object()))
  14825. {
  14826. JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
  14827. }
  14828. m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
  14829. }
  14830. /*!
  14831. @brief updates a JSON object from another object, overwriting existing keys
  14832. Inserts all values from JSON object @a j and overwrites existing keys.
  14833. @param[in] j JSON object to read values from
  14834. @throw type_error.312 if called on JSON values other than objects; example:
  14835. `"cannot use update() with string"`
  14836. @complexity O(N*log(size() + N)), where N is the number of elements to
  14837. insert.
  14838. @liveexample{The example shows how `update()` is used.,update}
  14839. @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
  14840. @since version 3.0.0
  14841. */
  14842. void update(const_reference j)
  14843. {
  14844. // implicitly convert null value to an empty object
  14845. if (is_null())
  14846. {
  14847. m_type = value_t::object;
  14848. m_value.object = create<object_t>();
  14849. assert_invariant();
  14850. }
  14851. if (JSON_UNLIKELY(not is_object()))
  14852. {
  14853. JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
  14854. }
  14855. if (JSON_UNLIKELY(not j.is_object()))
  14856. {
  14857. JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
  14858. }
  14859. for (auto it = j.cbegin(); it != j.cend(); ++it)
  14860. {
  14861. m_value.object->operator[](it.key()) = it.value();
  14862. }
  14863. }
  14864. /*!
  14865. @brief updates a JSON object from another object, overwriting existing keys
  14866. Inserts all values from from range `[first, last)` and overwrites existing
  14867. keys.
  14868. @param[in] first begin of the range of elements to insert
  14869. @param[in] last end of the range of elements to insert
  14870. @throw type_error.312 if called on JSON values other than objects; example:
  14871. `"cannot use update() with string"`
  14872. @throw invalid_iterator.202 if iterator @a first or @a last does does not
  14873. point to an object; example: `"iterators first and last must point to
  14874. objects"`
  14875. @throw invalid_iterator.210 if @a first and @a last do not belong to the
  14876. same JSON value; example: `"iterators do not fit"`
  14877. @complexity O(N*log(size() + N)), where N is the number of elements to
  14878. insert.
  14879. @liveexample{The example shows how `update()` is used__range.,update}
  14880. @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
  14881. @since version 3.0.0
  14882. */
  14883. void update(const_iterator first, const_iterator last)
  14884. {
  14885. // implicitly convert null value to an empty object
  14886. if (is_null())
  14887. {
  14888. m_type = value_t::object;
  14889. m_value.object = create<object_t>();
  14890. assert_invariant();
  14891. }
  14892. if (JSON_UNLIKELY(not is_object()))
  14893. {
  14894. JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
  14895. }
  14896. // check if range iterators belong to the same JSON object
  14897. if (JSON_UNLIKELY(first.m_object != last.m_object))
  14898. {
  14899. JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
  14900. }
  14901. // passed iterators must belong to objects
  14902. if (JSON_UNLIKELY(not first.m_object->is_object()
  14903. or not last.m_object->is_object()))
  14904. {
  14905. JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
  14906. }
  14907. for (auto it = first; it != last; ++it)
  14908. {
  14909. m_value.object->operator[](it.key()) = it.value();
  14910. }
  14911. }
  14912. /*!
  14913. @brief exchanges the values
  14914. Exchanges the contents of the JSON value with those of @a other. Does not
  14915. invoke any move, copy, or swap operations on individual elements. All
  14916. iterators and references remain valid. The past-the-end iterator is
  14917. invalidated.
  14918. @param[in,out] other JSON value to exchange the contents with
  14919. @complexity Constant.
  14920. @liveexample{The example below shows how JSON values can be swapped with
  14921. `swap()`.,swap__reference}
  14922. @since version 1.0.0
  14923. */
  14924. void swap(reference other) noexcept (
  14925. std::is_nothrow_move_constructible<value_t>::value and
  14926. std::is_nothrow_move_assignable<value_t>::value and
  14927. std::is_nothrow_move_constructible<json_value>::value and
  14928. std::is_nothrow_move_assignable<json_value>::value
  14929. )
  14930. {
  14931. std::swap(m_type, other.m_type);
  14932. std::swap(m_value, other.m_value);
  14933. assert_invariant();
  14934. }
  14935. /*!
  14936. @brief exchanges the values
  14937. Exchanges the contents of a JSON array with those of @a other. Does not
  14938. invoke any move, copy, or swap operations on individual elements. All
  14939. iterators and references remain valid. The past-the-end iterator is
  14940. invalidated.
  14941. @param[in,out] other array to exchange the contents with
  14942. @throw type_error.310 when JSON value is not an array; example: `"cannot
  14943. use swap() with string"`
  14944. @complexity Constant.
  14945. @liveexample{The example below shows how arrays can be swapped with
  14946. `swap()`.,swap__array_t}
  14947. @since version 1.0.0
  14948. */
  14949. void swap(array_t& other)
  14950. {
  14951. // swap only works for arrays
  14952. if (JSON_LIKELY(is_array()))
  14953. {
  14954. std::swap(*(m_value.array), other);
  14955. }
  14956. else
  14957. {
  14958. JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
  14959. }
  14960. }
  14961. /*!
  14962. @brief exchanges the values
  14963. Exchanges the contents of a JSON object with those of @a other. Does not
  14964. invoke any move, copy, or swap operations on individual elements. All
  14965. iterators and references remain valid. The past-the-end iterator is
  14966. invalidated.
  14967. @param[in,out] other object to exchange the contents with
  14968. @throw type_error.310 when JSON value is not an object; example:
  14969. `"cannot use swap() with string"`
  14970. @complexity Constant.
  14971. @liveexample{The example below shows how objects can be swapped with
  14972. `swap()`.,swap__object_t}
  14973. @since version 1.0.0
  14974. */
  14975. void swap(object_t& other)
  14976. {
  14977. // swap only works for objects
  14978. if (JSON_LIKELY(is_object()))
  14979. {
  14980. std::swap(*(m_value.object), other);
  14981. }
  14982. else
  14983. {
  14984. JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
  14985. }
  14986. }
  14987. /*!
  14988. @brief exchanges the values
  14989. Exchanges the contents of a JSON string with those of @a other. Does not
  14990. invoke any move, copy, or swap operations on individual elements. All
  14991. iterators and references remain valid. The past-the-end iterator is
  14992. invalidated.
  14993. @param[in,out] other string to exchange the contents with
  14994. @throw type_error.310 when JSON value is not a string; example: `"cannot
  14995. use swap() with boolean"`
  14996. @complexity Constant.
  14997. @liveexample{The example below shows how strings can be swapped with
  14998. `swap()`.,swap__string_t}
  14999. @since version 1.0.0
  15000. */
  15001. void swap(string_t& other)
  15002. {
  15003. // swap only works for strings
  15004. if (JSON_LIKELY(is_string()))
  15005. {
  15006. std::swap(*(m_value.string), other);
  15007. }
  15008. else
  15009. {
  15010. JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
  15011. }
  15012. }
  15013. /// @}
  15014. public:
  15015. //////////////////////////////////////////
  15016. // lexicographical comparison operators //
  15017. //////////////////////////////////////////
  15018. /// @name lexicographical comparison operators
  15019. /// @{
  15020. /*!
  15021. @brief comparison: equal
  15022. Compares two JSON values for equality according to the following rules:
  15023. - Two JSON values are equal if (1) they are from the same type and (2)
  15024. their stored values are the same according to their respective
  15025. `operator==`.
  15026. - Integer and floating-point numbers are automatically converted before
  15027. comparison. Note than two NaN values are always treated as unequal.
  15028. - Two JSON null values are equal.
  15029. @note Floating-point inside JSON values numbers are compared with
  15030. `json::number_float_t::operator==` which is `double::operator==` by
  15031. default. To compare floating-point while respecting an epsilon, an alternative
  15032. [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
  15033. could be used, for instance
  15034. @code {.cpp}
  15035. template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
  15036. inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
  15037. {
  15038. return std::abs(a - b) <= epsilon;
  15039. }
  15040. @endcode
  15041. @note NaN values never compare equal to themselves or to other NaN values.
  15042. @param[in] lhs first JSON value to consider
  15043. @param[in] rhs second JSON value to consider
  15044. @return whether the values @a lhs and @a rhs are equal
  15045. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15046. @complexity Linear.
  15047. @liveexample{The example demonstrates comparing several JSON
  15048. types.,operator__equal}
  15049. @since version 1.0.0
  15050. */
  15051. friend bool operator==(const_reference lhs, const_reference rhs) noexcept
  15052. {
  15053. const auto lhs_type = lhs.type();
  15054. const auto rhs_type = rhs.type();
  15055. if (lhs_type == rhs_type)
  15056. {
  15057. switch (lhs_type)
  15058. {
  15059. case value_t::array:
  15060. return (*lhs.m_value.array == *rhs.m_value.array);
  15061. case value_t::object:
  15062. return (*lhs.m_value.object == *rhs.m_value.object);
  15063. case value_t::null:
  15064. return true;
  15065. case value_t::string:
  15066. return (*lhs.m_value.string == *rhs.m_value.string);
  15067. case value_t::boolean:
  15068. return (lhs.m_value.boolean == rhs.m_value.boolean);
  15069. case value_t::number_integer:
  15070. return (lhs.m_value.number_integer == rhs.m_value.number_integer);
  15071. case value_t::number_unsigned:
  15072. return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
  15073. case value_t::number_float:
  15074. return (lhs.m_value.number_float == rhs.m_value.number_float);
  15075. default:
  15076. return false;
  15077. }
  15078. }
  15079. else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
  15080. {
  15081. return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
  15082. }
  15083. else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
  15084. {
  15085. return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
  15086. }
  15087. else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
  15088. {
  15089. return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
  15090. }
  15091. else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
  15092. {
  15093. return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
  15094. }
  15095. else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
  15096. {
  15097. return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
  15098. }
  15099. else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
  15100. {
  15101. return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
  15102. }
  15103. return false;
  15104. }
  15105. /*!
  15106. @brief comparison: equal
  15107. @copydoc operator==(const_reference, const_reference)
  15108. */
  15109. template<typename ScalarType, typename std::enable_if<
  15110. std::is_scalar<ScalarType>::value, int>::type = 0>
  15111. friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
  15112. {
  15113. return (lhs == basic_json(rhs));
  15114. }
  15115. /*!
  15116. @brief comparison: equal
  15117. @copydoc operator==(const_reference, const_reference)
  15118. */
  15119. template<typename ScalarType, typename std::enable_if<
  15120. std::is_scalar<ScalarType>::value, int>::type = 0>
  15121. friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
  15122. {
  15123. return (basic_json(lhs) == rhs);
  15124. }
  15125. /*!
  15126. @brief comparison: not equal
  15127. Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
  15128. @param[in] lhs first JSON value to consider
  15129. @param[in] rhs second JSON value to consider
  15130. @return whether the values @a lhs and @a rhs are not equal
  15131. @complexity Linear.
  15132. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15133. @liveexample{The example demonstrates comparing several JSON
  15134. types.,operator__notequal}
  15135. @since version 1.0.0
  15136. */
  15137. friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
  15138. {
  15139. return not (lhs == rhs);
  15140. }
  15141. /*!
  15142. @brief comparison: not equal
  15143. @copydoc operator!=(const_reference, const_reference)
  15144. */
  15145. template<typename ScalarType, typename std::enable_if<
  15146. std::is_scalar<ScalarType>::value, int>::type = 0>
  15147. friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
  15148. {
  15149. return (lhs != basic_json(rhs));
  15150. }
  15151. /*!
  15152. @brief comparison: not equal
  15153. @copydoc operator!=(const_reference, const_reference)
  15154. */
  15155. template<typename ScalarType, typename std::enable_if<
  15156. std::is_scalar<ScalarType>::value, int>::type = 0>
  15157. friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
  15158. {
  15159. return (basic_json(lhs) != rhs);
  15160. }
  15161. /*!
  15162. @brief comparison: less than
  15163. Compares whether one JSON value @a lhs is less than another JSON value @a
  15164. rhs according to the following rules:
  15165. - If @a lhs and @a rhs have the same type, the values are compared using
  15166. the default `<` operator.
  15167. - Integer and floating-point numbers are automatically converted before
  15168. comparison
  15169. - In case @a lhs and @a rhs have different types, the values are ignored
  15170. and the order of the types is considered, see
  15171. @ref operator<(const value_t, const value_t).
  15172. @param[in] lhs first JSON value to consider
  15173. @param[in] rhs second JSON value to consider
  15174. @return whether @a lhs is less than @a rhs
  15175. @complexity Linear.
  15176. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15177. @liveexample{The example demonstrates comparing several JSON
  15178. types.,operator__less}
  15179. @since version 1.0.0
  15180. */
  15181. friend bool operator<(const_reference lhs, const_reference rhs) noexcept
  15182. {
  15183. const auto lhs_type = lhs.type();
  15184. const auto rhs_type = rhs.type();
  15185. if (lhs_type == rhs_type)
  15186. {
  15187. switch (lhs_type)
  15188. {
  15189. case value_t::array:
  15190. return (*lhs.m_value.array) < (*rhs.m_value.array);
  15191. case value_t::object:
  15192. return *lhs.m_value.object < *rhs.m_value.object;
  15193. case value_t::null:
  15194. return false;
  15195. case value_t::string:
  15196. return *lhs.m_value.string < *rhs.m_value.string;
  15197. case value_t::boolean:
  15198. return lhs.m_value.boolean < rhs.m_value.boolean;
  15199. case value_t::number_integer:
  15200. return lhs.m_value.number_integer < rhs.m_value.number_integer;
  15201. case value_t::number_unsigned:
  15202. return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
  15203. case value_t::number_float:
  15204. return lhs.m_value.number_float < rhs.m_value.number_float;
  15205. default:
  15206. return false;
  15207. }
  15208. }
  15209. else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
  15210. {
  15211. return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
  15212. }
  15213. else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
  15214. {
  15215. return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
  15216. }
  15217. else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
  15218. {
  15219. return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
  15220. }
  15221. else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
  15222. {
  15223. return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
  15224. }
  15225. else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
  15226. {
  15227. return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
  15228. }
  15229. else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
  15230. {
  15231. return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
  15232. }
  15233. // We only reach this line if we cannot compare values. In that case,
  15234. // we compare types. Note we have to call the operator explicitly,
  15235. // because MSVC has problems otherwise.
  15236. return operator<(lhs_type, rhs_type);
  15237. }
  15238. /*!
  15239. @brief comparison: less than
  15240. @copydoc operator<(const_reference, const_reference)
  15241. */
  15242. template<typename ScalarType, typename std::enable_if<
  15243. std::is_scalar<ScalarType>::value, int>::type = 0>
  15244. friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
  15245. {
  15246. return (lhs < basic_json(rhs));
  15247. }
  15248. /*!
  15249. @brief comparison: less than
  15250. @copydoc operator<(const_reference, const_reference)
  15251. */
  15252. template<typename ScalarType, typename std::enable_if<
  15253. std::is_scalar<ScalarType>::value, int>::type = 0>
  15254. friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
  15255. {
  15256. return (basic_json(lhs) < rhs);
  15257. }
  15258. /*!
  15259. @brief comparison: less than or equal
  15260. Compares whether one JSON value @a lhs is less than or equal to another
  15261. JSON value by calculating `not (rhs < lhs)`.
  15262. @param[in] lhs first JSON value to consider
  15263. @param[in] rhs second JSON value to consider
  15264. @return whether @a lhs is less than or equal to @a rhs
  15265. @complexity Linear.
  15266. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15267. @liveexample{The example demonstrates comparing several JSON
  15268. types.,operator__greater}
  15269. @since version 1.0.0
  15270. */
  15271. friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
  15272. {
  15273. return not (rhs < lhs);
  15274. }
  15275. /*!
  15276. @brief comparison: less than or equal
  15277. @copydoc operator<=(const_reference, const_reference)
  15278. */
  15279. template<typename ScalarType, typename std::enable_if<
  15280. std::is_scalar<ScalarType>::value, int>::type = 0>
  15281. friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
  15282. {
  15283. return (lhs <= basic_json(rhs));
  15284. }
  15285. /*!
  15286. @brief comparison: less than or equal
  15287. @copydoc operator<=(const_reference, const_reference)
  15288. */
  15289. template<typename ScalarType, typename std::enable_if<
  15290. std::is_scalar<ScalarType>::value, int>::type = 0>
  15291. friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
  15292. {
  15293. return (basic_json(lhs) <= rhs);
  15294. }
  15295. /*!
  15296. @brief comparison: greater than
  15297. Compares whether one JSON value @a lhs is greater than another
  15298. JSON value by calculating `not (lhs <= rhs)`.
  15299. @param[in] lhs first JSON value to consider
  15300. @param[in] rhs second JSON value to consider
  15301. @return whether @a lhs is greater than to @a rhs
  15302. @complexity Linear.
  15303. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15304. @liveexample{The example demonstrates comparing several JSON
  15305. types.,operator__lessequal}
  15306. @since version 1.0.0
  15307. */
  15308. friend bool operator>(const_reference lhs, const_reference rhs) noexcept
  15309. {
  15310. return not (lhs <= rhs);
  15311. }
  15312. /*!
  15313. @brief comparison: greater than
  15314. @copydoc operator>(const_reference, const_reference)
  15315. */
  15316. template<typename ScalarType, typename std::enable_if<
  15317. std::is_scalar<ScalarType>::value, int>::type = 0>
  15318. friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
  15319. {
  15320. return (lhs > basic_json(rhs));
  15321. }
  15322. /*!
  15323. @brief comparison: greater than
  15324. @copydoc operator>(const_reference, const_reference)
  15325. */
  15326. template<typename ScalarType, typename std::enable_if<
  15327. std::is_scalar<ScalarType>::value, int>::type = 0>
  15328. friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
  15329. {
  15330. return (basic_json(lhs) > rhs);
  15331. }
  15332. /*!
  15333. @brief comparison: greater than or equal
  15334. Compares whether one JSON value @a lhs is greater than or equal to another
  15335. JSON value by calculating `not (lhs < rhs)`.
  15336. @param[in] lhs first JSON value to consider
  15337. @param[in] rhs second JSON value to consider
  15338. @return whether @a lhs is greater than or equal to @a rhs
  15339. @complexity Linear.
  15340. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15341. @liveexample{The example demonstrates comparing several JSON
  15342. types.,operator__greaterequal}
  15343. @since version 1.0.0
  15344. */
  15345. friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
  15346. {
  15347. return not (lhs < rhs);
  15348. }
  15349. /*!
  15350. @brief comparison: greater than or equal
  15351. @copydoc operator>=(const_reference, const_reference)
  15352. */
  15353. template<typename ScalarType, typename std::enable_if<
  15354. std::is_scalar<ScalarType>::value, int>::type = 0>
  15355. friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
  15356. {
  15357. return (lhs >= basic_json(rhs));
  15358. }
  15359. /*!
  15360. @brief comparison: greater than or equal
  15361. @copydoc operator>=(const_reference, const_reference)
  15362. */
  15363. template<typename ScalarType, typename std::enable_if<
  15364. std::is_scalar<ScalarType>::value, int>::type = 0>
  15365. friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
  15366. {
  15367. return (basic_json(lhs) >= rhs);
  15368. }
  15369. /// @}
  15370. ///////////////////
  15371. // serialization //
  15372. ///////////////////
  15373. /// @name serialization
  15374. /// @{
  15375. /*!
  15376. @brief serialize to stream
  15377. Serialize the given JSON value @a j to the output stream @a o. The JSON
  15378. value will be serialized using the @ref dump member function.
  15379. - The indentation of the output can be controlled with the member variable
  15380. `width` of the output stream @a o. For instance, using the manipulator
  15381. `std::setw(4)` on @a o sets the indentation level to `4` and the
  15382. serialization result is the same as calling `dump(4)`.
  15383. - The indentation character can be controlled with the member variable
  15384. `fill` of the output stream @a o. For instance, the manipulator
  15385. `std::setfill('\\t')` sets indentation to use a tab character rather than
  15386. the default space character.
  15387. @param[in,out] o stream to serialize to
  15388. @param[in] j JSON value to serialize
  15389. @return the stream @a o
  15390. @throw type_error.316 if a string stored inside the JSON value is not
  15391. UTF-8 encoded
  15392. @complexity Linear.
  15393. @liveexample{The example below shows the serialization with different
  15394. parameters to `width` to adjust the indentation level.,operator_serialize}
  15395. @since version 1.0.0; indentation character added in version 3.0.0
  15396. */
  15397. friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
  15398. {
  15399. // read width member and use it as indentation parameter if nonzero
  15400. const bool pretty_print = (o.width() > 0);
  15401. const auto indentation = (pretty_print ? o.width() : 0);
  15402. // reset width to 0 for subsequent calls to this stream
  15403. o.width(0);
  15404. // do the actual serialization
  15405. serializer s(detail::output_adapter<char>(o), o.fill());
  15406. s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
  15407. return o;
  15408. }
  15409. /*!
  15410. @brief serialize to stream
  15411. @deprecated This stream operator is deprecated and will be removed in
  15412. future 4.0.0 of the library. Please use
  15413. @ref operator<<(std::ostream&, const basic_json&)
  15414. instead; that is, replace calls like `j >> o;` with `o << j;`.
  15415. @since version 1.0.0; deprecated since version 3.0.0
  15416. */
  15417. JSON_DEPRECATED
  15418. friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
  15419. {
  15420. return o << j;
  15421. }
  15422. /// @}
  15423. /////////////////////
  15424. // deserialization //
  15425. /////////////////////
  15426. /// @name deserialization
  15427. /// @{
  15428. /*!
  15429. @brief deserialize from a compatible input
  15430. This function reads from a compatible input. Examples are:
  15431. - an array of 1-byte values
  15432. - strings with character/literal type with size of 1 byte
  15433. - input streams
  15434. - container with contiguous storage of 1-byte values. Compatible container
  15435. types include `std::vector`, `std::string`, `std::array`,
  15436. `std::valarray`, and `std::initializer_list`. Furthermore, C-style
  15437. arrays can be used with `std::begin()`/`std::end()`. User-defined
  15438. containers can be used as long as they implement random-access iterators
  15439. and a contiguous storage.
  15440. @pre Each element of the container has a size of 1 byte. Violating this
  15441. precondition yields undefined behavior. **This precondition is enforced
  15442. with a static assertion.**
  15443. @pre The container storage is contiguous. Violating this precondition
  15444. yields undefined behavior. **This precondition is enforced with an
  15445. assertion.**
  15446. @pre Each element of the container has a size of 1 byte. Violating this
  15447. precondition yields undefined behavior. **This precondition is enforced
  15448. with a static assertion.**
  15449. @warning There is no way to enforce all preconditions at compile-time. If
  15450. the function is called with a noncompliant container and with
  15451. assertions switched off, the behavior is undefined and will most
  15452. likely yield segmentation violation.
  15453. @param[in] i input to read from
  15454. @param[in] cb a parser callback function of type @ref parser_callback_t
  15455. which is used to control the deserialization by filtering unwanted values
  15456. (optional)
  15457. @param[in] allow_exceptions whether to throw exceptions in case of a
  15458. parse error (optional, true by default)
  15459. @return result of the deserialization
  15460. @throw parse_error.101 if a parse error occurs; example: `""unexpected end
  15461. of input; expected string literal""`
  15462. @throw parse_error.102 if to_unicode fails or surrogate error
  15463. @throw parse_error.103 if to_unicode fails
  15464. @complexity Linear in the length of the input. The parser is a predictive
  15465. LL(1) parser. The complexity can be higher if the parser callback function
  15466. @a cb has a super-linear complexity.
  15467. @note A UTF-8 byte order mark is silently ignored.
  15468. @liveexample{The example below demonstrates the `parse()` function reading
  15469. from an array.,parse__array__parser_callback_t}
  15470. @liveexample{The example below demonstrates the `parse()` function with
  15471. and without callback function.,parse__string__parser_callback_t}
  15472. @liveexample{The example below demonstrates the `parse()` function with
  15473. and without callback function.,parse__istream__parser_callback_t}
  15474. @liveexample{The example below demonstrates the `parse()` function reading
  15475. from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
  15476. @since version 2.0.3 (contiguous containers)
  15477. */
  15478. static basic_json parse(detail::input_adapter&& i,
  15479. const parser_callback_t cb = nullptr,
  15480. const bool allow_exceptions = true)
  15481. {
  15482. basic_json result;
  15483. parser(i, cb, allow_exceptions).parse(true, result);
  15484. return result;
  15485. }
  15486. static bool accept(detail::input_adapter&& i)
  15487. {
  15488. return parser(i).accept(true);
  15489. }
  15490. /*!
  15491. @brief generate SAX events
  15492. The SAX event lister must follow the interface of @ref json_sax.
  15493. This function reads from a compatible input. Examples are:
  15494. - an array of 1-byte values
  15495. - strings with character/literal type with size of 1 byte
  15496. - input streams
  15497. - container with contiguous storage of 1-byte values. Compatible container
  15498. types include `std::vector`, `std::string`, `std::array`,
  15499. `std::valarray`, and `std::initializer_list`. Furthermore, C-style
  15500. arrays can be used with `std::begin()`/`std::end()`. User-defined
  15501. containers can be used as long as they implement random-access iterators
  15502. and a contiguous storage.
  15503. @pre Each element of the container has a size of 1 byte. Violating this
  15504. precondition yields undefined behavior. **This precondition is enforced
  15505. with a static assertion.**
  15506. @pre The container storage is contiguous. Violating this precondition
  15507. yields undefined behavior. **This precondition is enforced with an
  15508. assertion.**
  15509. @pre Each element of the container has a size of 1 byte. Violating this
  15510. precondition yields undefined behavior. **This precondition is enforced
  15511. with a static assertion.**
  15512. @warning There is no way to enforce all preconditions at compile-time. If
  15513. the function is called with a noncompliant container and with
  15514. assertions switched off, the behavior is undefined and will most
  15515. likely yield segmentation violation.
  15516. @param[in] i input to read from
  15517. @param[in,out] sax SAX event listener
  15518. @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
  15519. @param[in] strict whether the input has to be consumed completely
  15520. @return return value of the last processed SAX event
  15521. @throw parse_error.101 if a parse error occurs; example: `""unexpected end
  15522. of input; expected string literal""`
  15523. @throw parse_error.102 if to_unicode fails or surrogate error
  15524. @throw parse_error.103 if to_unicode fails
  15525. @complexity Linear in the length of the input. The parser is a predictive
  15526. LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
  15527. a super-linear complexity.
  15528. @note A UTF-8 byte order mark is silently ignored.
  15529. @liveexample{The example below demonstrates the `sax_parse()` function
  15530. reading from string and processing the events with a user-defined SAX
  15531. event consumer.,sax_parse}
  15532. @since version 3.2.0
  15533. */
  15534. template <typename SAX>
  15535. static bool sax_parse(detail::input_adapter&& i, SAX* sax,
  15536. input_format_t format = input_format_t::json,
  15537. const bool strict = true)
  15538. {
  15539. assert(sax);
  15540. switch (format)
  15541. {
  15542. case input_format_t::json:
  15543. return parser(std::move(i)).sax_parse(sax, strict);
  15544. default:
  15545. return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
  15546. }
  15547. }
  15548. /*!
  15549. @brief deserialize from an iterator range with contiguous storage
  15550. This function reads from an iterator range of a container with contiguous
  15551. storage of 1-byte values. Compatible container types include
  15552. `std::vector`, `std::string`, `std::array`, `std::valarray`, and
  15553. `std::initializer_list`. Furthermore, C-style arrays can be used with
  15554. `std::begin()`/`std::end()`. User-defined containers can be used as long
  15555. as they implement random-access iterators and a contiguous storage.
  15556. @pre The iterator range is contiguous. Violating this precondition yields
  15557. undefined behavior. **This precondition is enforced with an assertion.**
  15558. @pre Each element in the range has a size of 1 byte. Violating this
  15559. precondition yields undefined behavior. **This precondition is enforced
  15560. with a static assertion.**
  15561. @warning There is no way to enforce all preconditions at compile-time. If
  15562. the function is called with noncompliant iterators and with
  15563. assertions switched off, the behavior is undefined and will most
  15564. likely yield segmentation violation.
  15565. @tparam IteratorType iterator of container with contiguous storage
  15566. @param[in] first begin of the range to parse (included)
  15567. @param[in] last end of the range to parse (excluded)
  15568. @param[in] cb a parser callback function of type @ref parser_callback_t
  15569. which is used to control the deserialization by filtering unwanted values
  15570. (optional)
  15571. @param[in] allow_exceptions whether to throw exceptions in case of a
  15572. parse error (optional, true by default)
  15573. @return result of the deserialization
  15574. @throw parse_error.101 in case of an unexpected token
  15575. @throw parse_error.102 if to_unicode fails or surrogate error
  15576. @throw parse_error.103 if to_unicode fails
  15577. @complexity Linear in the length of the input. The parser is a predictive
  15578. LL(1) parser. The complexity can be higher if the parser callback function
  15579. @a cb has a super-linear complexity.
  15580. @note A UTF-8 byte order mark is silently ignored.
  15581. @liveexample{The example below demonstrates the `parse()` function reading
  15582. from an iterator range.,parse__iteratortype__parser_callback_t}
  15583. @since version 2.0.3
  15584. */
  15585. template<class IteratorType, typename std::enable_if<
  15586. std::is_base_of<
  15587. std::random_access_iterator_tag,
  15588. typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
  15589. static basic_json parse(IteratorType first, IteratorType last,
  15590. const parser_callback_t cb = nullptr,
  15591. const bool allow_exceptions = true)
  15592. {
  15593. basic_json result;
  15594. parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
  15595. return result;
  15596. }
  15597. template<class IteratorType, typename std::enable_if<
  15598. std::is_base_of<
  15599. std::random_access_iterator_tag,
  15600. typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
  15601. static bool accept(IteratorType first, IteratorType last)
  15602. {
  15603. return parser(detail::input_adapter(first, last)).accept(true);
  15604. }
  15605. template<class IteratorType, class SAX, typename std::enable_if<
  15606. std::is_base_of<
  15607. std::random_access_iterator_tag,
  15608. typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
  15609. static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
  15610. {
  15611. return parser(detail::input_adapter(first, last)).sax_parse(sax);
  15612. }
  15613. /*!
  15614. @brief deserialize from stream
  15615. @deprecated This stream operator is deprecated and will be removed in
  15616. version 4.0.0 of the library. Please use
  15617. @ref operator>>(std::istream&, basic_json&)
  15618. instead; that is, replace calls like `j << i;` with `i >> j;`.
  15619. @since version 1.0.0; deprecated since version 3.0.0
  15620. */
  15621. JSON_DEPRECATED
  15622. friend std::istream& operator<<(basic_json& j, std::istream& i)
  15623. {
  15624. return operator>>(i, j);
  15625. }
  15626. /*!
  15627. @brief deserialize from stream
  15628. Deserializes an input stream to a JSON value.
  15629. @param[in,out] i input stream to read a serialized JSON value from
  15630. @param[in,out] j JSON value to write the deserialized input to
  15631. @throw parse_error.101 in case of an unexpected token
  15632. @throw parse_error.102 if to_unicode fails or surrogate error
  15633. @throw parse_error.103 if to_unicode fails
  15634. @complexity Linear in the length of the input. The parser is a predictive
  15635. LL(1) parser.
  15636. @note A UTF-8 byte order mark is silently ignored.
  15637. @liveexample{The example below shows how a JSON value is constructed by
  15638. reading a serialization from a stream.,operator_deserialize}
  15639. @sa parse(std::istream&, const parser_callback_t) for a variant with a
  15640. parser callback function to filter values while parsing
  15641. @since version 1.0.0
  15642. */
  15643. friend std::istream& operator>>(std::istream& i, basic_json& j)
  15644. {
  15645. parser(detail::input_adapter(i)).parse(false, j);
  15646. return i;
  15647. }
  15648. /// @}
  15649. ///////////////////////////
  15650. // convenience functions //
  15651. ///////////////////////////
  15652. /*!
  15653. @brief return the type as string
  15654. Returns the type name as string to be used in error messages - usually to
  15655. indicate that a function was called on a wrong JSON type.
  15656. @return a string representation of a the @a m_type member:
  15657. Value type | return value
  15658. ----------- | -------------
  15659. null | `"null"`
  15660. boolean | `"boolean"`
  15661. string | `"string"`
  15662. number | `"number"` (for all number types)
  15663. object | `"object"`
  15664. array | `"array"`
  15665. discarded | `"discarded"`
  15666. @exceptionsafety No-throw guarantee: this function never throws exceptions.
  15667. @complexity Constant.
  15668. @liveexample{The following code exemplifies `type_name()` for all JSON
  15669. types.,type_name}
  15670. @sa @ref type() -- return the type of the JSON value
  15671. @sa @ref operator value_t() -- return the type of the JSON value (implicit)
  15672. @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
  15673. since 3.0.0
  15674. */
  15675. const char* type_name() const noexcept
  15676. {
  15677. {
  15678. switch (m_type)
  15679. {
  15680. case value_t::null:
  15681. return "null";
  15682. case value_t::object:
  15683. return "object";
  15684. case value_t::array:
  15685. return "array";
  15686. case value_t::string:
  15687. return "string";
  15688. case value_t::boolean:
  15689. return "boolean";
  15690. case value_t::discarded:
  15691. return "discarded";
  15692. default:
  15693. return "number";
  15694. }
  15695. }
  15696. }
  15697. private:
  15698. //////////////////////
  15699. // member variables //
  15700. //////////////////////
  15701. /// the type of the current element
  15702. value_t m_type = value_t::null;
  15703. /// the value of the current element
  15704. json_value m_value = {};
  15705. //////////////////////////////////////////
  15706. // binary serialization/deserialization //
  15707. //////////////////////////////////////////
  15708. /// @name binary serialization/deserialization support
  15709. /// @{
  15710. public:
  15711. /*!
  15712. @brief create a CBOR serialization of a given JSON value
  15713. Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
  15714. Binary Object Representation) serialization format. CBOR is a binary
  15715. serialization format which aims to be more compact than JSON itself, yet
  15716. more efficient to parse.
  15717. The library uses the following mapping from JSON values types to
  15718. CBOR types according to the CBOR specification (RFC 7049):
  15719. JSON value type | value/range | CBOR type | first byte
  15720. --------------- | ------------------------------------------ | ---------------------------------- | ---------------
  15721. null | `null` | Null | 0xF6
  15722. boolean | `true` | True | 0xF5
  15723. boolean | `false` | False | 0xF4
  15724. number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
  15725. number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
  15726. number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
  15727. number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
  15728. number_integer | -24..-1 | Negative integer | 0x20..0x37
  15729. number_integer | 0..23 | Integer | 0x00..0x17
  15730. number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
  15731. number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
  15732. number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
  15733. number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
  15734. number_unsigned | 0..23 | Integer | 0x00..0x17
  15735. number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
  15736. number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
  15737. number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
  15738. number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
  15739. number_float | *any value* | Double-Precision Float | 0xFB
  15740. string | *length*: 0..23 | UTF-8 string | 0x60..0x77
  15741. string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
  15742. string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
  15743. string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
  15744. string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
  15745. array | *size*: 0..23 | array | 0x80..0x97
  15746. array | *size*: 23..255 | array (1 byte follow) | 0x98
  15747. array | *size*: 256..65535 | array (2 bytes follow) | 0x99
  15748. array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
  15749. array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
  15750. object | *size*: 0..23 | map | 0xA0..0xB7
  15751. object | *size*: 23..255 | map (1 byte follow) | 0xB8
  15752. object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
  15753. object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
  15754. object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
  15755. @note The mapping is **complete** in the sense that any JSON value type
  15756. can be converted to a CBOR value.
  15757. @note If NaN or Infinity are stored inside a JSON number, they are
  15758. serialized properly. This behavior differs from the @ref dump()
  15759. function which serializes NaN or Infinity to `null`.
  15760. @note The following CBOR types are not used in the conversion:
  15761. - byte strings (0x40..0x5F)
  15762. - UTF-8 strings terminated by "break" (0x7F)
  15763. - arrays terminated by "break" (0x9F)
  15764. - maps terminated by "break" (0xBF)
  15765. - date/time (0xC0..0xC1)
  15766. - bignum (0xC2..0xC3)
  15767. - decimal fraction (0xC4)
  15768. - bigfloat (0xC5)
  15769. - tagged items (0xC6..0xD4, 0xD8..0xDB)
  15770. - expected conversions (0xD5..0xD7)
  15771. - simple values (0xE0..0xF3, 0xF8)
  15772. - undefined (0xF7)
  15773. - half and single-precision floats (0xF9-0xFA)
  15774. - break (0xFF)
  15775. @param[in] j JSON value to serialize
  15776. @return MessagePack serialization as byte vector
  15777. @complexity Linear in the size of the JSON value @a j.
  15778. @liveexample{The example shows the serialization of a JSON value to a byte
  15779. vector in CBOR format.,to_cbor}
  15780. @sa http://cbor.io
  15781. @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
  15782. analogous deserialization
  15783. @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
  15784. @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
  15785. related UBJSON format
  15786. @since version 2.0.9
  15787. */
  15788. static std::vector<uint8_t> to_cbor(const basic_json& j)
  15789. {
  15790. std::vector<uint8_t> result;
  15791. to_cbor(j, result);
  15792. return result;
  15793. }
  15794. static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
  15795. {
  15796. binary_writer<uint8_t>(o).write_cbor(j);
  15797. }
  15798. static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
  15799. {
  15800. binary_writer<char>(o).write_cbor(j);
  15801. }
  15802. /*!
  15803. @brief create a MessagePack serialization of a given JSON value
  15804. Serializes a given JSON value @a j to a byte vector using the MessagePack
  15805. serialization format. MessagePack is a binary serialization format which
  15806. aims to be more compact than JSON itself, yet more efficient to parse.
  15807. The library uses the following mapping from JSON values types to
  15808. MessagePack types according to the MessagePack specification:
  15809. JSON value type | value/range | MessagePack type | first byte
  15810. --------------- | --------------------------------- | ---------------- | ----------
  15811. null | `null` | nil | 0xC0
  15812. boolean | `true` | true | 0xC3
  15813. boolean | `false` | false | 0xC2
  15814. number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
  15815. number_integer | -2147483648..-32769 | int32 | 0xD2
  15816. number_integer | -32768..-129 | int16 | 0xD1
  15817. number_integer | -128..-33 | int8 | 0xD0
  15818. number_integer | -32..-1 | negative fixint | 0xE0..0xFF
  15819. number_integer | 0..127 | positive fixint | 0x00..0x7F
  15820. number_integer | 128..255 | uint 8 | 0xCC
  15821. number_integer | 256..65535 | uint 16 | 0xCD
  15822. number_integer | 65536..4294967295 | uint 32 | 0xCE
  15823. number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
  15824. number_unsigned | 0..127 | positive fixint | 0x00..0x7F
  15825. number_unsigned | 128..255 | uint 8 | 0xCC
  15826. number_unsigned | 256..65535 | uint 16 | 0xCD
  15827. number_unsigned | 65536..4294967295 | uint 32 | 0xCE
  15828. number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
  15829. number_float | *any value* | float 64 | 0xCB
  15830. string | *length*: 0..31 | fixstr | 0xA0..0xBF
  15831. string | *length*: 32..255 | str 8 | 0xD9
  15832. string | *length*: 256..65535 | str 16 | 0xDA
  15833. string | *length*: 65536..4294967295 | str 32 | 0xDB
  15834. array | *size*: 0..15 | fixarray | 0x90..0x9F
  15835. array | *size*: 16..65535 | array 16 | 0xDC
  15836. array | *size*: 65536..4294967295 | array 32 | 0xDD
  15837. object | *size*: 0..15 | fix map | 0x80..0x8F
  15838. object | *size*: 16..65535 | map 16 | 0xDE
  15839. object | *size*: 65536..4294967295 | map 32 | 0xDF
  15840. @note The mapping is **complete** in the sense that any JSON value type
  15841. can be converted to a MessagePack value.
  15842. @note The following values can **not** be converted to a MessagePack value:
  15843. - strings with more than 4294967295 bytes
  15844. - arrays with more than 4294967295 elements
  15845. - objects with more than 4294967295 elements
  15846. @note The following MessagePack types are not used in the conversion:
  15847. - bin 8 - bin 32 (0xC4..0xC6)
  15848. - ext 8 - ext 32 (0xC7..0xC9)
  15849. - float 32 (0xCA)
  15850. - fixext 1 - fixext 16 (0xD4..0xD8)
  15851. @note Any MessagePack output created @ref to_msgpack can be successfully
  15852. parsed by @ref from_msgpack.
  15853. @note If NaN or Infinity are stored inside a JSON number, they are
  15854. serialized properly. This behavior differs from the @ref dump()
  15855. function which serializes NaN or Infinity to `null`.
  15856. @param[in] j JSON value to serialize
  15857. @return MessagePack serialization as byte vector
  15858. @complexity Linear in the size of the JSON value @a j.
  15859. @liveexample{The example shows the serialization of a JSON value to a byte
  15860. vector in MessagePack format.,to_msgpack}
  15861. @sa http://msgpack.org
  15862. @sa @ref from_msgpack for the analogous deserialization
  15863. @sa @ref to_cbor(const basic_json& for the related CBOR format
  15864. @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
  15865. related UBJSON format
  15866. @since version 2.0.9
  15867. */
  15868. static std::vector<uint8_t> to_msgpack(const basic_json& j)
  15869. {
  15870. std::vector<uint8_t> result;
  15871. to_msgpack(j, result);
  15872. return result;
  15873. }
  15874. static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
  15875. {
  15876. binary_writer<uint8_t>(o).write_msgpack(j);
  15877. }
  15878. static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
  15879. {
  15880. binary_writer<char>(o).write_msgpack(j);
  15881. }
  15882. /*!
  15883. @brief create a UBJSON serialization of a given JSON value
  15884. Serializes a given JSON value @a j to a byte vector using the UBJSON
  15885. (Universal Binary JSON) serialization format. UBJSON aims to be more compact
  15886. than JSON itself, yet more efficient to parse.
  15887. The library uses the following mapping from JSON values types to
  15888. UBJSON types according to the UBJSON specification:
  15889. JSON value type | value/range | UBJSON type | marker
  15890. --------------- | --------------------------------- | ----------- | ------
  15891. null | `null` | null | `Z`
  15892. boolean | `true` | true | `T`
  15893. boolean | `false` | false | `F`
  15894. number_integer | -9223372036854775808..-2147483649 | int64 | `L`
  15895. number_integer | -2147483648..-32769 | int32 | `l`
  15896. number_integer | -32768..-129 | int16 | `I`
  15897. number_integer | -128..127 | int8 | `i`
  15898. number_integer | 128..255 | uint8 | `U`
  15899. number_integer | 256..32767 | int16 | `I`
  15900. number_integer | 32768..2147483647 | int32 | `l`
  15901. number_integer | 2147483648..9223372036854775807 | int64 | `L`
  15902. number_unsigned | 0..127 | int8 | `i`
  15903. number_unsigned | 128..255 | uint8 | `U`
  15904. number_unsigned | 256..32767 | int16 | `I`
  15905. number_unsigned | 32768..2147483647 | int32 | `l`
  15906. number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
  15907. number_float | *any value* | float64 | `D`
  15908. string | *with shortest length indicator* | string | `S`
  15909. array | *see notes on optimized format* | array | `[`
  15910. object | *see notes on optimized format* | map | `{`
  15911. @note The mapping is **complete** in the sense that any JSON value type
  15912. can be converted to a UBJSON value.
  15913. @note The following values can **not** be converted to a UBJSON value:
  15914. - strings with more than 9223372036854775807 bytes (theoretical)
  15915. - unsigned integer numbers above 9223372036854775807
  15916. @note The following markers are not used in the conversion:
  15917. - `Z`: no-op values are not created.
  15918. - `C`: single-byte strings are serialized with `S` markers.
  15919. @note Any UBJSON output created @ref to_ubjson can be successfully parsed
  15920. by @ref from_ubjson.
  15921. @note If NaN or Infinity are stored inside a JSON number, they are
  15922. serialized properly. This behavior differs from the @ref dump()
  15923. function which serializes NaN or Infinity to `null`.
  15924. @note The optimized formats for containers are supported: Parameter
  15925. @a use_size adds size information to the beginning of a container and
  15926. removes the closing marker. Parameter @a use_type further checks
  15927. whether all elements of a container have the same type and adds the
  15928. type marker to the beginning of the container. The @a use_type
  15929. parameter must only be used together with @a use_size = true. Note
  15930. that @a use_size = true alone may result in larger representations -
  15931. the benefit of this parameter is that the receiving side is
  15932. immediately informed on the number of elements of the container.
  15933. @param[in] j JSON value to serialize
  15934. @param[in] use_size whether to add size annotations to container types
  15935. @param[in] use_type whether to add type annotations to container types
  15936. (must be combined with @a use_size = true)
  15937. @return UBJSON serialization as byte vector
  15938. @complexity Linear in the size of the JSON value @a j.
  15939. @liveexample{The example shows the serialization of a JSON value to a byte
  15940. vector in UBJSON format.,to_ubjson}
  15941. @sa http://ubjson.org
  15942. @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
  15943. analogous deserialization
  15944. @sa @ref to_cbor(const basic_json& for the related CBOR format
  15945. @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
  15946. @since version 3.1.0
  15947. */
  15948. static std::vector<uint8_t> to_ubjson(const basic_json& j,
  15949. const bool use_size = false,
  15950. const bool use_type = false)
  15951. {
  15952. std::vector<uint8_t> result;
  15953. to_ubjson(j, result, use_size, use_type);
  15954. return result;
  15955. }
  15956. static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
  15957. const bool use_size = false, const bool use_type = false)
  15958. {
  15959. binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
  15960. }
  15961. static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
  15962. const bool use_size = false, const bool use_type = false)
  15963. {
  15964. binary_writer<char>(o).write_ubjson(j, use_size, use_type);
  15965. }
  15966. /*!
  15967. @brief Serializes the given JSON object `j` to BSON and returns a vector
  15968. containing the corresponding BSON-representation.
  15969. BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
  15970. stored as a single entity (a so-called document).
  15971. The library uses the following mapping from JSON values types to BSON types:
  15972. JSON value type | value/range | BSON type | marker
  15973. --------------- | --------------------------------- | ----------- | ------
  15974. null | `null` | null | 0x0A
  15975. boolean | `true`, `false` | boolean | 0x08
  15976. number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
  15977. number_integer | -2147483648..2147483647 | int32 | 0x10
  15978. number_integer | 2147483648..9223372036854775807 | int64 | 0x12
  15979. number_unsigned | 0..2147483647 | int32 | 0x10
  15980. number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
  15981. number_unsigned | 9223372036854775808..18446744073709551615| -- | --
  15982. number_float | *any value* | double | 0x01
  15983. string | *any value* | string | 0x02
  15984. array | *any value* | document | 0x04
  15985. object | *any value* | document | 0x03
  15986. @warning The mapping is **incomplete**, since only JSON-objects (and things
  15987. contained therein) can be serialized to BSON.
  15988. Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
  15989. and the keys may not contain U+0000, since they are serialized a
  15990. zero-terminated c-strings.
  15991. @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
  15992. @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
  15993. @throw type_error.317 if `!j.is_object()`
  15994. @pre The input `j` is required to be an object: `j.is_object() == true`.
  15995. @note Any BSON output created via @ref to_bson can be successfully parsed
  15996. by @ref from_bson.
  15997. @param[in] j JSON value to serialize
  15998. @return BSON serialization as byte vector
  15999. @complexity Linear in the size of the JSON value @a j.
  16000. @liveexample{The example shows the serialization of a JSON value to a byte
  16001. vector in BSON format.,to_bson}
  16002. @sa http://bsonspec.org/spec.html
  16003. @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
  16004. analogous deserialization
  16005. @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
  16006. related UBJSON format
  16007. @sa @ref to_cbor(const basic_json&) for the related CBOR format
  16008. @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
  16009. */
  16010. static std::vector<uint8_t> to_bson(const basic_json& j)
  16011. {
  16012. std::vector<uint8_t> result;
  16013. to_bson(j, result);
  16014. return result;
  16015. }
  16016. /*!
  16017. @brief Serializes the given JSON object `j` to BSON and forwards the
  16018. corresponding BSON-representation to the given output_adapter `o`.
  16019. @param j The JSON object to convert to BSON.
  16020. @param o The output adapter that receives the binary BSON representation.
  16021. @pre The input `j` shall be an object: `j.is_object() == true`
  16022. @sa @ref to_bson(const basic_json&)
  16023. */
  16024. static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
  16025. {
  16026. binary_writer<uint8_t>(o).write_bson(j);
  16027. }
  16028. /*!
  16029. @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
  16030. */
  16031. static void to_bson(const basic_json& j, detail::output_adapter<char> o)
  16032. {
  16033. binary_writer<char>(o).write_bson(j);
  16034. }
  16035. /*!
  16036. @brief create a JSON value from an input in CBOR format
  16037. Deserializes a given input @a i to a JSON value using the CBOR (Concise
  16038. Binary Object Representation) serialization format.
  16039. The library maps CBOR types to JSON value types as follows:
  16040. CBOR type | JSON value type | first byte
  16041. ---------------------- | --------------- | ----------
  16042. Integer | number_unsigned | 0x00..0x17
  16043. Unsigned integer | number_unsigned | 0x18
  16044. Unsigned integer | number_unsigned | 0x19
  16045. Unsigned integer | number_unsigned | 0x1A
  16046. Unsigned integer | number_unsigned | 0x1B
  16047. Negative integer | number_integer | 0x20..0x37
  16048. Negative integer | number_integer | 0x38
  16049. Negative integer | number_integer | 0x39
  16050. Negative integer | number_integer | 0x3A
  16051. Negative integer | number_integer | 0x3B
  16052. Negative integer | number_integer | 0x40..0x57
  16053. UTF-8 string | string | 0x60..0x77
  16054. UTF-8 string | string | 0x78
  16055. UTF-8 string | string | 0x79
  16056. UTF-8 string | string | 0x7A
  16057. UTF-8 string | string | 0x7B
  16058. UTF-8 string | string | 0x7F
  16059. array | array | 0x80..0x97
  16060. array | array | 0x98
  16061. array | array | 0x99
  16062. array | array | 0x9A
  16063. array | array | 0x9B
  16064. array | array | 0x9F
  16065. map | object | 0xA0..0xB7
  16066. map | object | 0xB8
  16067. map | object | 0xB9
  16068. map | object | 0xBA
  16069. map | object | 0xBB
  16070. map | object | 0xBF
  16071. False | `false` | 0xF4
  16072. True | `true` | 0xF5
  16073. Null | `null` | 0xF6
  16074. Half-Precision Float | number_float | 0xF9
  16075. Single-Precision Float | number_float | 0xFA
  16076. Double-Precision Float | number_float | 0xFB
  16077. @warning The mapping is **incomplete** in the sense that not all CBOR
  16078. types can be converted to a JSON value. The following CBOR types
  16079. are not supported and will yield parse errors (parse_error.112):
  16080. - byte strings (0x40..0x5F)
  16081. - date/time (0xC0..0xC1)
  16082. - bignum (0xC2..0xC3)
  16083. - decimal fraction (0xC4)
  16084. - bigfloat (0xC5)
  16085. - tagged items (0xC6..0xD4, 0xD8..0xDB)
  16086. - expected conversions (0xD5..0xD7)
  16087. - simple values (0xE0..0xF3, 0xF8)
  16088. - undefined (0xF7)
  16089. @warning CBOR allows map keys of any type, whereas JSON only allows
  16090. strings as keys in object values. Therefore, CBOR maps with keys
  16091. other than UTF-8 strings are rejected (parse_error.113).
  16092. @note Any CBOR output created @ref to_cbor can be successfully parsed by
  16093. @ref from_cbor.
  16094. @param[in] i an input in CBOR format convertible to an input adapter
  16095. @param[in] strict whether to expect the input to be consumed until EOF
  16096. (true by default)
  16097. @param[in] allow_exceptions whether to throw exceptions in case of a
  16098. parse error (optional, true by default)
  16099. @return deserialized JSON value
  16100. @throw parse_error.110 if the given input ends prematurely or the end of
  16101. file was not reached when @a strict was set to true
  16102. @throw parse_error.112 if unsupported features from CBOR were
  16103. used in the given input @a v or if the input is not valid CBOR
  16104. @throw parse_error.113 if a string was expected as map key, but not found
  16105. @complexity Linear in the size of the input @a i.
  16106. @liveexample{The example shows the deserialization of a byte vector in CBOR
  16107. format to a JSON value.,from_cbor}
  16108. @sa http://cbor.io
  16109. @sa @ref to_cbor(const basic_json&) for the analogous serialization
  16110. @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
  16111. related MessagePack format
  16112. @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
  16113. related UBJSON format
  16114. @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
  16115. consume input adapters, removed start_index parameter, and added
  16116. @a strict parameter since 3.0.0; added @a allow_exceptions parameter
  16117. since 3.2.0
  16118. */
  16119. static basic_json from_cbor(detail::input_adapter&& i,
  16120. const bool strict = true,
  16121. const bool allow_exceptions = true)
  16122. {
  16123. basic_json result;
  16124. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16125. const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
  16126. return res ? result : basic_json(value_t::discarded);
  16127. }
  16128. /*!
  16129. @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
  16130. */
  16131. template<typename A1, typename A2,
  16132. detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
  16133. static basic_json from_cbor(A1 && a1, A2 && a2,
  16134. const bool strict = true,
  16135. const bool allow_exceptions = true)
  16136. {
  16137. basic_json result;
  16138. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16139. const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
  16140. return res ? result : basic_json(value_t::discarded);
  16141. }
  16142. /*!
  16143. @brief create a JSON value from an input in MessagePack format
  16144. Deserializes a given input @a i to a JSON value using the MessagePack
  16145. serialization format.
  16146. The library maps MessagePack types to JSON value types as follows:
  16147. MessagePack type | JSON value type | first byte
  16148. ---------------- | --------------- | ----------
  16149. positive fixint | number_unsigned | 0x00..0x7F
  16150. fixmap | object | 0x80..0x8F
  16151. fixarray | array | 0x90..0x9F
  16152. fixstr | string | 0xA0..0xBF
  16153. nil | `null` | 0xC0
  16154. false | `false` | 0xC2
  16155. true | `true` | 0xC3
  16156. float 32 | number_float | 0xCA
  16157. float 64 | number_float | 0xCB
  16158. uint 8 | number_unsigned | 0xCC
  16159. uint 16 | number_unsigned | 0xCD
  16160. uint 32 | number_unsigned | 0xCE
  16161. uint 64 | number_unsigned | 0xCF
  16162. int 8 | number_integer | 0xD0
  16163. int 16 | number_integer | 0xD1
  16164. int 32 | number_integer | 0xD2
  16165. int 64 | number_integer | 0xD3
  16166. str 8 | string | 0xD9
  16167. str 16 | string | 0xDA
  16168. str 32 | string | 0xDB
  16169. array 16 | array | 0xDC
  16170. array 32 | array | 0xDD
  16171. map 16 | object | 0xDE
  16172. map 32 | object | 0xDF
  16173. negative fixint | number_integer | 0xE0-0xFF
  16174. @warning The mapping is **incomplete** in the sense that not all
  16175. MessagePack types can be converted to a JSON value. The following
  16176. MessagePack types are not supported and will yield parse errors:
  16177. - bin 8 - bin 32 (0xC4..0xC6)
  16178. - ext 8 - ext 32 (0xC7..0xC9)
  16179. - fixext 1 - fixext 16 (0xD4..0xD8)
  16180. @note Any MessagePack output created @ref to_msgpack can be successfully
  16181. parsed by @ref from_msgpack.
  16182. @param[in] i an input in MessagePack format convertible to an input
  16183. adapter
  16184. @param[in] strict whether to expect the input to be consumed until EOF
  16185. (true by default)
  16186. @param[in] allow_exceptions whether to throw exceptions in case of a
  16187. parse error (optional, true by default)
  16188. @return deserialized JSON value
  16189. @throw parse_error.110 if the given input ends prematurely or the end of
  16190. file was not reached when @a strict was set to true
  16191. @throw parse_error.112 if unsupported features from MessagePack were
  16192. used in the given input @a i or if the input is not valid MessagePack
  16193. @throw parse_error.113 if a string was expected as map key, but not found
  16194. @complexity Linear in the size of the input @a i.
  16195. @liveexample{The example shows the deserialization of a byte vector in
  16196. MessagePack format to a JSON value.,from_msgpack}
  16197. @sa http://msgpack.org
  16198. @sa @ref to_msgpack(const basic_json&) for the analogous serialization
  16199. @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
  16200. related CBOR format
  16201. @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
  16202. the related UBJSON format
  16203. @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
  16204. the related BSON format
  16205. @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
  16206. consume input adapters, removed start_index parameter, and added
  16207. @a strict parameter since 3.0.0; added @a allow_exceptions parameter
  16208. since 3.2.0
  16209. */
  16210. static basic_json from_msgpack(detail::input_adapter&& i,
  16211. const bool strict = true,
  16212. const bool allow_exceptions = true)
  16213. {
  16214. basic_json result;
  16215. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16216. const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
  16217. return res ? result : basic_json(value_t::discarded);
  16218. }
  16219. /*!
  16220. @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
  16221. */
  16222. template<typename A1, typename A2,
  16223. detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
  16224. static basic_json from_msgpack(A1 && a1, A2 && a2,
  16225. const bool strict = true,
  16226. const bool allow_exceptions = true)
  16227. {
  16228. basic_json result;
  16229. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16230. const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
  16231. return res ? result : basic_json(value_t::discarded);
  16232. }
  16233. /*!
  16234. @brief create a JSON value from an input in UBJSON format
  16235. Deserializes a given input @a i to a JSON value using the UBJSON (Universal
  16236. Binary JSON) serialization format.
  16237. The library maps UBJSON types to JSON value types as follows:
  16238. UBJSON type | JSON value type | marker
  16239. ----------- | --------------------------------------- | ------
  16240. no-op | *no value, next value is read* | `N`
  16241. null | `null` | `Z`
  16242. false | `false` | `F`
  16243. true | `true` | `T`
  16244. float32 | number_float | `d`
  16245. float64 | number_float | `D`
  16246. uint8 | number_unsigned | `U`
  16247. int8 | number_integer | `i`
  16248. int16 | number_integer | `I`
  16249. int32 | number_integer | `l`
  16250. int64 | number_integer | `L`
  16251. string | string | `S`
  16252. char | string | `C`
  16253. array | array (optimized values are supported) | `[`
  16254. object | object (optimized values are supported) | `{`
  16255. @note The mapping is **complete** in the sense that any UBJSON value can
  16256. be converted to a JSON value.
  16257. @param[in] i an input in UBJSON format convertible to an input adapter
  16258. @param[in] strict whether to expect the input to be consumed until EOF
  16259. (true by default)
  16260. @param[in] allow_exceptions whether to throw exceptions in case of a
  16261. parse error (optional, true by default)
  16262. @return deserialized JSON value
  16263. @throw parse_error.110 if the given input ends prematurely or the end of
  16264. file was not reached when @a strict was set to true
  16265. @throw parse_error.112 if a parse error occurs
  16266. @throw parse_error.113 if a string could not be parsed successfully
  16267. @complexity Linear in the size of the input @a i.
  16268. @liveexample{The example shows the deserialization of a byte vector in
  16269. UBJSON format to a JSON value.,from_ubjson}
  16270. @sa http://ubjson.org
  16271. @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
  16272. analogous serialization
  16273. @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
  16274. related CBOR format
  16275. @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
  16276. the related MessagePack format
  16277. @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
  16278. the related BSON format
  16279. @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
  16280. */
  16281. static basic_json from_ubjson(detail::input_adapter&& i,
  16282. const bool strict = true,
  16283. const bool allow_exceptions = true)
  16284. {
  16285. basic_json result;
  16286. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16287. const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
  16288. return res ? result : basic_json(value_t::discarded);
  16289. }
  16290. /*!
  16291. @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
  16292. */
  16293. template<typename A1, typename A2,
  16294. detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
  16295. static basic_json from_ubjson(A1 && a1, A2 && a2,
  16296. const bool strict = true,
  16297. const bool allow_exceptions = true)
  16298. {
  16299. basic_json result;
  16300. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16301. const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
  16302. return res ? result : basic_json(value_t::discarded);
  16303. }
  16304. /*!
  16305. @brief Create a JSON value from an input in BSON format
  16306. Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
  16307. serialization format.
  16308. The library maps BSON record types to JSON value types as follows:
  16309. BSON type | BSON marker byte | JSON value type
  16310. --------------- | ---------------- | ---------------------------
  16311. double | 0x01 | number_float
  16312. string | 0x02 | string
  16313. document | 0x03 | object
  16314. array | 0x04 | array
  16315. binary | 0x05 | still unsupported
  16316. undefined | 0x06 | still unsupported
  16317. ObjectId | 0x07 | still unsupported
  16318. boolean | 0x08 | boolean
  16319. UTC Date-Time | 0x09 | still unsupported
  16320. null | 0x0A | null
  16321. Regular Expr. | 0x0B | still unsupported
  16322. DB Pointer | 0x0C | still unsupported
  16323. JavaScript Code | 0x0D | still unsupported
  16324. Symbol | 0x0E | still unsupported
  16325. JavaScript Code | 0x0F | still unsupported
  16326. int32 | 0x10 | number_integer
  16327. Timestamp | 0x11 | still unsupported
  16328. 128-bit decimal float | 0x13 | still unsupported
  16329. Max Key | 0x7F | still unsupported
  16330. Min Key | 0xFF | still unsupported
  16331. @warning The mapping is **incomplete**. The unsupported mappings
  16332. are indicated in the table above.
  16333. @param[in] i an input in BSON format convertible to an input adapter
  16334. @param[in] strict whether to expect the input to be consumed until EOF
  16335. (true by default)
  16336. @param[in] allow_exceptions whether to throw exceptions in case of a
  16337. parse error (optional, true by default)
  16338. @return deserialized JSON value
  16339. @throw parse_error.114 if an unsupported BSON record type is encountered
  16340. @complexity Linear in the size of the input @a i.
  16341. @liveexample{The example shows the deserialization of a byte vector in
  16342. BSON format to a JSON value.,from_bson}
  16343. @sa http://bsonspec.org/spec.html
  16344. @sa @ref to_bson(const basic_json&) for the analogous serialization
  16345. @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
  16346. related CBOR format
  16347. @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
  16348. the related MessagePack format
  16349. @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
  16350. related UBJSON format
  16351. */
  16352. static basic_json from_bson(detail::input_adapter&& i,
  16353. const bool strict = true,
  16354. const bool allow_exceptions = true)
  16355. {
  16356. basic_json result;
  16357. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16358. const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
  16359. return res ? result : basic_json(value_t::discarded);
  16360. }
  16361. /*!
  16362. @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
  16363. */
  16364. template<typename A1, typename A2,
  16365. detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
  16366. static basic_json from_bson(A1 && a1, A2 && a2,
  16367. const bool strict = true,
  16368. const bool allow_exceptions = true)
  16369. {
  16370. basic_json result;
  16371. detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
  16372. const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
  16373. return res ? result : basic_json(value_t::discarded);
  16374. }
  16375. /// @}
  16376. //////////////////////////
  16377. // JSON Pointer support //
  16378. //////////////////////////
  16379. /// @name JSON Pointer functions
  16380. /// @{
  16381. /*!
  16382. @brief access specified element via JSON Pointer
  16383. Uses a JSON pointer to retrieve a reference to the respective JSON value.
  16384. No bound checking is performed. Similar to @ref operator[](const typename
  16385. object_t::key_type&), `null` values are created in arrays and objects if
  16386. necessary.
  16387. In particular:
  16388. - If the JSON pointer points to an object key that does not exist, it
  16389. is created an filled with a `null` value before a reference to it
  16390. is returned.
  16391. - If the JSON pointer points to an array index that does not exist, it
  16392. is created an filled with a `null` value before a reference to it
  16393. is returned. All indices between the current maximum and the given
  16394. index are also filled with `null`.
  16395. - The special value `-` is treated as a synonym for the index past the
  16396. end.
  16397. @param[in] ptr a JSON pointer
  16398. @return reference to the element pointed to by @a ptr
  16399. @complexity Constant.
  16400. @throw parse_error.106 if an array index begins with '0'
  16401. @throw parse_error.109 if an array index was not a number
  16402. @throw out_of_range.404 if the JSON pointer can not be resolved
  16403. @liveexample{The behavior is shown in the example.,operatorjson_pointer}
  16404. @since version 2.0.0
  16405. */
  16406. reference operator[](const json_pointer& ptr)
  16407. {
  16408. return ptr.get_unchecked(this);
  16409. }
  16410. /*!
  16411. @brief access specified element via JSON Pointer
  16412. Uses a JSON pointer to retrieve a reference to the respective JSON value.
  16413. No bound checking is performed. The function does not change the JSON
  16414. value; no `null` values are created. In particular, the the special value
  16415. `-` yields an exception.
  16416. @param[in] ptr JSON pointer to the desired element
  16417. @return const reference to the element pointed to by @a ptr
  16418. @complexity Constant.
  16419. @throw parse_error.106 if an array index begins with '0'
  16420. @throw parse_error.109 if an array index was not a number
  16421. @throw out_of_range.402 if the array index '-' is used
  16422. @throw out_of_range.404 if the JSON pointer can not be resolved
  16423. @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
  16424. @since version 2.0.0
  16425. */
  16426. const_reference operator[](const json_pointer& ptr) const
  16427. {
  16428. return ptr.get_unchecked(this);
  16429. }
  16430. /*!
  16431. @brief access specified element via JSON Pointer
  16432. Returns a reference to the element at with specified JSON pointer @a ptr,
  16433. with bounds checking.
  16434. @param[in] ptr JSON pointer to the desired element
  16435. @return reference to the element pointed to by @a ptr
  16436. @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
  16437. begins with '0'. See example below.
  16438. @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
  16439. is not a number. See example below.
  16440. @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
  16441. is out of range. See example below.
  16442. @throw out_of_range.402 if the array index '-' is used in the passed JSON
  16443. pointer @a ptr. As `at` provides checked access (and no elements are
  16444. implicitly inserted), the index '-' is always invalid. See example below.
  16445. @throw out_of_range.403 if the JSON pointer describes a key of an object
  16446. which cannot be found. See example below.
  16447. @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
  16448. See example below.
  16449. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  16450. changes in the JSON value.
  16451. @complexity Constant.
  16452. @since version 2.0.0
  16453. @liveexample{The behavior is shown in the example.,at_json_pointer}
  16454. */
  16455. reference at(const json_pointer& ptr)
  16456. {
  16457. return ptr.get_checked(this);
  16458. }
  16459. /*!
  16460. @brief access specified element via JSON Pointer
  16461. Returns a const reference to the element at with specified JSON pointer @a
  16462. ptr, with bounds checking.
  16463. @param[in] ptr JSON pointer to the desired element
  16464. @return reference to the element pointed to by @a ptr
  16465. @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
  16466. begins with '0'. See example below.
  16467. @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
  16468. is not a number. See example below.
  16469. @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
  16470. is out of range. See example below.
  16471. @throw out_of_range.402 if the array index '-' is used in the passed JSON
  16472. pointer @a ptr. As `at` provides checked access (and no elements are
  16473. implicitly inserted), the index '-' is always invalid. See example below.
  16474. @throw out_of_range.403 if the JSON pointer describes a key of an object
  16475. which cannot be found. See example below.
  16476. @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
  16477. See example below.
  16478. @exceptionsafety Strong guarantee: if an exception is thrown, there are no
  16479. changes in the JSON value.
  16480. @complexity Constant.
  16481. @since version 2.0.0
  16482. @liveexample{The behavior is shown in the example.,at_json_pointer_const}
  16483. */
  16484. const_reference at(const json_pointer& ptr) const
  16485. {
  16486. return ptr.get_checked(this);
  16487. }
  16488. /*!
  16489. @brief return flattened JSON value
  16490. The function creates a JSON object whose keys are JSON pointers (see [RFC
  16491. 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
  16492. primitive. The original JSON value can be restored using the @ref
  16493. unflatten() function.
  16494. @return an object that maps JSON pointers to primitive values
  16495. @note Empty objects and arrays are flattened to `null` and will not be
  16496. reconstructed correctly by the @ref unflatten() function.
  16497. @complexity Linear in the size the JSON value.
  16498. @liveexample{The following code shows how a JSON object is flattened to an
  16499. object whose keys consist of JSON pointers.,flatten}
  16500. @sa @ref unflatten() for the reverse function
  16501. @since version 2.0.0
  16502. */
  16503. basic_json flatten() const
  16504. {
  16505. basic_json result(value_t::object);
  16506. json_pointer::flatten("", *this, result);
  16507. return result;
  16508. }
  16509. /*!
  16510. @brief unflatten a previously flattened JSON value
  16511. The function restores the arbitrary nesting of a JSON value that has been
  16512. flattened before using the @ref flatten() function. The JSON value must
  16513. meet certain constraints:
  16514. 1. The value must be an object.
  16515. 2. The keys must be JSON pointers (see
  16516. [RFC 6901](https://tools.ietf.org/html/rfc6901))
  16517. 3. The mapped values must be primitive JSON types.
  16518. @return the original JSON from a flattened version
  16519. @note Empty objects and arrays are flattened by @ref flatten() to `null`
  16520. values and can not unflattened to their original type. Apart from
  16521. this example, for a JSON value `j`, the following is always true:
  16522. `j == j.flatten().unflatten()`.
  16523. @complexity Linear in the size the JSON value.
  16524. @throw type_error.314 if value is not an object
  16525. @throw type_error.315 if object values are not primitive
  16526. @liveexample{The following code shows how a flattened JSON object is
  16527. unflattened into the original nested JSON object.,unflatten}
  16528. @sa @ref flatten() for the reverse function
  16529. @since version 2.0.0
  16530. */
  16531. basic_json unflatten() const
  16532. {
  16533. return json_pointer::unflatten(*this);
  16534. }
  16535. /// @}
  16536. //////////////////////////
  16537. // JSON Patch functions //
  16538. //////////////////////////
  16539. /// @name JSON Patch functions
  16540. /// @{
  16541. /*!
  16542. @brief applies a JSON patch
  16543. [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
  16544. expressing a sequence of operations to apply to a JSON) document. With
  16545. this function, a JSON Patch is applied to the current JSON value by
  16546. executing all operations from the patch.
  16547. @param[in] json_patch JSON patch document
  16548. @return patched document
  16549. @note The application of a patch is atomic: Either all operations succeed
  16550. and the patched document is returned or an exception is thrown. In
  16551. any case, the original value is not changed: the patch is applied
  16552. to a copy of the value.
  16553. @throw parse_error.104 if the JSON patch does not consist of an array of
  16554. objects
  16555. @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
  16556. attributes are missing); example: `"operation add must have member path"`
  16557. @throw out_of_range.401 if an array index is out of range.
  16558. @throw out_of_range.403 if a JSON pointer inside the patch could not be
  16559. resolved successfully in the current JSON value; example: `"key baz not
  16560. found"`
  16561. @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
  16562. "move")
  16563. @throw other_error.501 if "test" operation was unsuccessful
  16564. @complexity Linear in the size of the JSON value and the length of the
  16565. JSON patch. As usually only a fraction of the JSON value is affected by
  16566. the patch, the complexity can usually be neglected.
  16567. @liveexample{The following code shows how a JSON patch is applied to a
  16568. value.,patch}
  16569. @sa @ref diff -- create a JSON patch by comparing two JSON values
  16570. @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
  16571. @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
  16572. @since version 2.0.0
  16573. */
  16574. basic_json patch(const basic_json& json_patch) const
  16575. {
  16576. // make a working copy to apply the patch to
  16577. basic_json result = *this;
  16578. // the valid JSON Patch operations
  16579. enum class patch_operations {add, remove, replace, move, copy, test, invalid};
  16580. const auto get_op = [](const std::string & op)
  16581. {
  16582. if (op == "add")
  16583. {
  16584. return patch_operations::add;
  16585. }
  16586. if (op == "remove")
  16587. {
  16588. return patch_operations::remove;
  16589. }
  16590. if (op == "replace")
  16591. {
  16592. return patch_operations::replace;
  16593. }
  16594. if (op == "move")
  16595. {
  16596. return patch_operations::move;
  16597. }
  16598. if (op == "copy")
  16599. {
  16600. return patch_operations::copy;
  16601. }
  16602. if (op == "test")
  16603. {
  16604. return patch_operations::test;
  16605. }
  16606. return patch_operations::invalid;
  16607. };
  16608. // wrapper for "add" operation; add value at ptr
  16609. const auto operation_add = [&result](json_pointer & ptr, basic_json val)
  16610. {
  16611. // adding to the root of the target document means replacing it
  16612. if (ptr.is_root())
  16613. {
  16614. result = val;
  16615. }
  16616. else
  16617. {
  16618. // make sure the top element of the pointer exists
  16619. json_pointer top_pointer = ptr.top();
  16620. if (top_pointer != ptr)
  16621. {
  16622. result.at(top_pointer);
  16623. }
  16624. // get reference to parent of JSON pointer ptr
  16625. const auto last_path = ptr.pop_back();
  16626. basic_json& parent = result[ptr];
  16627. switch (parent.m_type)
  16628. {
  16629. case value_t::null:
  16630. case value_t::object:
  16631. {
  16632. // use operator[] to add value
  16633. parent[last_path] = val;
  16634. break;
  16635. }
  16636. case value_t::array:
  16637. {
  16638. if (last_path == "-")
  16639. {
  16640. // special case: append to back
  16641. parent.push_back(val);
  16642. }
  16643. else
  16644. {
  16645. const auto idx = json_pointer::array_index(last_path);
  16646. if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
  16647. {
  16648. // avoid undefined behavior
  16649. JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
  16650. }
  16651. // default case: insert add offset
  16652. parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
  16653. }
  16654. break;
  16655. }
  16656. // LCOV_EXCL_START
  16657. default:
  16658. {
  16659. // if there exists a parent it cannot be primitive
  16660. assert(false);
  16661. }
  16662. // LCOV_EXCL_STOP
  16663. }
  16664. }
  16665. };
  16666. // wrapper for "remove" operation; remove value at ptr
  16667. const auto operation_remove = [&result](json_pointer & ptr)
  16668. {
  16669. // get reference to parent of JSON pointer ptr
  16670. const auto last_path = ptr.pop_back();
  16671. basic_json& parent = result.at(ptr);
  16672. // remove child
  16673. if (parent.is_object())
  16674. {
  16675. // perform range check
  16676. auto it = parent.find(last_path);
  16677. if (JSON_LIKELY(it != parent.end()))
  16678. {
  16679. parent.erase(it);
  16680. }
  16681. else
  16682. {
  16683. JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
  16684. }
  16685. }
  16686. else if (parent.is_array())
  16687. {
  16688. // note erase performs range check
  16689. parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
  16690. }
  16691. };
  16692. // type check: top level value must be an array
  16693. if (JSON_UNLIKELY(not json_patch.is_array()))
  16694. {
  16695. JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
  16696. }
  16697. // iterate and apply the operations
  16698. for (const auto& val : json_patch)
  16699. {
  16700. // wrapper to get a value for an operation
  16701. const auto get_value = [&val](const std::string & op,
  16702. const std::string & member,
  16703. bool string_type) -> basic_json &
  16704. {
  16705. // find value
  16706. auto it = val.m_value.object->find(member);
  16707. // context-sensitive error message
  16708. const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
  16709. // check if desired value is present
  16710. if (JSON_UNLIKELY(it == val.m_value.object->end()))
  16711. {
  16712. JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
  16713. }
  16714. // check if result is of type string
  16715. if (JSON_UNLIKELY(string_type and not it->second.is_string()))
  16716. {
  16717. JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
  16718. }
  16719. // no error: return value
  16720. return it->second;
  16721. };
  16722. // type check: every element of the array must be an object
  16723. if (JSON_UNLIKELY(not val.is_object()))
  16724. {
  16725. JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
  16726. }
  16727. // collect mandatory members
  16728. const std::string op = get_value("op", "op", true);
  16729. const std::string path = get_value(op, "path", true);
  16730. json_pointer ptr(path);
  16731. switch (get_op(op))
  16732. {
  16733. case patch_operations::add:
  16734. {
  16735. operation_add(ptr, get_value("add", "value", false));
  16736. break;
  16737. }
  16738. case patch_operations::remove:
  16739. {
  16740. operation_remove(ptr);
  16741. break;
  16742. }
  16743. case patch_operations::replace:
  16744. {
  16745. // the "path" location must exist - use at()
  16746. result.at(ptr) = get_value("replace", "value", false);
  16747. break;
  16748. }
  16749. case patch_operations::move:
  16750. {
  16751. const std::string from_path = get_value("move", "from", true);
  16752. json_pointer from_ptr(from_path);
  16753. // the "from" location must exist - use at()
  16754. basic_json v = result.at(from_ptr);
  16755. // The move operation is functionally identical to a
  16756. // "remove" operation on the "from" location, followed
  16757. // immediately by an "add" operation at the target
  16758. // location with the value that was just removed.
  16759. operation_remove(from_ptr);
  16760. operation_add(ptr, v);
  16761. break;
  16762. }
  16763. case patch_operations::copy:
  16764. {
  16765. const std::string from_path = get_value("copy", "from", true);
  16766. const json_pointer from_ptr(from_path);
  16767. // the "from" location must exist - use at()
  16768. basic_json v = result.at(from_ptr);
  16769. // The copy is functionally identical to an "add"
  16770. // operation at the target location using the value
  16771. // specified in the "from" member.
  16772. operation_add(ptr, v);
  16773. break;
  16774. }
  16775. case patch_operations::test:
  16776. {
  16777. bool success = false;
  16778. JSON_TRY
  16779. {
  16780. // check if "value" matches the one at "path"
  16781. // the "path" location must exist - use at()
  16782. success = (result.at(ptr) == get_value("test", "value", false));
  16783. }
  16784. JSON_INTERNAL_CATCH (out_of_range&)
  16785. {
  16786. // ignore out of range errors: success remains false
  16787. }
  16788. // throw an exception if test fails
  16789. if (JSON_UNLIKELY(not success))
  16790. {
  16791. JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
  16792. }
  16793. break;
  16794. }
  16795. case patch_operations::invalid:
  16796. {
  16797. // op must be "add", "remove", "replace", "move", "copy", or
  16798. // "test"
  16799. JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
  16800. }
  16801. }
  16802. }
  16803. return result;
  16804. }
  16805. /*!
  16806. @brief creates a diff as a JSON patch
  16807. Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
  16808. be changed into the value @a target by calling @ref patch function.
  16809. @invariant For two JSON values @a source and @a target, the following code
  16810. yields always `true`:
  16811. @code {.cpp}
  16812. source.patch(diff(source, target)) == target;
  16813. @endcode
  16814. @note Currently, only `remove`, `add`, and `replace` operations are
  16815. generated.
  16816. @param[in] source JSON value to compare from
  16817. @param[in] target JSON value to compare against
  16818. @param[in] path helper value to create JSON pointers
  16819. @return a JSON patch to convert the @a source to @a target
  16820. @complexity Linear in the lengths of @a source and @a target.
  16821. @liveexample{The following code shows how a JSON patch is created as a
  16822. diff for two JSON values.,diff}
  16823. @sa @ref patch -- apply a JSON patch
  16824. @sa @ref merge_patch -- apply a JSON Merge Patch
  16825. @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
  16826. @since version 2.0.0
  16827. */
  16828. static basic_json diff(const basic_json& source, const basic_json& target,
  16829. const std::string& path = "")
  16830. {
  16831. // the patch
  16832. basic_json result(value_t::array);
  16833. // if the values are the same, return empty patch
  16834. if (source == target)
  16835. {
  16836. return result;
  16837. }
  16838. if (source.type() != target.type())
  16839. {
  16840. // different types: replace value
  16841. result.push_back(
  16842. {
  16843. {"op", "replace"}, {"path", path}, {"value", target}
  16844. });
  16845. }
  16846. else
  16847. {
  16848. switch (source.type())
  16849. {
  16850. case value_t::array:
  16851. {
  16852. // first pass: traverse common elements
  16853. std::size_t i = 0;
  16854. while (i < source.size() and i < target.size())
  16855. {
  16856. // recursive call to compare array values at index i
  16857. auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
  16858. result.insert(result.end(), temp_diff.begin(), temp_diff.end());
  16859. ++i;
  16860. }
  16861. // i now reached the end of at least one array
  16862. // in a second pass, traverse the remaining elements
  16863. // remove my remaining elements
  16864. const auto end_index = static_cast<difference_type>(result.size());
  16865. while (i < source.size())
  16866. {
  16867. // add operations in reverse order to avoid invalid
  16868. // indices
  16869. result.insert(result.begin() + end_index, object(
  16870. {
  16871. {"op", "remove"},
  16872. {"path", path + "/" + std::to_string(i)}
  16873. }));
  16874. ++i;
  16875. }
  16876. // add other remaining elements
  16877. while (i < target.size())
  16878. {
  16879. result.push_back(
  16880. {
  16881. {"op", "add"},
  16882. {"path", path + "/" + std::to_string(i)},
  16883. {"value", target[i]}
  16884. });
  16885. ++i;
  16886. }
  16887. break;
  16888. }
  16889. case value_t::object:
  16890. {
  16891. // first pass: traverse this object's elements
  16892. for (auto it = source.cbegin(); it != source.cend(); ++it)
  16893. {
  16894. // escape the key name to be used in a JSON patch
  16895. const auto key = json_pointer::escape(it.key());
  16896. if (target.find(it.key()) != target.end())
  16897. {
  16898. // recursive call to compare object values at key it
  16899. auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
  16900. result.insert(result.end(), temp_diff.begin(), temp_diff.end());
  16901. }
  16902. else
  16903. {
  16904. // found a key that is not in o -> remove it
  16905. result.push_back(object(
  16906. {
  16907. {"op", "remove"}, {"path", path + "/" + key}
  16908. }));
  16909. }
  16910. }
  16911. // second pass: traverse other object's elements
  16912. for (auto it = target.cbegin(); it != target.cend(); ++it)
  16913. {
  16914. if (source.find(it.key()) == source.end())
  16915. {
  16916. // found a key that is not in this -> add it
  16917. const auto key = json_pointer::escape(it.key());
  16918. result.push_back(
  16919. {
  16920. {"op", "add"}, {"path", path + "/" + key},
  16921. {"value", it.value()}
  16922. });
  16923. }
  16924. }
  16925. break;
  16926. }
  16927. default:
  16928. {
  16929. // both primitive type: replace value
  16930. result.push_back(
  16931. {
  16932. {"op", "replace"}, {"path", path}, {"value", target}
  16933. });
  16934. break;
  16935. }
  16936. }
  16937. }
  16938. return result;
  16939. }
  16940. /// @}
  16941. ////////////////////////////////
  16942. // JSON Merge Patch functions //
  16943. ////////////////////////////////
  16944. /// @name JSON Merge Patch functions
  16945. /// @{
  16946. /*!
  16947. @brief applies a JSON Merge Patch
  16948. The merge patch format is primarily intended for use with the HTTP PATCH
  16949. method as a means of describing a set of modifications to a target
  16950. resource's content. This function applies a merge patch to the current
  16951. JSON value.
  16952. The function implements the following algorithm from Section 2 of
  16953. [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
  16954. ```
  16955. define MergePatch(Target, Patch):
  16956. if Patch is an Object:
  16957. if Target is not an Object:
  16958. Target = {} // Ignore the contents and set it to an empty Object
  16959. for each Name/Value pair in Patch:
  16960. if Value is null:
  16961. if Name exists in Target:
  16962. remove the Name/Value pair from Target
  16963. else:
  16964. Target[Name] = MergePatch(Target[Name], Value)
  16965. return Target
  16966. else:
  16967. return Patch
  16968. ```
  16969. Thereby, `Target` is the current object; that is, the patch is applied to
  16970. the current value.
  16971. @param[in] apply_patch the patch to apply
  16972. @complexity Linear in the lengths of @a patch.
  16973. @liveexample{The following code shows how a JSON Merge Patch is applied to
  16974. a JSON document.,merge_patch}
  16975. @sa @ref patch -- apply a JSON patch
  16976. @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
  16977. @since version 3.0.0
  16978. */
  16979. void merge_patch(const basic_json& apply_patch)
  16980. {
  16981. if (apply_patch.is_object())
  16982. {
  16983. if (not is_object())
  16984. {
  16985. *this = object();
  16986. }
  16987. for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
  16988. {
  16989. if (it.value().is_null())
  16990. {
  16991. erase(it.key());
  16992. }
  16993. else
  16994. {
  16995. operator[](it.key()).merge_patch(it.value());
  16996. }
  16997. }
  16998. }
  16999. else
  17000. {
  17001. *this = apply_patch;
  17002. }
  17003. }
  17004. /// @}
  17005. };
  17006. } // namespace nlohmann
  17007. ///////////////////////
  17008. // nonmember support //
  17009. ///////////////////////
  17010. // specialization of std::swap, and std::hash
  17011. namespace std
  17012. {
  17013. /// hash value for JSON objects
  17014. template<>
  17015. struct hash<nlohmann::json>
  17016. {
  17017. /*!
  17018. @brief return a hash value for a JSON object
  17019. @since version 1.0.0
  17020. */
  17021. std::size_t operator()(const nlohmann::json& j) const
  17022. {
  17023. // a naive hashing via the string representation
  17024. const auto& h = hash<nlohmann::json::string_t>();
  17025. return h(j.dump());
  17026. }
  17027. };
  17028. /// specialization for std::less<value_t>
  17029. /// @note: do not remove the space after '<',
  17030. /// see https://github.com/nlohmann/json/pull/679
  17031. template<>
  17032. struct less< ::nlohmann::detail::value_t>
  17033. {
  17034. /*!
  17035. @brief compare two value_t enum values
  17036. @since version 3.0.0
  17037. */
  17038. bool operator()(nlohmann::detail::value_t lhs,
  17039. nlohmann::detail::value_t rhs) const noexcept
  17040. {
  17041. return nlohmann::detail::operator<(lhs, rhs);
  17042. }
  17043. };
  17044. /*!
  17045. @brief exchanges the values of two JSON objects
  17046. @since version 1.0.0
  17047. */
  17048. template<>
  17049. inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
  17050. is_nothrow_move_constructible<nlohmann::json>::value and
  17051. is_nothrow_move_assignable<nlohmann::json>::value
  17052. )
  17053. {
  17054. j1.swap(j2);
  17055. }
  17056. } // namespace std
  17057. /*!
  17058. @brief user-defined string literal for JSON values
  17059. This operator implements a user-defined string literal for JSON objects. It
  17060. can be used by adding `"_json"` to a string literal and returns a JSON object
  17061. if no parse error occurred.
  17062. @param[in] s a string representation of a JSON object
  17063. @param[in] n the length of string @a s
  17064. @return a JSON object
  17065. @since version 1.0.0
  17066. */
  17067. inline nlohmann::json operator "" _json(const char* s, std::size_t n)
  17068. {
  17069. return nlohmann::json::parse(s, s + n);
  17070. }
  17071. /*!
  17072. @brief user-defined string literal for JSON pointer
  17073. This operator implements a user-defined string literal for JSON Pointers. It
  17074. can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
  17075. object if no parse error occurred.
  17076. @param[in] s a string representation of a JSON Pointer
  17077. @param[in] n the length of string @a s
  17078. @return a JSON pointer object
  17079. @since version 2.0.0
  17080. */
  17081. inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
  17082. {
  17083. return nlohmann::json::json_pointer(std::string(s, n));
  17084. }
  17085. // #include <nlohmann/detail/macro_unscope.hpp>
  17086. // restore GCC/clang diagnostic settings
  17087. #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
  17088. #pragma GCC diagnostic pop
  17089. #endif
  17090. #if defined(__clang__)
  17091. #pragma GCC diagnostic pop
  17092. #endif
  17093. // clean up
  17094. #undef JSON_INTERNAL_CATCH
  17095. #undef JSON_CATCH
  17096. #undef JSON_THROW
  17097. #undef JSON_TRY
  17098. #undef JSON_LIKELY
  17099. #undef JSON_UNLIKELY
  17100. #undef JSON_DEPRECATED
  17101. #undef JSON_HAS_CPP_14
  17102. #undef JSON_HAS_CPP_17
  17103. #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
  17104. #undef NLOHMANN_BASIC_JSON_TPL
  17105. #endif
  17106. /* stb_image_write - v1.11 - public domain - http://nothings.org/stb/stb_image_write.h
  17107. writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
  17108. no warranty implied; use at your own risk
  17109. Before #including,
  17110. #define STB_IMAGE_WRITE_IMPLEMENTATION
  17111. in the file that you want to have the implementation.
  17112. Will probably not work correctly with strict-aliasing optimizations.
  17113. If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
  17114. compilation warnings or even errors. To avoid this, also before #including,
  17115. #define STBI_MSC_SECURE_CRT
  17116. ABOUT:
  17117. This header file is a library for writing images to C stdio or a callback.
  17118. The PNG output is not optimal; it is 20-50% larger than the file
  17119. written by a decent optimizing implementation; though providing a custom
  17120. zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
  17121. This library is designed for source code compactness and simplicity,
  17122. not optimal image file size or run-time performance.
  17123. BUILDING:
  17124. You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
  17125. You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
  17126. malloc,realloc,free.
  17127. You can #define STBIW_MEMMOVE() to replace memmove()
  17128. You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
  17129. for PNG compression (instead of the builtin one), it must have the following signature:
  17130. unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
  17131. The returned data will be freed with STBIW_FREE() (free() by default),
  17132. so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
  17133. UNICODE:
  17134. If compiling for Windows and you wish to use Unicode filenames, compile
  17135. with
  17136. #define STBIW_WINDOWS_UTF8
  17137. and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
  17138. Windows wchar_t filenames to utf8.
  17139. USAGE:
  17140. There are five functions, one for each image file format:
  17141. int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
  17142. int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
  17143. int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
  17144. int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
  17145. int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
  17146. void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
  17147. There are also five equivalent functions that use an arbitrary write function. You are
  17148. expected to open/close your file-equivalent before and after calling these:
  17149. int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
  17150. int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
  17151. int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
  17152. int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
  17153. int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
  17154. where the callback is:
  17155. void stbi_write_func(void *context, void *data, int size);
  17156. You can configure it with these global variables:
  17157. int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE
  17158. int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression
  17159. int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode
  17160. You can define STBI_WRITE_NO_STDIO to disable the file variant of these
  17161. functions, so the library will not use stdio.h at all. However, this will
  17162. also disable HDR writing, because it requires stdio for formatted output.
  17163. Each function returns 0 on failure and non-0 on success.
  17164. The functions create an image file defined by the parameters. The image
  17165. is a rectangle of pixels stored from left-to-right, top-to-bottom.
  17166. Each pixel contains 'comp' channels of data stored interleaved with 8-bits
  17167. per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
  17168. monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
  17169. The *data pointer points to the first byte of the top-left-most pixel.
  17170. For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
  17171. a row of pixels to the first byte of the next row of pixels.
  17172. PNG creates output files with the same number of components as the input.
  17173. The BMP format expands Y to RGB in the file format and does not
  17174. output alpha.
  17175. PNG supports writing rectangles of data even when the bytes storing rows of
  17176. data are not consecutive in memory (e.g. sub-rectangles of a larger image),
  17177. by supplying the stride between the beginning of adjacent rows. The other
  17178. formats do not. (Thus you cannot write a native-format BMP through the BMP
  17179. writer, both because it is in BGR order and because it may have padding
  17180. at the end of the line.)
  17181. PNG allows you to set the deflate compression level by setting the global
  17182. variable 'stbi_write_png_compression_level' (it defaults to 8).
  17183. HDR expects linear float data. Since the format is always 32-bit rgb(e)
  17184. data, alpha (if provided) is discarded, and for monochrome data it is
  17185. replicated across all three channels.
  17186. TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
  17187. data, set the global variable 'stbi_write_tga_with_rle' to 0.
  17188. JPEG does ignore alpha channels in input data; quality is between 1 and 100.
  17189. Higher quality looks better but results in a bigger image.
  17190. JPEG baseline (no JPEG progressive).
  17191. CREDITS:
  17192. Sean Barrett - PNG/BMP/TGA
  17193. Baldur Karlsson - HDR
  17194. Jean-Sebastien Guay - TGA monochrome
  17195. Tim Kelsey - misc enhancements
  17196. Alan Hickman - TGA RLE
  17197. Emmanuel Julien - initial file IO callback implementation
  17198. Jon Olick - original jo_jpeg.cpp code
  17199. Daniel Gibson - integrate JPEG, allow external zlib
  17200. Aarni Koskela - allow choosing PNG filter
  17201. bugfixes:
  17202. github:Chribba
  17203. Guillaume Chereau
  17204. github:jry2
  17205. github:romigrou
  17206. Sergio Gonzalez
  17207. Jonas Karlsson
  17208. Filip Wasil
  17209. Thatcher Ulrich
  17210. github:poppolopoppo
  17211. Patrick Boettcher
  17212. github:xeekworx
  17213. Cap Petschulat
  17214. Simon Rodriguez
  17215. Ivan Tikhonov
  17216. github:ignotion
  17217. Adam Schackart
  17218. LICENSE
  17219. See end of file for license information.
  17220. */
  17221. #ifndef INCLUDE_STB_IMAGE_WRITE_H
  17222. #define INCLUDE_STB_IMAGE_WRITE_H
  17223. #include <stdlib.h>
  17224. // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
  17225. #ifndef STBIWDEF
  17226. #ifdef STB_IMAGE_WRITE_STATIC
  17227. #define STBIWDEF static
  17228. #else
  17229. #ifdef __cplusplus
  17230. #define STBIWDEF extern "C"
  17231. #else
  17232. #define STBIWDEF extern
  17233. #endif
  17234. #endif
  17235. #endif
  17236. #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
  17237. extern int stbi_write_tga_with_rle;
  17238. extern int stbi_write_png_compression_level;
  17239. extern int stbi_write_force_png_filter;
  17240. #endif
  17241. #ifndef STBI_WRITE_NO_STDIO
  17242. STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
  17243. STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
  17244. STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
  17245. STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
  17246. STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
  17247. #ifdef STBI_WINDOWS_UTF8
  17248. STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input);
  17249. #endif
  17250. #endif
  17251. typedef void stbi_write_func(void *context, void *data, int size);
  17252. STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
  17253. STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
  17254. STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
  17255. STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
  17256. STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
  17257. STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
  17258. #endif//INCLUDE_STB_IMAGE_WRITE_H
  17259. #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
  17260. #ifdef _WIN32
  17261. #ifndef _CRT_SECURE_NO_WARNINGS
  17262. #define _CRT_SECURE_NO_WARNINGS
  17263. #endif
  17264. #ifndef _CRT_NONSTDC_NO_DEPRECATE
  17265. #define _CRT_NONSTDC_NO_DEPRECATE
  17266. #endif
  17267. #endif
  17268. #ifndef STBI_WRITE_NO_STDIO
  17269. #include <stdio.h>
  17270. #endif // STBI_WRITE_NO_STDIO
  17271. #include <stdarg.h>
  17272. #include <stdlib.h>
  17273. #include <string.h>
  17274. #include <math.h>
  17275. #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
  17276. // ok
  17277. #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
  17278. // ok
  17279. #else
  17280. #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
  17281. #endif
  17282. #ifndef STBIW_MALLOC
  17283. #define STBIW_MALLOC(sz) malloc(sz)
  17284. #define STBIW_REALLOC(p,newsz) realloc(p,newsz)
  17285. #define STBIW_FREE(p) free(p)
  17286. #endif
  17287. #ifndef STBIW_REALLOC_SIZED
  17288. #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
  17289. #endif
  17290. #ifndef STBIW_MEMMOVE
  17291. #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
  17292. #endif
  17293. #ifndef STBIW_ASSERT
  17294. #include <assert.h>
  17295. #define STBIW_ASSERT(x) assert(x)
  17296. #endif
  17297. #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
  17298. #ifdef STB_IMAGE_WRITE_STATIC
  17299. static int stbi__flip_vertically_on_write = 0;
  17300. static int stbi_write_png_compression_level = 8;
  17301. static int stbi_write_tga_with_rle = 1;
  17302. static int stbi_write_force_png_filter = -1;
  17303. #else
  17304. int stbi_write_png_compression_level = 8;
  17305. int stbi__flip_vertically_on_write = 0;
  17306. int stbi_write_tga_with_rle = 1;
  17307. int stbi_write_force_png_filter = -1;
  17308. #endif
  17309. STBIWDEF void stbi_flip_vertically_on_write(int flag)
  17310. {
  17311. stbi__flip_vertically_on_write = flag;
  17312. }
  17313. typedef struct
  17314. {
  17315. stbi_write_func *func;
  17316. void *context;
  17317. } stbi__write_context;
  17318. // initialize a callback-based context
  17319. static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
  17320. {
  17321. s->func = c;
  17322. s->context = context;
  17323. }
  17324. #ifndef STBI_WRITE_NO_STDIO
  17325. static void stbi__stdio_write(void *context, void *data, int size)
  17326. {
  17327. fwrite(data, 1, size, (FILE *)context);
  17328. }
  17329. #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
  17330. #ifdef __cplusplus
  17331. #define STBIW_EXTERN extern "C"
  17332. #else
  17333. #define STBIW_EXTERN extern
  17334. #endif
  17335. STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
  17336. STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
  17337. STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input)
  17338. {
  17339. return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL);
  17340. }
  17341. #endif
  17342. static FILE *stbiw__fopen(char const *filename, char const *mode)
  17343. {
  17344. FILE *f;
  17345. #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
  17346. wchar_t wMode[64];
  17347. wchar_t wFilename[1024];
  17348. if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
  17349. return 0;
  17350. if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
  17351. return 0;
  17352. #if _MSC_VER >= 1400
  17353. if (0 != _wfopen_s(&f, wFilename, wMode))
  17354. f = 0;
  17355. #else
  17356. f = _wfopen(wFilename, wMode);
  17357. #endif
  17358. #elif defined(_MSC_VER) && _MSC_VER >= 1400
  17359. if (0 != fopen_s(&f, filename, mode))
  17360. f = 0;
  17361. #else
  17362. f = fopen(filename, mode);
  17363. #endif
  17364. return f;
  17365. }
  17366. static int stbi__start_write_file(stbi__write_context *s, const char *filename)
  17367. {
  17368. FILE *f = stbiw__fopen(filename, "wb");
  17369. stbi__start_write_callbacks(s, stbi__stdio_write, (void *)f);
  17370. return f != NULL;
  17371. }
  17372. static void stbi__end_write_file(stbi__write_context *s)
  17373. {
  17374. fclose((FILE *)s->context);
  17375. }
  17376. #endif // !STBI_WRITE_NO_STDIO
  17377. typedef unsigned int stbiw_uint32;
  17378. typedef int stb_image_write_test[sizeof(stbiw_uint32) == 4 ? 1 : -1];
  17379. static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
  17380. {
  17381. while (*fmt)
  17382. {
  17383. switch (*fmt++)
  17384. {
  17385. case ' ': break;
  17386. case '1':
  17387. {
  17388. unsigned char x = STBIW_UCHAR(va_arg(v, int));
  17389. s->func(s->context, &x, 1);
  17390. break;
  17391. }
  17392. case '2':
  17393. {
  17394. int x = va_arg(v, int);
  17395. unsigned char b[2];
  17396. b[0] = STBIW_UCHAR(x);
  17397. b[1] = STBIW_UCHAR(x >> 8);
  17398. s->func(s->context, b, 2);
  17399. break;
  17400. }
  17401. case '4':
  17402. {
  17403. stbiw_uint32 x = va_arg(v, int);
  17404. unsigned char b[4];
  17405. b[0] = STBIW_UCHAR(x);
  17406. b[1] = STBIW_UCHAR(x >> 8);
  17407. b[2] = STBIW_UCHAR(x >> 16);
  17408. b[3] = STBIW_UCHAR(x >> 24);
  17409. s->func(s->context, b, 4);
  17410. break;
  17411. }
  17412. default:
  17413. STBIW_ASSERT(0);
  17414. return;
  17415. }
  17416. }
  17417. }
  17418. static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
  17419. {
  17420. va_list v;
  17421. va_start(v, fmt);
  17422. stbiw__writefv(s, fmt, v);
  17423. va_end(v);
  17424. }
  17425. static void stbiw__putc(stbi__write_context *s, unsigned char c)
  17426. {
  17427. s->func(s->context, &c, 1);
  17428. }
  17429. static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
  17430. {
  17431. unsigned char arr[3];
  17432. arr[0] = a, arr[1] = b, arr[2] = c;
  17433. s->func(s->context, arr, 3);
  17434. }
  17435. static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
  17436. {
  17437. unsigned char bg[3] = { 255, 0, 255 }, px[3];
  17438. int k;
  17439. if (write_alpha < 0)
  17440. s->func(s->context, &d[comp - 1], 1);
  17441. switch (comp)
  17442. {
  17443. case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
  17444. case 1:
  17445. if (expand_mono)
  17446. stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
  17447. else
  17448. s->func(s->context, d, 1); // monochrome TGA
  17449. break;
  17450. case 4:
  17451. if (!write_alpha)
  17452. {
  17453. // composite against pink background
  17454. for (k = 0; k < 3; ++k)
  17455. px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
  17456. stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
  17457. break;
  17458. }
  17459. /* FALLTHROUGH */
  17460. case 3:
  17461. stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
  17462. break;
  17463. }
  17464. if (write_alpha > 0)
  17465. s->func(s->context, &d[comp - 1], 1);
  17466. }
  17467. static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
  17468. {
  17469. stbiw_uint32 zero = 0;
  17470. int i, j, j_end;
  17471. if (y <= 0)
  17472. return;
  17473. if (stbi__flip_vertically_on_write)
  17474. vdir *= -1;
  17475. if (vdir < 0)
  17476. j_end = -1, j = y - 1;
  17477. else
  17478. j_end = y, j = 0;
  17479. for (; j != j_end; j += vdir)
  17480. {
  17481. for (i = 0; i < x; ++i)
  17482. {
  17483. unsigned char *d = (unsigned char *)data + (j * x + i) * comp;
  17484. stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
  17485. }
  17486. s->func(s->context, &zero, scanline_pad);
  17487. }
  17488. }
  17489. static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
  17490. {
  17491. if (y < 0 || x < 0)
  17492. {
  17493. return 0;
  17494. }
  17495. else
  17496. {
  17497. va_list v;
  17498. va_start(v, fmt);
  17499. stbiw__writefv(s, fmt, v);
  17500. va_end(v);
  17501. stbiw__write_pixels(s, rgb_dir, vdir, x, y, comp, data, alpha, pad, expand_mono);
  17502. return 1;
  17503. }
  17504. }
  17505. static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
  17506. {
  17507. int pad = (-x * 3) & 3;
  17508. return stbiw__outfile(s, -1, -1, x, y, comp, 1, (void *)data, 0, pad,
  17509. "11 4 22 4" "4 44 22 444444",
  17510. 'B', 'M', 14 + 40 + (x * 3 + pad) * y, 0, 0, 14 + 40, // file header
  17511. 40, x, y, 1, 24, 0, 0, 0, 0, 0, 0); // bitmap header
  17512. }
  17513. STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
  17514. {
  17515. stbi__write_context s;
  17516. stbi__start_write_callbacks(&s, func, context);
  17517. return stbi_write_bmp_core(&s, x, y, comp, data);
  17518. }
  17519. #ifndef STBI_WRITE_NO_STDIO
  17520. STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
  17521. {
  17522. stbi__write_context s;
  17523. if (stbi__start_write_file(&s, filename))
  17524. {
  17525. int r = stbi_write_bmp_core(&s, x, y, comp, data);
  17526. stbi__end_write_file(&s);
  17527. return r;
  17528. }
  17529. else
  17530. return 0;
  17531. }
  17532. #endif //!STBI_WRITE_NO_STDIO
  17533. static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
  17534. {
  17535. int has_alpha = (comp == 2 || comp == 4);
  17536. int colorbytes = has_alpha ? comp - 1 : comp;
  17537. int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
  17538. if (y < 0 || x < 0)
  17539. return 0;
  17540. if (!stbi_write_tga_with_rle)
  17541. {
  17542. return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *)data, has_alpha, 0,
  17543. "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
  17544. }
  17545. else
  17546. {
  17547. int i, j, k;
  17548. int jend, jdir;
  17549. stbiw__writef(s, "111 221 2222 11", 0, 0, format + 8, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
  17550. if (stbi__flip_vertically_on_write)
  17551. {
  17552. j = 0;
  17553. jend = y;
  17554. jdir = 1;
  17555. }
  17556. else
  17557. {
  17558. j = y - 1;
  17559. jend = -1;
  17560. jdir = -1;
  17561. }
  17562. for (; j != jend; j += jdir)
  17563. {
  17564. unsigned char *row = (unsigned char *)data + j * x * comp;
  17565. int len;
  17566. for (i = 0; i < x; i += len)
  17567. {
  17568. unsigned char *begin = row + i * comp;
  17569. int diff = 1;
  17570. len = 1;
  17571. if (i < x - 1)
  17572. {
  17573. ++len;
  17574. diff = memcmp(begin, row + (i + 1) * comp, comp);
  17575. if (diff)
  17576. {
  17577. const unsigned char *prev = begin;
  17578. for (k = i + 2; k < x && len < 128; ++k)
  17579. {
  17580. if (memcmp(prev, row + k * comp, comp))
  17581. {
  17582. prev += comp;
  17583. ++len;
  17584. }
  17585. else
  17586. {
  17587. --len;
  17588. break;
  17589. }
  17590. }
  17591. }
  17592. else
  17593. {
  17594. for (k = i + 2; k < x && len < 128; ++k)
  17595. {
  17596. if (!memcmp(begin, row + k * comp, comp))
  17597. {
  17598. ++len;
  17599. }
  17600. else
  17601. {
  17602. break;
  17603. }
  17604. }
  17605. }
  17606. }
  17607. if (diff)
  17608. {
  17609. unsigned char header = STBIW_UCHAR(len - 1);
  17610. s->func(s->context, &header, 1);
  17611. for (k = 0; k < len; ++k)
  17612. {
  17613. stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
  17614. }
  17615. }
  17616. else
  17617. {
  17618. unsigned char header = STBIW_UCHAR(len - 129);
  17619. s->func(s->context, &header, 1);
  17620. stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
  17621. }
  17622. }
  17623. }
  17624. }
  17625. return 1;
  17626. }
  17627. STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
  17628. {
  17629. stbi__write_context s;
  17630. stbi__start_write_callbacks(&s, func, context);
  17631. return stbi_write_tga_core(&s, x, y, comp, (void *)data);
  17632. }
  17633. #ifndef STBI_WRITE_NO_STDIO
  17634. STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
  17635. {
  17636. stbi__write_context s;
  17637. if (stbi__start_write_file(&s, filename))
  17638. {
  17639. int r = stbi_write_tga_core(&s, x, y, comp, (void *)data);
  17640. stbi__end_write_file(&s);
  17641. return r;
  17642. }
  17643. else
  17644. return 0;
  17645. }
  17646. #endif
  17647. // *************************************************************************************************
  17648. // Radiance RGBE HDR writer
  17649. // by Baldur Karlsson
  17650. #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
  17651. static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
  17652. {
  17653. int exponent;
  17654. float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
  17655. if (maxcomp < 1e-32f)
  17656. {
  17657. rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
  17658. }
  17659. else
  17660. {
  17661. float normalize = (float)frexp(maxcomp, &exponent) * 256.0f / maxcomp;
  17662. rgbe[0] = (unsigned char)(linear[0] * normalize);
  17663. rgbe[1] = (unsigned char)(linear[1] * normalize);
  17664. rgbe[2] = (unsigned char)(linear[2] * normalize);
  17665. rgbe[3] = (unsigned char)(exponent + 128);
  17666. }
  17667. }
  17668. static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
  17669. {
  17670. unsigned char lengthbyte = STBIW_UCHAR(length + 128);
  17671. STBIW_ASSERT(length + 128 <= 255);
  17672. s->func(s->context, &lengthbyte, 1);
  17673. s->func(s->context, &databyte, 1);
  17674. }
  17675. static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
  17676. {
  17677. unsigned char lengthbyte = STBIW_UCHAR(length);
  17678. STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
  17679. s->func(s->context, &lengthbyte, 1);
  17680. s->func(s->context, data, length);
  17681. }
  17682. static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
  17683. {
  17684. unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
  17685. unsigned char rgbe[4];
  17686. float linear[3];
  17687. int x;
  17688. scanlineheader[2] = (width & 0xff00) >> 8;
  17689. scanlineheader[3] = (width & 0x00ff);
  17690. /* skip RLE for images too small or large */
  17691. if (width < 8 || width >= 32768)
  17692. {
  17693. for (x = 0; x < width; x++)
  17694. {
  17695. switch (ncomp)
  17696. {
  17697. case 4: /* fallthrough */
  17698. case 3: linear[2] = scanline[x * ncomp + 2];
  17699. linear[1] = scanline[x * ncomp + 1];
  17700. linear[0] = scanline[x * ncomp + 0];
  17701. break;
  17702. default:
  17703. linear[0] = linear[1] = linear[2] = scanline[x * ncomp + 0];
  17704. break;
  17705. }
  17706. stbiw__linear_to_rgbe(rgbe, linear);
  17707. s->func(s->context, rgbe, 4);
  17708. }
  17709. }
  17710. else
  17711. {
  17712. int c, r;
  17713. /* encode into scratch buffer */
  17714. for (x = 0; x < width; x++)
  17715. {
  17716. switch (ncomp)
  17717. {
  17718. case 4: /* fallthrough */
  17719. case 3: linear[2] = scanline[x * ncomp + 2];
  17720. linear[1] = scanline[x * ncomp + 1];
  17721. linear[0] = scanline[x * ncomp + 0];
  17722. break;
  17723. default:
  17724. linear[0] = linear[1] = linear[2] = scanline[x * ncomp + 0];
  17725. break;
  17726. }
  17727. stbiw__linear_to_rgbe(rgbe, linear);
  17728. scratch[x + width * 0] = rgbe[0];
  17729. scratch[x + width * 1] = rgbe[1];
  17730. scratch[x + width * 2] = rgbe[2];
  17731. scratch[x + width * 3] = rgbe[3];
  17732. }
  17733. s->func(s->context, scanlineheader, 4);
  17734. /* RLE each component separately */
  17735. for (c = 0; c < 4; c++)
  17736. {
  17737. unsigned char *comp = &scratch[width * c];
  17738. x = 0;
  17739. while (x < width)
  17740. {
  17741. // find first run
  17742. r = x;
  17743. while (r + 2 < width)
  17744. {
  17745. if (comp[r] == comp[r + 1] && comp[r] == comp[r + 2])
  17746. break;
  17747. ++r;
  17748. }
  17749. if (r + 2 >= width)
  17750. r = width;
  17751. // dump up to first run
  17752. while (x < r)
  17753. {
  17754. int len = r - x;
  17755. if (len > 128) len = 128;
  17756. stbiw__write_dump_data(s, len, &comp[x]);
  17757. x += len;
  17758. }
  17759. // if there's a run, output it
  17760. if (r + 2 < width)
  17761. { // same test as what we break out of in search loop, so only true if we break'd
  17762. // find next byte after run
  17763. while (r < width && comp[r] == comp[x])
  17764. ++r;
  17765. // output run up to r
  17766. while (x < r)
  17767. {
  17768. int len = r - x;
  17769. if (len > 127) len = 127;
  17770. stbiw__write_run_data(s, len, comp[x]);
  17771. x += len;
  17772. }
  17773. }
  17774. }
  17775. }
  17776. }
  17777. }
  17778. static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
  17779. {
  17780. if (y <= 0 || x <= 0 || data == NULL)
  17781. return 0;
  17782. else
  17783. {
  17784. // Each component is stored separately. Allocate scratch space for full output scanline.
  17785. unsigned char *scratch = (unsigned char *)STBIW_MALLOC(x * 4);
  17786. int i, len;
  17787. char buffer[128];
  17788. char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
  17789. s->func(s->context, header, sizeof(header) - 1);
  17790. #ifdef STBI_MSC_SECURE_CRT
  17791. len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
  17792. #else
  17793. len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
  17794. #endif
  17795. s->func(s->context, buffer, len);
  17796. for (i = 0; i < y; i++)
  17797. stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp * x * (stbi__flip_vertically_on_write ? y - 1 - i : i));
  17798. STBIW_FREE(scratch);
  17799. return 1;
  17800. }
  17801. }
  17802. STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
  17803. {
  17804. stbi__write_context s;
  17805. stbi__start_write_callbacks(&s, func, context);
  17806. return stbi_write_hdr_core(&s, x, y, comp, (float *)data);
  17807. }
  17808. #ifndef STBI_WRITE_NO_STDIO
  17809. STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
  17810. {
  17811. stbi__write_context s;
  17812. if (stbi__start_write_file(&s, filename))
  17813. {
  17814. int r = stbi_write_hdr_core(&s, x, y, comp, (float *)data);
  17815. stbi__end_write_file(&s);
  17816. return r;
  17817. }
  17818. else
  17819. return 0;
  17820. }
  17821. #endif // STBI_WRITE_NO_STDIO
  17822. //////////////////////////////////////////////////////////////////////////////
  17823. //
  17824. // PNG writer
  17825. //
  17826. #ifndef STBIW_ZLIB_COMPRESS
  17827. // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
  17828. #define stbiw__sbraw(a) ((int *) (a) - 2)
  17829. #define stbiw__sbm(a) stbiw__sbraw(a)[0]
  17830. #define stbiw__sbn(a) stbiw__sbraw(a)[1]
  17831. #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
  17832. #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
  17833. #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
  17834. #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
  17835. #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
  17836. #define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
  17837. static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
  17838. {
  17839. int m = *arr ? 2 * stbiw__sbm(*arr) + increment : increment + 1;
  17840. void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr) * itemsize + sizeof(int) * 2) : 0, itemsize * m + sizeof(int) * 2);
  17841. STBIW_ASSERT(p);
  17842. if (p)
  17843. {
  17844. if (!*arr) ((int *)p)[1] = 0;
  17845. *arr = (void *)((int *)p + 2);
  17846. stbiw__sbm(*arr) = m;
  17847. }
  17848. return *arr;
  17849. }
  17850. static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
  17851. {
  17852. while (*bitcount >= 8)
  17853. {
  17854. stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
  17855. *bitbuffer >>= 8;
  17856. *bitcount -= 8;
  17857. }
  17858. return data;
  17859. }
  17860. static int stbiw__zlib_bitrev(int code, int codebits)
  17861. {
  17862. int res = 0;
  17863. while (codebits--)
  17864. {
  17865. res = (res << 1) | (code & 1);
  17866. code >>= 1;
  17867. }
  17868. return res;
  17869. }
  17870. static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
  17871. {
  17872. int i;
  17873. for (i = 0; i < limit && i < 258; ++i)
  17874. if (a[i] != b[i]) break;
  17875. return i;
  17876. }
  17877. static unsigned int stbiw__zhash(unsigned char *data)
  17878. {
  17879. stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
  17880. hash ^= hash << 3;
  17881. hash += hash >> 5;
  17882. hash ^= hash << 4;
  17883. hash += hash >> 17;
  17884. hash ^= hash << 25;
  17885. hash += hash >> 6;
  17886. return hash;
  17887. }
  17888. #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
  17889. #define stbiw__zlib_add(code,codebits) \
  17890. (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
  17891. #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
  17892. // default huffman tables
  17893. #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
  17894. #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
  17895. #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
  17896. #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
  17897. #define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
  17898. #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
  17899. #define stbiw__ZHASH 16384
  17900. #endif // STBIW_ZLIB_COMPRESS
  17901. STBIWDEF unsigned char *stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
  17902. {
  17903. #ifdef STBIW_ZLIB_COMPRESS
  17904. // user provided a zlib compress implementation, use that
  17905. return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
  17906. #else // use builtin
  17907. static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
  17908. static unsigned char lengtheb[] = { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
  17909. static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
  17910. static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
  17911. unsigned int bitbuf = 0;
  17912. int i, j, bitcount = 0;
  17913. unsigned char *out = NULL;
  17914. unsigned char ***hash_table = (unsigned char ***)STBIW_MALLOC(stbiw__ZHASH * sizeof(char **));
  17915. if (hash_table == NULL)
  17916. return NULL;
  17917. if (quality < 5) quality = 5;
  17918. stbiw__sbpush(out, 0x78); // DEFLATE 32K window
  17919. stbiw__sbpush(out, 0x5e); // FLEVEL = 1
  17920. stbiw__zlib_add(1, 1); // BFINAL = 1
  17921. stbiw__zlib_add(1, 2); // BTYPE = 1 -- fixed huffman
  17922. for (i = 0; i < stbiw__ZHASH; ++i)
  17923. hash_table[i] = NULL;
  17924. i = 0;
  17925. while (i < data_len - 3)
  17926. {
  17927. // hash next 3 bytes of data to be compressed
  17928. int h = stbiw__zhash(data + i) & (stbiw__ZHASH - 1), best = 3;
  17929. unsigned char *bestloc = 0;
  17930. unsigned char **hlist = hash_table[h];
  17931. int n = stbiw__sbcount(hlist);
  17932. for (j = 0; j < n; ++j)
  17933. {
  17934. if (hlist[j] - data > i - 32768)
  17935. { // if entry lies within window
  17936. int d = stbiw__zlib_countm(hlist[j], data + i, data_len - i);
  17937. if (d >= best) best = d, bestloc = hlist[j];
  17938. }
  17939. }
  17940. // when hash table entry is too long, delete half the entries
  17941. if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2 * quality)
  17942. {
  17943. STBIW_MEMMOVE(hash_table[h], hash_table[h] + quality, sizeof(hash_table[h][0]) * quality);
  17944. stbiw__sbn(hash_table[h]) = quality;
  17945. }
  17946. stbiw__sbpush(hash_table[h], data + i);
  17947. if (bestloc)
  17948. {
  17949. // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
  17950. h = stbiw__zhash(data + i + 1) & (stbiw__ZHASH - 1);
  17951. hlist = hash_table[h];
  17952. n = stbiw__sbcount(hlist);
  17953. for (j = 0; j < n; ++j)
  17954. {
  17955. if (hlist[j] - data > i - 32767)
  17956. {
  17957. int e = stbiw__zlib_countm(hlist[j], data + i + 1, data_len - i - 1);
  17958. if (e > best)
  17959. { // if next match is better, bail on current match
  17960. bestloc = NULL;
  17961. break;
  17962. }
  17963. }
  17964. }
  17965. }
  17966. if (bestloc)
  17967. {
  17968. int d = (int)(data + i - bestloc); // distance back
  17969. STBIW_ASSERT(d <= 32767 && best <= 258);
  17970. for (j = 0; best > lengthc[j + 1] - 1; ++j);
  17971. stbiw__zlib_huff(j + 257);
  17972. if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
  17973. for (j = 0; d > distc[j + 1] - 1; ++j);
  17974. stbiw__zlib_add(stbiw__zlib_bitrev(j, 5), 5);
  17975. if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
  17976. i += best;
  17977. }
  17978. else
  17979. {
  17980. stbiw__zlib_huffb(data[i]);
  17981. ++i;
  17982. }
  17983. }
  17984. // write out final bytes
  17985. for (; i < data_len; ++i)
  17986. stbiw__zlib_huffb(data[i]);
  17987. stbiw__zlib_huff(256); // end of block
  17988. // pad with 0 bits to byte boundary
  17989. while (bitcount)
  17990. stbiw__zlib_add(0, 1);
  17991. for (i = 0; i < stbiw__ZHASH; ++i)
  17992. (void)stbiw__sbfree(hash_table[i]);
  17993. STBIW_FREE(hash_table);
  17994. {
  17995. // compute adler32 on input
  17996. unsigned int s1 = 1, s2 = 0;
  17997. int blocklen = (int)(data_len % 5552);
  17998. j = 0;
  17999. while (j < data_len)
  18000. {
  18001. for (i = 0; i < blocklen; ++i) s1 += data[j + i], s2 += s1;
  18002. s1 %= 65521, s2 %= 65521;
  18003. j += blocklen;
  18004. blocklen = 5552;
  18005. }
  18006. stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
  18007. stbiw__sbpush(out, STBIW_UCHAR(s2));
  18008. stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
  18009. stbiw__sbpush(out, STBIW_UCHAR(s1));
  18010. }
  18011. *out_len = stbiw__sbn(out);
  18012. // make returned pointer freeable
  18013. STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
  18014. return (unsigned char *)stbiw__sbraw(out);
  18015. #endif // STBIW_ZLIB_COMPRESS
  18016. }
  18017. static unsigned int stbiw__crc32(unsigned char *buffer, int len)
  18018. {
  18019. #ifdef STBIW_CRC32
  18020. return STBIW_CRC32(buffer, len);
  18021. #else
  18022. static unsigned int crc_table[256] =
  18023. {
  18024. 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
  18025. 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
  18026. 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  18027. 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
  18028. 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
  18029. 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  18030. 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
  18031. 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
  18032. 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  18033. 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
  18034. 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
  18035. 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  18036. 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
  18037. 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
  18038. 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  18039. 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
  18040. 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
  18041. 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  18042. 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
  18043. 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
  18044. 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  18045. 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
  18046. 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
  18047. 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  18048. 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
  18049. 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
  18050. 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  18051. 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
  18052. 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
  18053. 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  18054. 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
  18055. 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
  18056. };
  18057. unsigned int crc = ~0u;
  18058. int i;
  18059. for (i = 0; i < len; ++i)
  18060. crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
  18061. return ~crc;
  18062. #endif
  18063. }
  18064. #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
  18065. #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
  18066. #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
  18067. static void stbiw__wpcrc(unsigned char **data, int len)
  18068. {
  18069. unsigned int crc = stbiw__crc32(*data - len - 4, len + 4);
  18070. stbiw__wp32(*data, crc);
  18071. }
  18072. static unsigned char stbiw__paeth(int a, int b, int c)
  18073. {
  18074. int p = a + b - c, pa = abs(p - a), pb = abs(p - b), pc = abs(p - c);
  18075. if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
  18076. if (pb <= pc) return STBIW_UCHAR(b);
  18077. return STBIW_UCHAR(c);
  18078. }
  18079. // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
  18080. static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer)
  18081. {
  18082. static int mapping[] = { 0,1,2,3,4 };
  18083. static int firstmap[] = { 0,1,0,5,6 };
  18084. int *mymap = (y != 0) ? mapping : firstmap;
  18085. int i;
  18086. int type = mymap[filter_type];
  18087. unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height - 1 - y : y);
  18088. int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
  18089. if (type == 0)
  18090. {
  18091. memcpy(line_buffer, z, width * n);
  18092. return;
  18093. }
  18094. // first loop isn't optimized since it's just one pixel
  18095. for (i = 0; i < n; ++i)
  18096. {
  18097. switch (type)
  18098. {
  18099. case 1: line_buffer[i] = z[i]; break;
  18100. case 2: line_buffer[i] = z[i] - z[i - signed_stride]; break;
  18101. case 3: line_buffer[i] = z[i] - (z[i - signed_stride] >> 1); break;
  18102. case 4: line_buffer[i] = (signed char)(z[i] - stbiw__paeth(0, z[i - signed_stride], 0)); break;
  18103. case 5: line_buffer[i] = z[i]; break;
  18104. case 6: line_buffer[i] = z[i]; break;
  18105. }
  18106. }
  18107. switch (type)
  18108. {
  18109. case 1: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - z[i - n]; break;
  18110. case 2: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - z[i - signed_stride]; break;
  18111. case 3: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - ((z[i - n] + z[i - signed_stride]) >> 1); break;
  18112. case 4: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i - n], z[i - signed_stride], z[i - signed_stride - n]); break;
  18113. case 5: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - (z[i - n] >> 1); break;
  18114. case 6: for (i = n; i < width * n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i - n], 0, 0); break;
  18115. }
  18116. }
  18117. STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
  18118. {
  18119. int force_filter = stbi_write_force_png_filter;
  18120. int ctype[5] = { -1, 0, 4, 2, 6 };
  18121. unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
  18122. unsigned char *out, *o, *filt, *zlib;
  18123. signed char *line_buffer;
  18124. int j, zlen;
  18125. if (stride_bytes == 0)
  18126. stride_bytes = x * n;
  18127. if (force_filter >= 5)
  18128. {
  18129. force_filter = -1;
  18130. }
  18131. filt = (unsigned char *)STBIW_MALLOC((x * n + 1) * y); if (!filt) return 0;
  18132. line_buffer = (signed char *)STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
  18133. for (j = 0; j < y; ++j)
  18134. {
  18135. int filter_type;
  18136. if (force_filter > -1)
  18137. {
  18138. filter_type = force_filter;
  18139. stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
  18140. }
  18141. else
  18142. { // Estimate the best filter by running through all of them:
  18143. int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
  18144. for (filter_type = 0; filter_type < 5; filter_type++)
  18145. {
  18146. stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
  18147. // Estimate the entropy of the line using this filter; the less, the better.
  18148. est = 0;
  18149. for (i = 0; i < x * n; ++i)
  18150. {
  18151. est += abs((signed char)line_buffer[i]);
  18152. }
  18153. if (est < best_filter_val)
  18154. {
  18155. best_filter_val = est;
  18156. best_filter = filter_type;
  18157. }
  18158. }
  18159. if (filter_type != best_filter)
  18160. { // If the last iteration already got us the best filter, don't redo it
  18161. stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
  18162. filter_type = best_filter;
  18163. }
  18164. }
  18165. // when we get here, filter_type contains the filter type, and line_buffer contains the data
  18166. filt[j * (x * n + 1)] = (unsigned char)filter_type;
  18167. STBIW_MEMMOVE(filt + j * (x * n + 1) + 1, line_buffer, x * n);
  18168. }
  18169. STBIW_FREE(line_buffer);
  18170. zlib = stbi_zlib_compress(filt, y * (x * n + 1), &zlen, stbi_write_png_compression_level);
  18171. STBIW_FREE(filt);
  18172. if (!zlib) return 0;
  18173. // each tag requires 12 bytes of overhead
  18174. out = (unsigned char *)STBIW_MALLOC(8 + 12 + 13 + 12 + zlen + 12);
  18175. if (!out) return 0;
  18176. *out_len = 8 + 12 + 13 + 12 + zlen + 12;
  18177. o = out;
  18178. STBIW_MEMMOVE(o, sig, 8); o += 8;
  18179. stbiw__wp32(o, 13); // header length
  18180. stbiw__wptag(o, "IHDR");
  18181. stbiw__wp32(o, x);
  18182. stbiw__wp32(o, y);
  18183. *o++ = 8;
  18184. *o++ = STBIW_UCHAR(ctype[n]);
  18185. *o++ = 0;
  18186. *o++ = 0;
  18187. *o++ = 0;
  18188. stbiw__wpcrc(&o, 13);
  18189. stbiw__wp32(o, zlen);
  18190. stbiw__wptag(o, "IDAT");
  18191. STBIW_MEMMOVE(o, zlib, zlen);
  18192. o += zlen;
  18193. STBIW_FREE(zlib);
  18194. stbiw__wpcrc(&o, zlen);
  18195. stbiw__wp32(o, 0);
  18196. stbiw__wptag(o, "IEND");
  18197. stbiw__wpcrc(&o, 0);
  18198. STBIW_ASSERT(o == out + *out_len);
  18199. return out;
  18200. }
  18201. #ifndef STBI_WRITE_NO_STDIO
  18202. STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
  18203. {
  18204. FILE *f;
  18205. int len;
  18206. unsigned char *png = stbi_write_png_to_mem((const unsigned char *)data, stride_bytes, x, y, comp, &len);
  18207. if (png == NULL) return 0;
  18208. f = stbiw__fopen(filename, "wb");
  18209. if (!f) { STBIW_FREE(png); return 0; }
  18210. fwrite(png, 1, len, f);
  18211. fclose(f);
  18212. STBIW_FREE(png);
  18213. return 1;
  18214. }
  18215. #endif
  18216. STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
  18217. {
  18218. int len;
  18219. unsigned char *png = stbi_write_png_to_mem((const unsigned char *)data, stride_bytes, x, y, comp, &len);
  18220. if (png == NULL) return 0;
  18221. func(context, png, len);
  18222. STBIW_FREE(png);
  18223. return 1;
  18224. }
  18225. /* ***************************************************************************
  18226. *
  18227. * JPEG writer
  18228. *
  18229. * This is based on Jon Olick's jo_jpeg.cpp:
  18230. * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html
  18231. */
  18232. static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,
  18233. 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 };
  18234. static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs)
  18235. {
  18236. int bitBuf = *bitBufP, bitCnt = *bitCntP;
  18237. bitCnt += bs[1];
  18238. bitBuf |= bs[0] << (24 - bitCnt);
  18239. while (bitCnt >= 8)
  18240. {
  18241. unsigned char c = (bitBuf >> 16) & 255;
  18242. stbiw__putc(s, c);
  18243. if (c == 255)
  18244. {
  18245. stbiw__putc(s, 0);
  18246. }
  18247. bitBuf <<= 8;
  18248. bitCnt -= 8;
  18249. }
  18250. *bitBufP = bitBuf;
  18251. *bitCntP = bitCnt;
  18252. }
  18253. static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p)
  18254. {
  18255. float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
  18256. float z1, z2, z3, z4, z5, z11, z13;
  18257. float tmp0 = d0 + d7;
  18258. float tmp7 = d0 - d7;
  18259. float tmp1 = d1 + d6;
  18260. float tmp6 = d1 - d6;
  18261. float tmp2 = d2 + d5;
  18262. float tmp5 = d2 - d5;
  18263. float tmp3 = d3 + d4;
  18264. float tmp4 = d3 - d4;
  18265. // Even part
  18266. float tmp10 = tmp0 + tmp3; // phase 2
  18267. float tmp13 = tmp0 - tmp3;
  18268. float tmp11 = tmp1 + tmp2;
  18269. float tmp12 = tmp1 - tmp2;
  18270. d0 = tmp10 + tmp11; // phase 3
  18271. d4 = tmp10 - tmp11;
  18272. z1 = (tmp12 + tmp13) * 0.707106781f; // c4
  18273. d2 = tmp13 + z1; // phase 5
  18274. d6 = tmp13 - z1;
  18275. // Odd part
  18276. tmp10 = tmp4 + tmp5; // phase 2
  18277. tmp11 = tmp5 + tmp6;
  18278. tmp12 = tmp6 + tmp7;
  18279. // The rotator is modified from fig 4-8 to avoid extra negations.
  18280. z5 = (tmp10 - tmp12) * 0.382683433f; // c6
  18281. z2 = tmp10 * 0.541196100f + z5; // c2-c6
  18282. z4 = tmp12 * 1.306562965f + z5; // c2+c6
  18283. z3 = tmp11 * 0.707106781f; // c4
  18284. z11 = tmp7 + z3; // phase 5
  18285. z13 = tmp7 - z3;
  18286. *d5p = z13 + z2; // phase 6
  18287. *d3p = z13 - z2;
  18288. *d1p = z11 + z4;
  18289. *d7p = z11 - z4;
  18290. *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6;
  18291. }
  18292. static void stbiw__jpg_calcBits(int val, unsigned short bits[2])
  18293. {
  18294. int tmp1 = val < 0 ? -val : val;
  18295. val = val < 0 ? val - 1 : val;
  18296. bits[1] = 1;
  18297. while (tmp1 >>= 1)
  18298. {
  18299. ++bits[1];
  18300. }
  18301. bits[0] = val & ((1 << bits[1]) - 1);
  18302. }
  18303. static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2])
  18304. {
  18305. const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
  18306. const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
  18307. int dataOff, i, diff, end0pos;
  18308. int DU[64];
  18309. // DCT rows
  18310. for (dataOff = 0; dataOff < 64; dataOff += 8)
  18311. {
  18312. stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff + 1], &CDU[dataOff + 2], &CDU[dataOff + 3], &CDU[dataOff + 4], &CDU[dataOff + 5], &CDU[dataOff + 6], &CDU[dataOff + 7]);
  18313. }
  18314. // DCT columns
  18315. for (dataOff = 0; dataOff < 8; ++dataOff)
  18316. {
  18317. stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff + 8], &CDU[dataOff + 16], &CDU[dataOff + 24], &CDU[dataOff + 32], &CDU[dataOff + 40], &CDU[dataOff + 48], &CDU[dataOff + 56]);
  18318. }
  18319. // Quantize/descale/zigzag the coefficients
  18320. for (i = 0; i < 64; ++i)
  18321. {
  18322. float v = CDU[i] * fdtbl[i];
  18323. // DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
  18324. // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
  18325. DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
  18326. }
  18327. // Encode DC
  18328. diff = DU[0] - DC;
  18329. if (diff == 0)
  18330. {
  18331. stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
  18332. }
  18333. else
  18334. {
  18335. unsigned short bits[2];
  18336. stbiw__jpg_calcBits(diff, bits);
  18337. stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
  18338. stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
  18339. }
  18340. // Encode ACs
  18341. end0pos = 63;
  18342. for (; (end0pos > 0) && (DU[end0pos] == 0); --end0pos)
  18343. {
  18344. }
  18345. // end0pos = first element in reverse order !=0
  18346. if (end0pos == 0)
  18347. {
  18348. stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
  18349. return DU[0];
  18350. }
  18351. for (i = 1; i <= end0pos; ++i)
  18352. {
  18353. int startpos = i;
  18354. int nrzeroes;
  18355. unsigned short bits[2];
  18356. for (; DU[i] == 0 && i <= end0pos; ++i)
  18357. {
  18358. }
  18359. nrzeroes = i - startpos;
  18360. if (nrzeroes >= 16)
  18361. {
  18362. int lng = nrzeroes >> 4;
  18363. int nrmarker;
  18364. for (nrmarker = 1; nrmarker <= lng; ++nrmarker)
  18365. stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
  18366. nrzeroes &= 15;
  18367. }
  18368. stbiw__jpg_calcBits(DU[i], bits);
  18369. stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes << 4) + bits[1]]);
  18370. stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
  18371. }
  18372. if (end0pos != 63)
  18373. {
  18374. stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
  18375. }
  18376. return DU[0];
  18377. }
  18378. static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void *data, int quality)
  18379. {
  18380. // Constants that don't pollute global namespace
  18381. static const unsigned char std_dc_luminance_nrcodes[] = { 0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0 };
  18382. static const unsigned char std_dc_luminance_values[] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
  18383. static const unsigned char std_ac_luminance_nrcodes[] = { 0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d };
  18384. static const unsigned char std_ac_luminance_values[] = {
  18385. 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
  18386. 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
  18387. 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
  18388. 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
  18389. 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
  18390. 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
  18391. 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
  18392. };
  18393. static const unsigned char std_dc_chrominance_nrcodes[] = { 0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0 };
  18394. static const unsigned char std_dc_chrominance_values[] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
  18395. static const unsigned char std_ac_chrominance_nrcodes[] = { 0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77 };
  18396. static const unsigned char std_ac_chrominance_values[] = {
  18397. 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
  18398. 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
  18399. 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
  18400. 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
  18401. 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
  18402. 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
  18403. 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
  18404. };
  18405. // Huffman tables
  18406. static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9} };
  18407. static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11} };
  18408. static const unsigned short YAC_HT[256][2] = {
  18409. {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18410. {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18411. {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18412. {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18413. {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18414. {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18415. {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18416. {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18417. {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18418. {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18419. {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18420. {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18421. {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18422. {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18423. {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0},
  18424. {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
  18425. };
  18426. static const unsigned short UVAC_HT[256][2] = {
  18427. {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18428. {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18429. {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18430. {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18431. {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18432. {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18433. {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18434. {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18435. {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18436. {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18437. {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18438. {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18439. {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18440. {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
  18441. {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0},
  18442. {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
  18443. };
  18444. static const int YQT[] = { 16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,
  18445. 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99 };
  18446. static const int UVQT[] = { 17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
  18447. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99 };
  18448. static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
  18449. 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
  18450. int row, col, i, k;
  18451. float fdtbl_Y[64], fdtbl_UV[64];
  18452. unsigned char YTable[64], UVTable[64];
  18453. if (!data || !width || !height || comp > 4 || comp < 1)
  18454. {
  18455. return 0;
  18456. }
  18457. quality = quality ? quality : 90;
  18458. quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
  18459. quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
  18460. for (i = 0; i < 64; ++i)
  18461. {
  18462. int uvti, yti = (YQT[i] * quality + 50) / 100;
  18463. YTable[stbiw__jpg_ZigZag[i]] = (unsigned char)(yti < 1 ? 1 : yti > 255 ? 255 : yti);
  18464. uvti = (UVQT[i] * quality + 50) / 100;
  18465. UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char)(uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
  18466. }
  18467. for (row = 0, k = 0; row < 8; ++row)
  18468. {
  18469. for (col = 0; col < 8; ++col, ++k)
  18470. {
  18471. fdtbl_Y[k] = 1 / (YTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
  18472. fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
  18473. }
  18474. }
  18475. // Write Headers
  18476. {
  18477. static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
  18478. static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
  18479. const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height >> 8),STBIW_UCHAR(height),(unsigned char)(width >> 8),STBIW_UCHAR(width),
  18480. 3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
  18481. s->func(s->context, (void *)head0, sizeof(head0));
  18482. s->func(s->context, (void *)YTable, sizeof(YTable));
  18483. stbiw__putc(s, 1);
  18484. s->func(s->context, UVTable, sizeof(UVTable));
  18485. s->func(s->context, (void *)head1, sizeof(head1));
  18486. s->func(s->context, (void *)(std_dc_luminance_nrcodes + 1), sizeof(std_dc_luminance_nrcodes) - 1);
  18487. s->func(s->context, (void *)std_dc_luminance_values, sizeof(std_dc_luminance_values));
  18488. stbiw__putc(s, 0x10); // HTYACinfo
  18489. s->func(s->context, (void *)(std_ac_luminance_nrcodes + 1), sizeof(std_ac_luminance_nrcodes) - 1);
  18490. s->func(s->context, (void *)std_ac_luminance_values, sizeof(std_ac_luminance_values));
  18491. stbiw__putc(s, 1); // HTUDCinfo
  18492. s->func(s->context, (void *)(std_dc_chrominance_nrcodes + 1), sizeof(std_dc_chrominance_nrcodes) - 1);
  18493. s->func(s->context, (void *)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
  18494. stbiw__putc(s, 0x11); // HTUACinfo
  18495. s->func(s->context, (void *)(std_ac_chrominance_nrcodes + 1), sizeof(std_ac_chrominance_nrcodes) - 1);
  18496. s->func(s->context, (void *)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
  18497. s->func(s->context, (void *)head2, sizeof(head2));
  18498. }
  18499. // Encode 8x8 macroblocks
  18500. {
  18501. static const unsigned short fillBits[] = { 0x7F, 7 };
  18502. const unsigned char *imageData = (const unsigned char *)data;
  18503. int DCY = 0, DCU = 0, DCV = 0;
  18504. int bitBuf = 0, bitCnt = 0;
  18505. // comp == 2 is grey+alpha (alpha is ignored)
  18506. int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
  18507. int x, y, pos;
  18508. for (y = 0; y < height; y += 8)
  18509. {
  18510. for (x = 0; x < width; x += 8)
  18511. {
  18512. float YDU[64], UDU[64], VDU[64];
  18513. for (row = y, pos = 0; row < y + 8; ++row)
  18514. {
  18515. // row >= height => use last input row
  18516. int clamped_row = (row < height) ? row : height - 1;
  18517. int base_p = (stbi__flip_vertically_on_write ? (height - 1 - clamped_row) : clamped_row) * width * comp;
  18518. for (col = x; col < x + 8; ++col, ++pos)
  18519. {
  18520. float r, g, b;
  18521. // if col >= width => use pixel from last input column
  18522. int p = base_p + ((col < width) ? col : (width - 1)) * comp;
  18523. r = imageData[p + 0];
  18524. g = imageData[p + ofsG];
  18525. b = imageData[p + ofsB];
  18526. YDU[pos] = +0.29900f * r + 0.58700f * g + 0.11400f * b - 128;
  18527. UDU[pos] = -0.16874f * r - 0.33126f * g + 0.50000f * b;
  18528. VDU[pos] = +0.50000f * r - 0.41869f * g - 0.08131f * b;
  18529. }
  18530. }
  18531. DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
  18532. DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
  18533. DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
  18534. }
  18535. }
  18536. // Do the bit alignment of the EOI marker
  18537. stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
  18538. }
  18539. // EOI
  18540. stbiw__putc(s, 0xFF);
  18541. stbiw__putc(s, 0xD9);
  18542. return 1;
  18543. }
  18544. STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
  18545. {
  18546. stbi__write_context s;
  18547. stbi__start_write_callbacks(&s, func, context);
  18548. return stbi_write_jpg_core(&s, x, y, comp, (void *)data, quality);
  18549. }
  18550. #ifndef STBI_WRITE_NO_STDIO
  18551. STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
  18552. {
  18553. stbi__write_context s;
  18554. if (stbi__start_write_file(&s, filename))
  18555. {
  18556. int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
  18557. stbi__end_write_file(&s);
  18558. return r;
  18559. }
  18560. else
  18561. return 0;
  18562. }
  18563. #endif
  18564. #endif // STB_IMAGE_WRITE_IMPLEMENTATION
  18565. /* Revision history
  18566. 1.10 (2019-02-07)
  18567. support utf8 filenames in Windows; fix warnings and platform ifdefs
  18568. 1.09 (2018-02-11)
  18569. fix typo in zlib quality API, improve STB_I_W_STATIC in C++
  18570. 1.08 (2018-01-29)
  18571. add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
  18572. 1.07 (2017-07-24)
  18573. doc fix
  18574. 1.06 (2017-07-23)
  18575. writing JPEG (using Jon Olick's code)
  18576. 1.05 ???
  18577. 1.04 (2017-03-03)
  18578. monochrome BMP expansion
  18579. 1.03 ???
  18580. 1.02 (2016-04-02)
  18581. avoid allocating large structures on the stack
  18582. 1.01 (2016-01-16)
  18583. STBIW_REALLOC_SIZED: support allocators with no realloc support
  18584. avoid race-condition in crc initialization
  18585. minor compile issues
  18586. 1.00 (2015-09-14)
  18587. installable file IO function
  18588. 0.99 (2015-09-13)
  18589. warning fixes; TGA rle support
  18590. 0.98 (2015-04-08)
  18591. added STBIW_MALLOC, STBIW_ASSERT etc
  18592. 0.97 (2015-01-18)
  18593. fixed HDR asserts, rewrote HDR rle logic
  18594. 0.96 (2015-01-17)
  18595. add HDR output
  18596. fix monochrome BMP
  18597. 0.95 (2014-08-17)
  18598. add monochrome TGA output
  18599. 0.94 (2014-05-31)
  18600. rename private functions to avoid conflicts with stb_image.h
  18601. 0.93 (2014-05-27)
  18602. warning fixes
  18603. 0.92 (2010-08-01)
  18604. casts to unsigned char to fix warnings
  18605. 0.91 (2010-07-17)
  18606. first public release
  18607. 0.90 first internal release
  18608. */
  18609. /*
  18610. ------------------------------------------------------------------------------
  18611. This software is available under 2 licenses -- choose whichever you prefer.
  18612. ------------------------------------------------------------------------------
  18613. ALTERNATIVE A - MIT License
  18614. Copyright (c) 2017 Sean Barrett
  18615. Permission is hereby granted, free of charge, to any person obtaining a copy of
  18616. this software and associated documentation files (the "Software"), to deal in
  18617. the Software without restriction, including without limitation the rights to
  18618. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  18619. of the Software, and to permit persons to whom the Software is furnished to do
  18620. so, subject to the following conditions:
  18621. The above copyright notice and this permission notice shall be included in all
  18622. copies or substantial portions of the Software.
  18623. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18624. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18625. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18626. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18627. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18628. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18629. SOFTWARE.
  18630. ------------------------------------------------------------------------------
  18631. ALTERNATIVE B - Public Domain (www.unlicense.org)
  18632. This is free and unencumbered software released into the public domain.
  18633. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  18634. software, either in source code form or as a compiled binary, for any purpose,
  18635. commercial or non-commercial, and by any means.
  18636. In jurisdictions that recognize copyright laws, the author or authors of this
  18637. software dedicate any and all copyright interest in the software to the public
  18638. domain. We make this dedication for the benefit of the public at large and to
  18639. the detriment of our heirs and successors. We intend this dedication to be an
  18640. overt act of relinquishment in perpetuity of all present and future rights to
  18641. this software under copyright law.
  18642. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18643. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18644. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18645. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18646. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18647. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18648. ------------------------------------------------------------------------------
  18649. */
  18650. //
  18651. // Header-only tiny glTF 2.0 loader and serializer.
  18652. //
  18653. //
  18654. // The MIT License (MIT)
  18655. //
  18656. // Copyright (c) 2015 - 2020 Syoyo Fujita, Aurélien Chatelain and many
  18657. // contributors.
  18658. //
  18659. // Permission is hereby granted, free of charge, to any person obtaining a copy
  18660. // of this software and associated documentation files (the "Software"), to deal
  18661. // in the Software without restriction, including without limitation the rights
  18662. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18663. // copies of the Software, and to permit persons to whom the Software is
  18664. // furnished to do so, subject to the following conditions:
  18665. //
  18666. // The above copyright notice and this permission notice shall be included in
  18667. // all copies or substantial portions of the Software.
  18668. //
  18669. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18670. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18671. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18672. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18673. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18674. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18675. // THE SOFTWARE.
  18676. // Version:
  18677. // - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
  18678. // - v2.4.3 Fix null object output when when material has all default parameters.
  18679. // - v2.4.2 Decode percent-encoded URI.
  18680. // - v2.4.1 Fix some glTF object class does not have `extensions` and/or
  18681. // `extras` property.
  18682. // - v2.4.0 Experimental RapidJSON and C++14 support(Thanks to @jrkoone).
  18683. // - v2.3.1 Set default value of minFilter and magFilter in Sampler to -1.
  18684. // - v2.3.0 Modified Material representation according to glTF 2.0 schema
  18685. // (and introduced TextureInfo class)
  18686. // Change the behavior of `Value::IsNumber`. It return true either the
  18687. // value is int or real.
  18688. // - v2.2.0 Add loading 16bit PNG support. Add Sparse accessor support(Thanks
  18689. // to @Ybalrid)
  18690. // - v2.1.0 Add draco compression.
  18691. // - v2.0.1 Add comparsion feature(Thanks to @Selmar).
  18692. // - v2.0.0 glTF 2.0!.
  18693. //
  18694. // Tiny glTF loader is using following third party libraries:
  18695. //
  18696. // - jsonhpp: C++ JSON library.
  18697. // - base64: base64 decode/encode library.
  18698. // - stb_image: Image loading library.
  18699. //
  18700. #ifndef TINY_GLTF_H_
  18701. #define TINY_GLTF_H_
  18702. #define TINYGLTF_USE_CPP14
  18703. #include <array>
  18704. #include <cassert>
  18705. #include <cmath> // std::fabs
  18706. #include <cstdint>
  18707. #include <cstdlib>
  18708. #include <cstring>
  18709. #include <limits>
  18710. #include <map>
  18711. #include <string>
  18712. #include <vector>
  18713. #ifndef TINYGLTF_USE_CPP14
  18714. #include <functional>
  18715. #endif
  18716. #ifdef __ANDROID__
  18717. #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
  18718. #include <android/asset_manager.h>
  18719. #endif
  18720. #endif
  18721. #ifdef __GNUC__
  18722. #if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 8))
  18723. #define TINYGLTF_NOEXCEPT
  18724. #else
  18725. #define TINYGLTF_NOEXCEPT noexcept
  18726. #endif
  18727. #else
  18728. #define TINYGLTF_NOEXCEPT noexcept
  18729. #endif
  18730. #define DEFAULT_METHODS(x) \
  18731. ~x() = default; \
  18732. x(const x &) = default; \
  18733. x(x &&) TINYGLTF_NOEXCEPT = default; \
  18734. x &operator=(const x &) = default; \
  18735. x &operator=(x &&) TINYGLTF_NOEXCEPT = default;
  18736. namespace tinygltf
  18737. {
  18738. #define TINYGLTF_MODE_POINTS (0)
  18739. #define TINYGLTF_MODE_LINE (1)
  18740. #define TINYGLTF_MODE_LINE_LOOP (2)
  18741. #define TINYGLTF_MODE_LINE_STRIP (3)
  18742. #define TINYGLTF_MODE_TRIANGLES (4)
  18743. #define TINYGLTF_MODE_TRIANGLE_STRIP (5)
  18744. #define TINYGLTF_MODE_TRIANGLE_FAN (6)
  18745. #define TINYGLTF_COMPONENT_TYPE_BYTE (5120)
  18746. #define TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE (5121)
  18747. #define TINYGLTF_COMPONENT_TYPE_SHORT (5122)
  18748. #define TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT (5123)
  18749. #define TINYGLTF_COMPONENT_TYPE_INT (5124)
  18750. #define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
  18751. #define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
  18752. #define TINYGLTF_COMPONENT_TYPE_DOUBLE (5130)
  18753. #define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
  18754. #define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
  18755. #define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST (9984)
  18756. #define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST (9985)
  18757. #define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR (9986)
  18758. #define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR (9987)
  18759. #define TINYGLTF_TEXTURE_WRAP_REPEAT (10497)
  18760. #define TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE (33071)
  18761. #define TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT (33648)
  18762. // Redeclarations of the above for technique.parameters.
  18763. #define TINYGLTF_PARAMETER_TYPE_BYTE (5120)
  18764. #define TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE (5121)
  18765. #define TINYGLTF_PARAMETER_TYPE_SHORT (5122)
  18766. #define TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT (5123)
  18767. #define TINYGLTF_PARAMETER_TYPE_INT (5124)
  18768. #define TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT (5125)
  18769. #define TINYGLTF_PARAMETER_TYPE_FLOAT (5126)
  18770. #define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC2 (35664)
  18771. #define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC3 (35665)
  18772. #define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC4 (35666)
  18773. #define TINYGLTF_PARAMETER_TYPE_INT_VEC2 (35667)
  18774. #define TINYGLTF_PARAMETER_TYPE_INT_VEC3 (35668)
  18775. #define TINYGLTF_PARAMETER_TYPE_INT_VEC4 (35669)
  18776. #define TINYGLTF_PARAMETER_TYPE_BOOL (35670)
  18777. #define TINYGLTF_PARAMETER_TYPE_BOOL_VEC2 (35671)
  18778. #define TINYGLTF_PARAMETER_TYPE_BOOL_VEC3 (35672)
  18779. #define TINYGLTF_PARAMETER_TYPE_BOOL_VEC4 (35673)
  18780. #define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT2 (35674)
  18781. #define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT3 (35675)
  18782. #define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT4 (35676)
  18783. #define TINYGLTF_PARAMETER_TYPE_SAMPLER_2D (35678)
  18784. // End parameter types
  18785. #define TINYGLTF_TYPE_VEC2 (2)
  18786. #define TINYGLTF_TYPE_VEC3 (3)
  18787. #define TINYGLTF_TYPE_VEC4 (4)
  18788. #define TINYGLTF_TYPE_MAT2 (32 + 2)
  18789. #define TINYGLTF_TYPE_MAT3 (32 + 3)
  18790. #define TINYGLTF_TYPE_MAT4 (32 + 4)
  18791. #define TINYGLTF_TYPE_SCALAR (64 + 1)
  18792. #define TINYGLTF_TYPE_VECTOR (64 + 4)
  18793. #define TINYGLTF_TYPE_MATRIX (64 + 16)
  18794. #define TINYGLTF_IMAGE_FORMAT_JPEG (0)
  18795. #define TINYGLTF_IMAGE_FORMAT_PNG (1)
  18796. #define TINYGLTF_IMAGE_FORMAT_BMP (2)
  18797. #define TINYGLTF_IMAGE_FORMAT_GIF (3)
  18798. #define TINYGLTF_TEXTURE_FORMAT_ALPHA (6406)
  18799. #define TINYGLTF_TEXTURE_FORMAT_RGB (6407)
  18800. #define TINYGLTF_TEXTURE_FORMAT_RGBA (6408)
  18801. #define TINYGLTF_TEXTURE_FORMAT_LUMINANCE (6409)
  18802. #define TINYGLTF_TEXTURE_FORMAT_LUMINANCE_ALPHA (6410)
  18803. #define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553)
  18804. #define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121)
  18805. #define TINYGLTF_TARGET_ARRAY_BUFFER (34962)
  18806. #define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963)
  18807. #define TINYGLTF_SHADER_TYPE_VERTEX_SHADER (35633)
  18808. #define TINYGLTF_SHADER_TYPE_FRAGMENT_SHADER (35632)
  18809. #define TINYGLTF_DOUBLE_EPS (1.e-12)
  18810. #define TINYGLTF_DOUBLE_EQUAL(a, b) (std::fabs((b) - (a)) < TINYGLTF_DOUBLE_EPS)
  18811. #ifdef __ANDROID__
  18812. #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
  18813. AAssetManager *asset_manager = nullptr;
  18814. #endif
  18815. #endif
  18816. typedef enum
  18817. {
  18818. NULL_TYPE = 0,
  18819. REAL_TYPE = 1,
  18820. INT_TYPE = 2,
  18821. BOOL_TYPE = 3,
  18822. STRING_TYPE = 4,
  18823. ARRAY_TYPE = 5,
  18824. BINARY_TYPE = 6,
  18825. OBJECT_TYPE = 7
  18826. } Type;
  18827. static inline int32_t GetComponentSizeInBytes(uint32_t componentType)
  18828. {
  18829. if (componentType == TINYGLTF_COMPONENT_TYPE_BYTE)
  18830. {
  18831. return 1;
  18832. }
  18833. else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
  18834. {
  18835. return 1;
  18836. }
  18837. else if (componentType == TINYGLTF_COMPONENT_TYPE_SHORT)
  18838. {
  18839. return 2;
  18840. }
  18841. else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
  18842. {
  18843. return 2;
  18844. }
  18845. else if (componentType == TINYGLTF_COMPONENT_TYPE_INT)
  18846. {
  18847. return 4;
  18848. }
  18849. else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
  18850. {
  18851. return 4;
  18852. }
  18853. else if (componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
  18854. {
  18855. return 4;
  18856. }
  18857. else if (componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)
  18858. {
  18859. return 8;
  18860. }
  18861. else
  18862. {
  18863. // Unknown componenty type
  18864. return -1;
  18865. }
  18866. }
  18867. static inline int32_t GetNumComponentsInType(uint32_t ty)
  18868. {
  18869. if (ty == TINYGLTF_TYPE_SCALAR)
  18870. {
  18871. return 1;
  18872. }
  18873. else if (ty == TINYGLTF_TYPE_VEC2)
  18874. {
  18875. return 2;
  18876. }
  18877. else if (ty == TINYGLTF_TYPE_VEC3)
  18878. {
  18879. return 3;
  18880. }
  18881. else if (ty == TINYGLTF_TYPE_VEC4)
  18882. {
  18883. return 4;
  18884. }
  18885. else if (ty == TINYGLTF_TYPE_MAT2)
  18886. {
  18887. return 4;
  18888. }
  18889. else if (ty == TINYGLTF_TYPE_MAT3)
  18890. {
  18891. return 9;
  18892. }
  18893. else if (ty == TINYGLTF_TYPE_MAT4)
  18894. {
  18895. return 16;
  18896. }
  18897. else
  18898. {
  18899. // Unknown componenty type
  18900. return -1;
  18901. }
  18902. }
  18903. // TODO(syoyo): Move these functions to TinyGLTF class
  18904. bool IsDataURI(const std::string &in);
  18905. bool DecodeDataURI(std::vector<unsigned char> *out, std::string &mime_type,
  18906. const std::string &in, size_t reqBytes, bool checkSize);
  18907. #ifdef __clang__
  18908. #pragma clang diagnostic push
  18909. // Suppress warning for : static Value null_value
  18910. // https://stackoverflow.com/questions/15708411/how-to-deal-with-global-constructor-warning-in-clang
  18911. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  18912. #pragma clang diagnostic ignored "-Wpadded"
  18913. #endif
  18914. // Simple class to represent JSON object
  18915. class Value
  18916. {
  18917. public:
  18918. typedef std::vector<Value> Array;
  18919. typedef std::map<std::string, Value> Object;
  18920. Value()
  18921. : type_(NULL_TYPE),
  18922. int_value_(0),
  18923. real_value_(0.0),
  18924. boolean_value_(false)
  18925. {
  18926. }
  18927. explicit Value(bool b) : type_(BOOL_TYPE) { boolean_value_ = b; }
  18928. explicit Value(int i) : type_(INT_TYPE)
  18929. {
  18930. int_value_ = i;
  18931. real_value_ = i;
  18932. }
  18933. explicit Value(double n) : type_(REAL_TYPE) { real_value_ = n; }
  18934. explicit Value(const std::string &s) : type_(STRING_TYPE)
  18935. {
  18936. string_value_ = s;
  18937. }
  18938. explicit Value(std::string &&s)
  18939. : type_(STRING_TYPE), string_value_(std::move(s))
  18940. {
  18941. }
  18942. explicit Value(const unsigned char *p, size_t n) : type_(BINARY_TYPE)
  18943. {
  18944. binary_value_.resize(n);
  18945. memcpy(binary_value_.data(), p, n);
  18946. }
  18947. explicit Value(std::vector<unsigned char> &&v) noexcept
  18948. : type_(BINARY_TYPE),
  18949. binary_value_(std::move(v))
  18950. {
  18951. }
  18952. explicit Value(const Array &a) : type_(ARRAY_TYPE) { array_value_ = a; }
  18953. explicit Value(Array &&a) noexcept : type_(ARRAY_TYPE),
  18954. array_value_(std::move(a))
  18955. {
  18956. }
  18957. explicit Value(const Object &o) : type_(OBJECT_TYPE) { object_value_ = o; }
  18958. explicit Value(Object &&o) noexcept : type_(OBJECT_TYPE),
  18959. object_value_(std::move(o))
  18960. {
  18961. }
  18962. DEFAULT_METHODS(Value)
  18963. char Type() const { return static_cast<const char>(type_); }
  18964. bool IsBool() const { return (type_ == BOOL_TYPE); }
  18965. bool IsInt() const { return (type_ == INT_TYPE); }
  18966. bool IsNumber() const { return (type_ == REAL_TYPE) || (type_ == INT_TYPE); }
  18967. bool IsReal() const { return (type_ == REAL_TYPE); }
  18968. bool IsString() const { return (type_ == STRING_TYPE); }
  18969. bool IsBinary() const { return (type_ == BINARY_TYPE); }
  18970. bool IsArray() const { return (type_ == ARRAY_TYPE); }
  18971. bool IsObject() const { return (type_ == OBJECT_TYPE); }
  18972. // Use this function if you want to have number value as double.
  18973. double GetNumberAsDouble() const
  18974. {
  18975. if (type_ == INT_TYPE)
  18976. {
  18977. return double(int_value_);
  18978. }
  18979. else
  18980. {
  18981. return real_value_;
  18982. }
  18983. }
  18984. // Use this function if you want to have number value as int.
  18985. // TODO(syoyo): Support int value larger than 32 bits
  18986. int GetNumberAsInt() const
  18987. {
  18988. if (type_ == REAL_TYPE)
  18989. {
  18990. return int(real_value_);
  18991. }
  18992. else
  18993. {
  18994. return int_value_;
  18995. }
  18996. }
  18997. // Accessor
  18998. template <typename T>
  18999. const T &Get() const;
  19000. template <typename T>
  19001. T &Get();
  19002. // Lookup value from an array
  19003. const Value &Get(int idx) const
  19004. {
  19005. static Value null_value;
  19006. assert(IsArray());
  19007. assert(idx >= 0);
  19008. return (static_cast<size_t>(idx) < array_value_.size())
  19009. ? array_value_[static_cast<size_t>(idx)]
  19010. : null_value;
  19011. }
  19012. // Lookup value from a key-value pair
  19013. const Value &Get(const std::string &key) const
  19014. {
  19015. static Value null_value;
  19016. assert(IsObject());
  19017. Object::const_iterator it = object_value_.find(key);
  19018. return (it != object_value_.end()) ? it->second : null_value;
  19019. }
  19020. size_t ArrayLen() const
  19021. {
  19022. if (!IsArray()) return 0;
  19023. return array_value_.size();
  19024. }
  19025. // Valid only for object type.
  19026. bool Has(const std::string &key) const
  19027. {
  19028. if (!IsObject()) return false;
  19029. Object::const_iterator it = object_value_.find(key);
  19030. return (it != object_value_.end()) ? true : false;
  19031. }
  19032. // List keys
  19033. std::vector<std::string> Keys() const
  19034. {
  19035. std::vector<std::string> keys;
  19036. if (!IsObject()) return keys; // empty
  19037. for (Object::const_iterator it = object_value_.begin();
  19038. it != object_value_.end(); ++it)
  19039. {
  19040. keys.push_back(it->first);
  19041. }
  19042. return keys;
  19043. }
  19044. size_t Size() const { return (IsArray() ? ArrayLen() : Keys().size()); }
  19045. bool operator==(const tinygltf::Value &other) const;
  19046. protected:
  19047. int type_ = NULL_TYPE;
  19048. int int_value_ = 0;
  19049. double real_value_ = 0.0;
  19050. std::string string_value_;
  19051. std::vector<unsigned char> binary_value_;
  19052. Array array_value_;
  19053. Object object_value_;
  19054. bool boolean_value_ = false;
  19055. };
  19056. #ifdef __clang__
  19057. #pragma clang diagnostic pop
  19058. #endif
  19059. #define TINYGLTF_VALUE_GET(ctype, var) \
  19060. template <> \
  19061. inline const ctype &Value::Get<ctype>() const { \
  19062. return var; \
  19063. } \
  19064. template <> \
  19065. inline ctype &Value::Get<ctype>() { \
  19066. return var; \
  19067. }
  19068. TINYGLTF_VALUE_GET(bool, boolean_value_)
  19069. TINYGLTF_VALUE_GET(double, real_value_)
  19070. TINYGLTF_VALUE_GET(int, int_value_)
  19071. TINYGLTF_VALUE_GET(std::string, string_value_)
  19072. TINYGLTF_VALUE_GET(std::vector<unsigned char>, binary_value_)
  19073. TINYGLTF_VALUE_GET(Value::Array, array_value_)
  19074. TINYGLTF_VALUE_GET(Value::Object, object_value_)
  19075. #undef TINYGLTF_VALUE_GET
  19076. #ifdef __clang__
  19077. #pragma clang diagnostic push
  19078. #pragma clang diagnostic ignored "-Wc++98-compat"
  19079. #pragma clang diagnostic ignored "-Wpadded"
  19080. #endif
  19081. /// Agregate object for representing a color
  19082. using ColorValue = std::array<double, 4>;
  19083. // === legacy interface ====
  19084. // TODO(syoyo): Deprecate `Parameter` class.
  19085. struct Parameter
  19086. {
  19087. bool bool_value = false;
  19088. bool has_number_value = false;
  19089. std::string string_value;
  19090. std::vector<double> number_array;
  19091. std::map<std::string, double> json_double_value;
  19092. double number_value = 0.0;
  19093. // context sensitive methods. depending the type of the Parameter you are
  19094. // accessing, these are either valid or not
  19095. // If this parameter represent a texture map in a material, will return the
  19096. // texture index
  19097. /// Return the index of a texture if this Parameter is a texture map.
  19098. /// Returned value is only valid if the parameter represent a texture from a
  19099. /// material
  19100. int TextureIndex() const
  19101. {
  19102. const auto it = json_double_value.find("index");
  19103. if (it != std::end(json_double_value))
  19104. {
  19105. return int(it->second);
  19106. }
  19107. return -1;
  19108. }
  19109. /// Return the index of a texture coordinate set if this Parameter is a
  19110. /// texture map. Returned value is only valid if the parameter represent a
  19111. /// texture from a material
  19112. int TextureTexCoord() const
  19113. {
  19114. const auto it = json_double_value.find("texCoord");
  19115. if (it != std::end(json_double_value))
  19116. {
  19117. return int(it->second);
  19118. }
  19119. // As per the spec, if texCoord is ommited, this parameter is 0
  19120. return 0;
  19121. }
  19122. /// Return the scale of a texture if this Parameter is a normal texture map.
  19123. /// Returned value is only valid if the parameter represent a normal texture
  19124. /// from a material
  19125. double TextureScale() const
  19126. {
  19127. const auto it = json_double_value.find("scale");
  19128. if (it != std::end(json_double_value))
  19129. {
  19130. return it->second;
  19131. }
  19132. // As per the spec, if scale is ommited, this paramter is 1
  19133. return 1;
  19134. }
  19135. /// Return the strength of a texture if this Parameter is a an occlusion map.
  19136. /// Returned value is only valid if the parameter represent an occlusion map
  19137. /// from a material
  19138. double TextureStrength() const
  19139. {
  19140. const auto it = json_double_value.find("strength");
  19141. if (it != std::end(json_double_value))
  19142. {
  19143. return it->second;
  19144. }
  19145. // As per the spec, if strenghth is ommited, this parameter is 1
  19146. return 1;
  19147. }
  19148. /// Material factor, like the roughness or metalness of a material
  19149. /// Returned value is only valid if the parameter represent a texture from a
  19150. /// material
  19151. double Factor() const { return number_value; }
  19152. /// Return the color of a material
  19153. /// Returned value is only valid if the parameter represent a texture from a
  19154. /// material
  19155. ColorValue ColorFactor() const
  19156. {
  19157. return {
  19158. {// this agregate intialize the std::array object, and uses C++11 RVO.
  19159. number_array[0], number_array[1], number_array[2],
  19160. (number_array.size() > 3 ? number_array[3] : 1.0)} };
  19161. }
  19162. Parameter() = default;
  19163. DEFAULT_METHODS(Parameter)
  19164. bool operator==(const Parameter &) const;
  19165. };
  19166. #ifdef __clang__
  19167. #pragma clang diagnostic pop
  19168. #endif
  19169. #ifdef __clang__
  19170. #pragma clang diagnostic push
  19171. #pragma clang diagnostic ignored "-Wpadded"
  19172. #endif
  19173. typedef std::map<std::string, Parameter> ParameterMap;
  19174. typedef std::map<std::string, Value> ExtensionMap;
  19175. struct AnimationChannel
  19176. {
  19177. int sampler; // required
  19178. int target_node; // required (index of the node to target)
  19179. std::string target_path; // required in ["translation", "rotation", "scale",
  19180. // "weights"]
  19181. Value extras;
  19182. ExtensionMap extensions;
  19183. ExtensionMap target_extensions;
  19184. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19185. std::string extras_json_string;
  19186. std::string extensions_json_string;
  19187. std::string target_extensions_json_string;
  19188. AnimationChannel() : sampler(-1), target_node(-1) {}
  19189. DEFAULT_METHODS(AnimationChannel)
  19190. bool operator==(const AnimationChannel &) const;
  19191. };
  19192. struct AnimationSampler
  19193. {
  19194. int input; // required
  19195. int output; // required
  19196. std::string interpolation; // "LINEAR", "STEP","CUBICSPLINE" or user defined
  19197. // string. default "LINEAR"
  19198. Value extras;
  19199. ExtensionMap extensions;
  19200. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19201. std::string extras_json_string;
  19202. std::string extensions_json_string;
  19203. AnimationSampler() : input(-1), output(-1), interpolation("LINEAR") {}
  19204. DEFAULT_METHODS(AnimationSampler)
  19205. bool operator==(const AnimationSampler &) const;
  19206. };
  19207. struct Animation
  19208. {
  19209. std::string name;
  19210. std::vector<AnimationChannel> channels;
  19211. std::vector<AnimationSampler> samplers;
  19212. Value extras;
  19213. ExtensionMap extensions;
  19214. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19215. std::string extras_json_string;
  19216. std::string extensions_json_string;
  19217. Animation() = default;
  19218. DEFAULT_METHODS(Animation)
  19219. bool operator==(const Animation &) const;
  19220. };
  19221. struct Skin
  19222. {
  19223. std::string name;
  19224. int inverseBindMatrices; // required here but not in the spec
  19225. int skeleton; // The index of the node used as a skeleton root
  19226. std::vector<int> joints; // Indices of skeleton nodes
  19227. Value extras;
  19228. ExtensionMap extensions;
  19229. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19230. std::string extras_json_string;
  19231. std::string extensions_json_string;
  19232. Skin()
  19233. {
  19234. inverseBindMatrices = -1;
  19235. skeleton = -1;
  19236. }
  19237. DEFAULT_METHODS(Skin)
  19238. bool operator==(const Skin &) const;
  19239. };
  19240. struct Sampler
  19241. {
  19242. std::string name;
  19243. // glTF 2.0 spec does not define default value for `minFilter` and
  19244. // `magFilter`. Set -1 in TinyGLTF(issue #186)
  19245. int minFilter =
  19246. -1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR",
  19247. // "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_NEAREST",
  19248. // "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"]
  19249. int magFilter =
  19250. -1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR"]
  19251. int wrapS =
  19252. TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
  19253. // "REPEAT"], default "REPEAT"
  19254. int wrapT =
  19255. TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
  19256. // "REPEAT"], default "REPEAT"
  19257. int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension
  19258. Value extras;
  19259. ExtensionMap extensions;
  19260. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19261. std::string extras_json_string;
  19262. std::string extensions_json_string;
  19263. Sampler()
  19264. : minFilter(-1),
  19265. magFilter(-1),
  19266. wrapS(TINYGLTF_TEXTURE_WRAP_REPEAT),
  19267. wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT),
  19268. wrapR(TINYGLTF_TEXTURE_WRAP_REPEAT)
  19269. {
  19270. }
  19271. DEFAULT_METHODS(Sampler)
  19272. bool operator==(const Sampler &) const;
  19273. };
  19274. struct Image
  19275. {
  19276. std::string name;
  19277. int width;
  19278. int height;
  19279. int component;
  19280. int bits; // bit depth per channel. 8(byte), 16 or 32.
  19281. int pixel_type; // pixel type(TINYGLTF_COMPONENT_TYPE_***). usually
  19282. // UBYTE(bits = 8) or USHORT(bits = 16)
  19283. std::vector<unsigned char> image;
  19284. int bufferView; // (required if no uri)
  19285. std::string mimeType; // (required if no uri) ["image/jpeg", "image/png",
  19286. // "image/bmp", "image/gif"]
  19287. std::string uri; // (required if no mimeType) uri is not decoded(e.g.
  19288. // whitespace may be represented as %20)
  19289. Value extras;
  19290. ExtensionMap extensions;
  19291. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19292. std::string extras_json_string;
  19293. std::string extensions_json_string;
  19294. // When this flag is true, data is stored to `image` in as-is format(e.g. jpeg
  19295. // compressed for "image/jpeg" mime) This feature is good if you use custom
  19296. // image loader function. (e.g. delayed decoding of images for faster glTF
  19297. // parsing) Default parser for Image does not provide as-is loading feature at
  19298. // the moment. (You can manipulate this by providing your own LoadImageData
  19299. // function)
  19300. bool as_is;
  19301. Image() : as_is(false)
  19302. {
  19303. bufferView = -1;
  19304. width = -1;
  19305. height = -1;
  19306. component = -1;
  19307. bits = -1;
  19308. pixel_type = -1;
  19309. }
  19310. DEFAULT_METHODS(Image)
  19311. bool operator==(const Image &) const;
  19312. };
  19313. struct Texture
  19314. {
  19315. std::string name;
  19316. int sampler;
  19317. int source;
  19318. Value extras;
  19319. ExtensionMap extensions;
  19320. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19321. std::string extras_json_string;
  19322. std::string extensions_json_string;
  19323. Texture() : sampler(-1), source(-1) {}
  19324. DEFAULT_METHODS(Texture)
  19325. bool operator==(const Texture &) const;
  19326. };
  19327. struct TextureInfo
  19328. {
  19329. int index = -1; // required.
  19330. int texCoord; // The set index of texture's TEXCOORD attribute used for
  19331. // texture coordinate mapping.
  19332. Value extras;
  19333. ExtensionMap extensions;
  19334. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19335. std::string extras_json_string;
  19336. std::string extensions_json_string;
  19337. TextureInfo() : index(-1), texCoord(0) {}
  19338. DEFAULT_METHODS(TextureInfo)
  19339. bool operator==(const TextureInfo &) const;
  19340. };
  19341. struct NormalTextureInfo
  19342. {
  19343. int index = -1; // required
  19344. int texCoord; // The set index of texture's TEXCOORD attribute used for
  19345. // texture coordinate mapping.
  19346. double scale; // scaledNormal = normalize((<sampled normal texture value>
  19347. // * 2.0 - 1.0) * vec3(<normal scale>, <normal scale>, 1.0))
  19348. Value extras;
  19349. ExtensionMap extensions;
  19350. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19351. std::string extras_json_string;
  19352. std::string extensions_json_string;
  19353. NormalTextureInfo() : index(-1), texCoord(0), scale(1.0) {}
  19354. DEFAULT_METHODS(NormalTextureInfo)
  19355. bool operator==(const NormalTextureInfo &) const;
  19356. };
  19357. struct OcclusionTextureInfo
  19358. {
  19359. int index = -1; // required
  19360. int texCoord; // The set index of texture's TEXCOORD attribute used for
  19361. // texture coordinate mapping.
  19362. double strength; // occludedColor = lerp(color, color * <sampled occlusion
  19363. // texture value>, <occlusion strength>)
  19364. Value extras;
  19365. ExtensionMap extensions;
  19366. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19367. std::string extras_json_string;
  19368. std::string extensions_json_string;
  19369. OcclusionTextureInfo() : index(-1), texCoord(0), strength(1.0) {}
  19370. DEFAULT_METHODS(OcclusionTextureInfo)
  19371. bool operator==(const OcclusionTextureInfo &) const;
  19372. };
  19373. // pbrMetallicRoughness class defined in glTF 2.0 spec.
  19374. struct PbrMetallicRoughness
  19375. {
  19376. std::vector<double> baseColorFactor; // len = 4. default [1,1,1,1]
  19377. TextureInfo baseColorTexture;
  19378. double metallicFactor; // default 0
  19379. double roughnessFactor; // default 0.5
  19380. TextureInfo metallicRoughnessTexture;
  19381. Value extras;
  19382. ExtensionMap extensions;
  19383. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19384. std::string extras_json_string;
  19385. std::string extensions_json_string;
  19386. PbrMetallicRoughness()
  19387. : baseColorFactor(std::vector<double>{1.0, 1.0, 1.0, 1.0}),
  19388. metallicFactor(0),
  19389. roughnessFactor(0.5)
  19390. {
  19391. }
  19392. DEFAULT_METHODS(PbrMetallicRoughness)
  19393. bool operator==(const PbrMetallicRoughness &) const;
  19394. };
  19395. // Each extension should be stored in a ParameterMap.
  19396. // members not in the values could be included in the ParameterMap
  19397. // to keep a single material model
  19398. struct Material
  19399. {
  19400. std::string name;
  19401. std::vector<double> emissiveFactor; // length 3. default [0, 0, 0]
  19402. std::string alphaMode; // default "OPAQUE"
  19403. double alphaCutoff; // default 0.5
  19404. bool doubleSided; // default false;
  19405. PbrMetallicRoughness pbrMetallicRoughness;
  19406. NormalTextureInfo normalTexture;
  19407. OcclusionTextureInfo occlusionTexture;
  19408. TextureInfo emissiveTexture;
  19409. // For backward compatibility
  19410. // TODO(syoyo): Remove `values` and `additionalValues` in the next release.
  19411. ParameterMap values;
  19412. ParameterMap additionalValues;
  19413. ExtensionMap extensions;
  19414. Value extras;
  19415. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19416. std::string extras_json_string;
  19417. std::string extensions_json_string;
  19418. Material() : alphaMode("OPAQUE"), alphaCutoff(0.5), doubleSided(false) {}
  19419. DEFAULT_METHODS(Material)
  19420. bool operator==(const Material &) const;
  19421. };
  19422. struct BufferView
  19423. {
  19424. std::string name;
  19425. int buffer{ -1 }; // Required
  19426. size_t byteOffset{ 0 }; // minimum 0, default 0
  19427. size_t byteLength{ 0 }; // required, minimum 1. 0 = invalid
  19428. size_t byteStride{ 0 }; // minimum 4, maximum 252 (multiple of 4), default 0 =
  19429. // understood to be tightly packed
  19430. int target{ 0 }; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"] for vertex indices
  19431. // or atttribs. Could be 0 for other data
  19432. Value extras;
  19433. ExtensionMap extensions;
  19434. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19435. std::string extras_json_string;
  19436. std::string extensions_json_string;
  19437. bool dracoDecoded{ false }; // Flag indicating this has been draco decoded
  19438. BufferView()
  19439. : buffer(-1),
  19440. byteOffset(0),
  19441. byteLength(0),
  19442. byteStride(0),
  19443. target(0),
  19444. dracoDecoded(false)
  19445. {
  19446. }
  19447. DEFAULT_METHODS(BufferView)
  19448. bool operator==(const BufferView &) const;
  19449. };
  19450. struct Accessor
  19451. {
  19452. int bufferView; // optional in spec but required here since sparse accessor
  19453. // are not supported
  19454. std::string name;
  19455. size_t byteOffset;
  19456. bool normalized; // optional.
  19457. int componentType; // (required) One of TINYGLTF_COMPONENT_TYPE_***
  19458. size_t count; // required
  19459. int type; // (required) One of TINYGLTF_TYPE_*** ..
  19460. Value extras;
  19461. ExtensionMap extensions;
  19462. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19463. std::string extras_json_string;
  19464. std::string extensions_json_string;
  19465. std::vector<double> minValues; // optional
  19466. std::vector<double> maxValues; // optional
  19467. struct
  19468. {
  19469. int count;
  19470. bool isSparse;
  19471. struct
  19472. {
  19473. int byteOffset;
  19474. int bufferView;
  19475. int componentType; // a TINYGLTF_COMPONENT_TYPE_ value
  19476. } indices;
  19477. struct
  19478. {
  19479. int bufferView;
  19480. int byteOffset;
  19481. } values;
  19482. } sparse;
  19483. ///
  19484. /// Utility function to compute byteStride for a given bufferView object.
  19485. /// Returns -1 upon invalid glTF value or parameter configuration.
  19486. ///
  19487. int ByteStride(const BufferView &bufferViewObject) const
  19488. {
  19489. if (bufferViewObject.byteStride == 0)
  19490. {
  19491. // Assume data is tightly packed.
  19492. int componentSizeInBytes =
  19493. GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
  19494. if (componentSizeInBytes <= 0)
  19495. {
  19496. return -1;
  19497. }
  19498. int numComponents = GetNumComponentsInType(static_cast<uint32_t>(type));
  19499. if (numComponents <= 0)
  19500. {
  19501. return -1;
  19502. }
  19503. return componentSizeInBytes * numComponents;
  19504. }
  19505. else
  19506. {
  19507. // Check if byteStride is a mulple of the size of the accessor's component
  19508. // type.
  19509. int componentSizeInBytes =
  19510. GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
  19511. if (componentSizeInBytes <= 0)
  19512. {
  19513. return -1;
  19514. }
  19515. if ((bufferViewObject.byteStride % uint32_t(componentSizeInBytes)) != 0)
  19516. {
  19517. return -1;
  19518. }
  19519. return static_cast<int>(bufferViewObject.byteStride);
  19520. }
  19521. // unreachable return 0;
  19522. }
  19523. Accessor()
  19524. : bufferView(-1),
  19525. byteOffset(0),
  19526. normalized(false),
  19527. componentType(-1),
  19528. count(0),
  19529. type(-1)
  19530. {
  19531. sparse.isSparse = false;
  19532. }
  19533. DEFAULT_METHODS(Accessor)
  19534. bool operator==(const tinygltf::Accessor &) const;
  19535. };
  19536. struct PerspectiveCamera
  19537. {
  19538. double aspectRatio; // min > 0
  19539. double yfov; // required. min > 0
  19540. double zfar; // min > 0
  19541. double znear; // required. min > 0
  19542. PerspectiveCamera()
  19543. : aspectRatio(0.0),
  19544. yfov(0.0),
  19545. zfar(0.0) // 0 = use infinite projecton matrix
  19546. ,
  19547. znear(0.0)
  19548. {
  19549. }
  19550. DEFAULT_METHODS(PerspectiveCamera)
  19551. bool operator==(const PerspectiveCamera &) const;
  19552. ExtensionMap extensions;
  19553. Value extras;
  19554. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19555. std::string extras_json_string;
  19556. std::string extensions_json_string;
  19557. };
  19558. struct OrthographicCamera
  19559. {
  19560. double xmag; // required. must not be zero.
  19561. double ymag; // required. must not be zero.
  19562. double zfar; // required. `zfar` must be greater than `znear`.
  19563. double znear; // required
  19564. OrthographicCamera() : xmag(0.0), ymag(0.0), zfar(0.0), znear(0.0) {}
  19565. DEFAULT_METHODS(OrthographicCamera)
  19566. bool operator==(const OrthographicCamera &) const;
  19567. ExtensionMap extensions;
  19568. Value extras;
  19569. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19570. std::string extras_json_string;
  19571. std::string extensions_json_string;
  19572. };
  19573. struct Camera
  19574. {
  19575. std::string type; // required. "perspective" or "orthographic"
  19576. std::string name;
  19577. PerspectiveCamera perspective;
  19578. OrthographicCamera orthographic;
  19579. Camera() {}
  19580. DEFAULT_METHODS(Camera)
  19581. bool operator==(const Camera &) const;
  19582. ExtensionMap extensions;
  19583. Value extras;
  19584. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19585. std::string extras_json_string;
  19586. std::string extensions_json_string;
  19587. };
  19588. struct Primitive
  19589. {
  19590. std::map<std::string, int> attributes; // (required) A dictionary object of
  19591. // integer, where each integer
  19592. // is the index of the accessor
  19593. // containing an attribute.
  19594. int material; // The index of the material to apply to this primitive
  19595. // when rendering.
  19596. int indices; // The index of the accessor that contains the indices.
  19597. int mode; // one of TINYGLTF_MODE_***
  19598. std::vector<std::map<std::string, int> > targets; // array of morph targets,
  19599. // where each target is a dict with attribues in ["POSITION, "NORMAL",
  19600. // "TANGENT"] pointing
  19601. // to their corresponding accessors
  19602. ExtensionMap extensions;
  19603. Value extras;
  19604. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19605. std::string extras_json_string;
  19606. std::string extensions_json_string;
  19607. Primitive()
  19608. {
  19609. material = -1;
  19610. indices = -1;
  19611. mode = -1;
  19612. }
  19613. DEFAULT_METHODS(Primitive)
  19614. bool operator==(const Primitive &) const;
  19615. };
  19616. struct Mesh
  19617. {
  19618. std::string name;
  19619. std::vector<Primitive> primitives;
  19620. std::vector<double> weights; // weights to be applied to the Morph Targets
  19621. ExtensionMap extensions;
  19622. Value extras;
  19623. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19624. std::string extras_json_string;
  19625. std::string extensions_json_string;
  19626. Mesh() = default;
  19627. DEFAULT_METHODS(Mesh)
  19628. bool operator==(const Mesh &) const;
  19629. };
  19630. class Node
  19631. {
  19632. public:
  19633. Node() : camera(-1), skin(-1), mesh(-1) {}
  19634. DEFAULT_METHODS(Node)
  19635. bool operator==(const Node &) const;
  19636. int camera; // the index of the camera referenced by this node
  19637. std::string name;
  19638. int skin;
  19639. int mesh;
  19640. std::vector<int> children;
  19641. std::vector<double> rotation; // length must be 0 or 4
  19642. std::vector<double> scale; // length must be 0 or 3
  19643. std::vector<double> translation; // length must be 0 or 3
  19644. std::vector<double> matrix; // length must be 0 or 16
  19645. std::vector<double> weights; // The weights of the instantiated Morph Target
  19646. ExtensionMap extensions;
  19647. Value extras;
  19648. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19649. std::string extras_json_string;
  19650. std::string extensions_json_string;
  19651. };
  19652. struct Buffer
  19653. {
  19654. std::string name;
  19655. std::vector<unsigned char> data;
  19656. std::string
  19657. uri; // considered as required here but not in the spec (need to clarify)
  19658. // uri is not decoded(e.g. whitespace may be represented as %20)
  19659. Value extras;
  19660. ExtensionMap extensions;
  19661. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19662. std::string extras_json_string;
  19663. std::string extensions_json_string;
  19664. Buffer() = default;
  19665. DEFAULT_METHODS(Buffer)
  19666. bool operator==(const Buffer &) const;
  19667. };
  19668. struct Asset
  19669. {
  19670. std::string version; // required
  19671. std::string generator;
  19672. std::string minVersion;
  19673. std::string copyright;
  19674. ExtensionMap extensions;
  19675. Value extras;
  19676. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19677. std::string extras_json_string;
  19678. std::string extensions_json_string;
  19679. Asset() = default;
  19680. DEFAULT_METHODS(Asset)
  19681. bool operator==(const Asset &) const;
  19682. };
  19683. struct Scene
  19684. {
  19685. std::string name;
  19686. std::vector<int> nodes;
  19687. ExtensionMap extensions;
  19688. Value extras;
  19689. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19690. std::string extras_json_string;
  19691. std::string extensions_json_string;
  19692. Scene() = default;
  19693. DEFAULT_METHODS(Scene)
  19694. bool operator==(const Scene &) const;
  19695. };
  19696. struct SpotLight
  19697. {
  19698. double innerConeAngle;
  19699. double outerConeAngle;
  19700. SpotLight() : innerConeAngle(0.0), outerConeAngle(0.7853981634) {}
  19701. DEFAULT_METHODS(SpotLight)
  19702. bool operator==(const SpotLight &) const;
  19703. ExtensionMap extensions;
  19704. Value extras;
  19705. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19706. std::string extras_json_string;
  19707. std::string extensions_json_string;
  19708. };
  19709. struct Light
  19710. {
  19711. std::string name;
  19712. std::vector<double> color;
  19713. double intensity{ 1.0 };
  19714. std::string type;
  19715. double range{ 0.0 }; // 0.0 = inifinite
  19716. SpotLight spot;
  19717. Light() : intensity(1.0), range(0.0) {}
  19718. DEFAULT_METHODS(Light)
  19719. bool operator==(const Light &) const;
  19720. ExtensionMap extensions;
  19721. Value extras;
  19722. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19723. std::string extras_json_string;
  19724. std::string extensions_json_string;
  19725. };
  19726. class Model
  19727. {
  19728. public:
  19729. Model() = default;
  19730. DEFAULT_METHODS(Model)
  19731. bool operator==(const Model &) const;
  19732. std::vector<Accessor> accessors;
  19733. std::vector<Animation> animations;
  19734. std::vector<Buffer> buffers;
  19735. std::vector<BufferView> bufferViews;
  19736. std::vector<Material> materials;
  19737. std::vector<Mesh> meshes;
  19738. std::vector<Node> nodes;
  19739. std::vector<Texture> textures;
  19740. std::vector<Image> images;
  19741. std::vector<Skin> skins;
  19742. std::vector<Sampler> samplers;
  19743. std::vector<Camera> cameras;
  19744. std::vector<Scene> scenes;
  19745. std::vector<Light> lights;
  19746. int defaultScene = -1;
  19747. std::vector<std::string> extensionsUsed;
  19748. std::vector<std::string> extensionsRequired;
  19749. Asset asset;
  19750. Value extras;
  19751. ExtensionMap extensions;
  19752. // Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
  19753. std::string extras_json_string;
  19754. std::string extensions_json_string;
  19755. };
  19756. enum SectionCheck
  19757. {
  19758. NO_REQUIRE = 0x00,
  19759. REQUIRE_VERSION = 0x01,
  19760. REQUIRE_SCENE = 0x02,
  19761. REQUIRE_SCENES = 0x04,
  19762. REQUIRE_NODES = 0x08,
  19763. REQUIRE_ACCESSORS = 0x10,
  19764. REQUIRE_BUFFERS = 0x20,
  19765. REQUIRE_BUFFER_VIEWS = 0x40,
  19766. REQUIRE_ALL = 0x7f
  19767. };
  19768. ///
  19769. /// LoadImageDataFunction type. Signature for custom image loading callbacks.
  19770. ///
  19771. typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
  19772. std::string *, int, int,
  19773. const unsigned char *, int, void *user_pointer);
  19774. ///
  19775. /// WriteImageDataFunction type. Signature for custom image writing callbacks.
  19776. ///
  19777. typedef bool (*WriteImageDataFunction)(const std::string *, const std::string *,
  19778. Image *, bool, void *);
  19779. #ifndef TINYGLTF_NO_STB_IMAGE
  19780. // Declaration of default image loader callback
  19781. bool LoadImageData(Image *image, const int image_idx, std::string *err,
  19782. std::string *warn, int req_width, int req_height,
  19783. const unsigned char *bytes, int size, void *);
  19784. #endif
  19785. #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
  19786. // Declaration of default image writer callback
  19787. bool WriteImageData(const std::string *basepath, const std::string *filename,
  19788. Image *image, bool embedImages, void *);
  19789. #endif
  19790. ///
  19791. /// FilExistsFunction type. Signature for custom filesystem callbacks.
  19792. ///
  19793. typedef bool (*FileExistsFunction)(const std::string &abs_filename, void *);
  19794. ///
  19795. /// ExpandFilePathFunction type. Signature for custom filesystem callbacks.
  19796. ///
  19797. typedef std::string(*ExpandFilePathFunction)(const std::string &, void *);
  19798. ///
  19799. /// ReadWholeFileFunction type. Signature for custom filesystem callbacks.
  19800. ///
  19801. typedef bool (*ReadWholeFileFunction)(std::vector<unsigned char> *,
  19802. std::string *, const std::string &,
  19803. void *);
  19804. ///
  19805. /// WriteWholeFileFunction type. Signature for custom filesystem callbacks.
  19806. ///
  19807. typedef bool (*WriteWholeFileFunction)(std::string *, const std::string &,
  19808. const std::vector<unsigned char> &,
  19809. void *);
  19810. ///
  19811. /// A structure containing all required filesystem callbacks and a pointer to
  19812. /// their user data.
  19813. ///
  19814. struct FsCallbacks
  19815. {
  19816. FileExistsFunction FileExists;
  19817. ExpandFilePathFunction ExpandFilePath;
  19818. ReadWholeFileFunction ReadWholeFile;
  19819. WriteWholeFileFunction WriteWholeFile;
  19820. void *user_data; // An argument that is passed to all fs callbacks
  19821. };
  19822. #ifndef TINYGLTF_NO_FS
  19823. // Declaration of default filesystem callbacks
  19824. bool FileExists(const std::string &abs_filename, void *);
  19825. ///
  19826. /// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to
  19827. /// `C:\Users\tinygltf\AppData`)
  19828. ///
  19829. /// @param[in] filepath File path string. Assume UTF-8
  19830. /// @param[in] userdata User data. Set to `nullptr` if you don't need it.
  19831. ///
  19832. std::string ExpandFilePath(const std::string &filepath, void *userdata);
  19833. bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
  19834. const std::string &filepath, void *);
  19835. bool WriteWholeFile(std::string *err, const std::string &filepath,
  19836. const std::vector<unsigned char> &contents, void *);
  19837. #endif
  19838. ///
  19839. /// glTF Parser/Serialier context.
  19840. ///
  19841. class TinyGLTF
  19842. {
  19843. public:
  19844. #ifdef __clang__
  19845. #pragma clang diagnostic push
  19846. #pragma clang diagnostic ignored "-Wc++98-compat"
  19847. #endif
  19848. TinyGLTF() : bin_data_(nullptr), bin_size_(0), is_binary_(false) {}
  19849. #ifdef __clang__
  19850. #pragma clang diagnostic pop
  19851. #endif
  19852. ~TinyGLTF() {}
  19853. ///
  19854. /// Loads glTF ASCII asset from a file.
  19855. /// Set warning message to `warn` for example it fails to load asserts.
  19856. /// Returns false and set error string to `err` if there's an error.
  19857. ///
  19858. bool LoadASCIIFromFile(Model *model, std::string *err, std::string *warn,
  19859. const std::string &filename,
  19860. unsigned int check_sections = REQUIRE_VERSION);
  19861. ///
  19862. /// Loads glTF ASCII asset from string(memory).
  19863. /// `length` = strlen(str);
  19864. /// Set warning message to `warn` for example it fails to load asserts.
  19865. /// Returns false and set error string to `err` if there's an error.
  19866. ///
  19867. bool LoadASCIIFromString(Model *model, std::string *err, std::string *warn,
  19868. const char *str, const unsigned int length,
  19869. const std::string &base_dir,
  19870. unsigned int check_sections = REQUIRE_VERSION);
  19871. ///
  19872. /// Loads glTF binary asset from a file.
  19873. /// Set warning message to `warn` for example it fails to load asserts.
  19874. /// Returns false and set error string to `err` if there's an error.
  19875. ///
  19876. bool LoadBinaryFromFile(Model *model, std::string *err, std::string *warn,
  19877. const std::string &filename,
  19878. unsigned int check_sections = REQUIRE_VERSION);
  19879. ///
  19880. /// Loads glTF binary asset from memory.
  19881. /// `length` = strlen(str);
  19882. /// Set warning message to `warn` for example it fails to load asserts.
  19883. /// Returns false and set error string to `err` if there's an error.
  19884. ///
  19885. bool LoadBinaryFromMemory(Model *model, std::string *err, std::string *warn,
  19886. const unsigned char *bytes,
  19887. const unsigned int length,
  19888. const std::string &base_dir = "",
  19889. unsigned int check_sections = REQUIRE_VERSION);
  19890. ///
  19891. /// Write glTF to stream, buffers and images will be embeded
  19892. ///
  19893. bool WriteGltfSceneToStream(Model *model, std::ostream &stream,
  19894. bool prettyPrint, bool writeBinary);
  19895. ///
  19896. /// Write glTF to file.
  19897. ///
  19898. bool WriteGltfSceneToFile(Model *model, const std::string &filename,
  19899. bool embedImages, bool embedBuffers,
  19900. bool prettyPrint, bool writeBinary);
  19901. ///
  19902. /// Set callback to use for loading image data
  19903. ///
  19904. void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
  19905. ///
  19906. /// Unset(remove) callback of loading image data
  19907. ///
  19908. void RemoveImageLoader();
  19909. ///
  19910. /// Set callback to use for writing image data
  19911. ///
  19912. void SetImageWriter(WriteImageDataFunction WriteImageData, void *user_data);
  19913. ///
  19914. /// Set callbacks to use for filesystem (fs) access and their user data
  19915. ///
  19916. void SetFsCallbacks(FsCallbacks callbacks);
  19917. ///
  19918. /// Set serializing default values(default = false).
  19919. /// When true, default values are force serialized to .glTF.
  19920. /// This may be helpfull if you want to serialize a full description of glTF
  19921. /// data.
  19922. ///
  19923. /// TODO(LTE): Supply parsing option as function arguments to
  19924. /// `LoadASCIIFromFile()` and others, not by a class method
  19925. ///
  19926. void SetSerializeDefaultValues(const bool enabled)
  19927. {
  19928. serialize_default_values_ = enabled;
  19929. }
  19930. bool GetSerializeDefaultValues() const { return serialize_default_values_; }
  19931. ///
  19932. /// Store original JSON string for `extras` and `extensions`.
  19933. /// This feature will be useful when the user want to reconstruct custom data
  19934. /// structure from JSON string.
  19935. ///
  19936. void SetStoreOriginalJSONForExtrasAndExtensions(const bool enabled)
  19937. {
  19938. store_original_json_for_extras_and_extensions_ = enabled;
  19939. }
  19940. bool GetStoreOriginalJSONForExtrasAndExtensions() const
  19941. {
  19942. return store_original_json_for_extras_and_extensions_;
  19943. }
  19944. ///
  19945. /// Specify whether preserve image channales when loading images or not.
  19946. /// (Not effective when the user suppy their own LoadImageData callbacks)
  19947. ///
  19948. void SetPreserveImageChannels(bool onoff)
  19949. {
  19950. preserve_image_channels_ = onoff;
  19951. }
  19952. bool GetPreserveImageChannels() const
  19953. {
  19954. return preserve_image_channels_;
  19955. }
  19956. private:
  19957. ///
  19958. /// Loads glTF asset from string(memory).
  19959. /// `length` = strlen(str);
  19960. /// Set warning message to `warn` for example it fails to load asserts
  19961. /// Returns false and set error string to `err` if there's an error.
  19962. ///
  19963. bool LoadFromString(Model *model, std::string *err, std::string *warn,
  19964. const char *str, const unsigned int length,
  19965. const std::string &base_dir, unsigned int check_sections);
  19966. const unsigned char *bin_data_ = nullptr;
  19967. size_t bin_size_ = 0;
  19968. bool is_binary_ = false;
  19969. bool serialize_default_values_ = false; ///< Serialize default values?
  19970. bool store_original_json_for_extras_and_extensions_ = false;
  19971. bool preserve_image_channels_ = false; /// Default false(expand channels to RGBA) for backward compatibility.
  19972. FsCallbacks fs = {
  19973. #ifndef TINYGLTF_NO_FS
  19974. & tinygltf::FileExists, &tinygltf::ExpandFilePath,
  19975. &tinygltf::ReadWholeFile, &tinygltf::WriteWholeFile,
  19976. nullptr // Fs callback user data
  19977. #else
  19978. nullptr, nullptr, nullptr, nullptr,
  19979. nullptr // Fs callback user data
  19980. #endif
  19981. };
  19982. LoadImageDataFunction LoadImageData =
  19983. #ifndef TINYGLTF_NO_STB_IMAGE
  19984. & tinygltf::LoadImageData;
  19985. #else
  19986. nullptr;
  19987. #endif
  19988. void *load_image_user_data_{ nullptr };
  19989. bool user_image_loader_{ false };
  19990. WriteImageDataFunction WriteImageData =
  19991. #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
  19992. & tinygltf::WriteImageData;
  19993. #else
  19994. nullptr;
  19995. #endif
  19996. void *write_image_user_data_{ nullptr };
  19997. };
  19998. #ifdef __clang__
  19999. #pragma clang diagnostic pop // -Wpadded
  20000. #endif
  20001. } // namespace tinygltf
  20002. #endif // TINY_GLTF_H_
  20003. #if defined(TINYGLTF_IMPLEMENTATION) || defined(__INTELLISENSE__)
  20004. #include <algorithm>
  20005. //#include <cassert>
  20006. #ifndef TINYGLTF_NO_FS
  20007. #include <cstdio>
  20008. #endif
  20009. #include <sstream>
  20010. #ifdef __clang__
  20011. // Disable some warnings for external files.
  20012. #pragma clang diagnostic push
  20013. #pragma clang diagnostic ignored "-Wfloat-equal"
  20014. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  20015. #pragma clang diagnostic ignored "-Wconversion"
  20016. #pragma clang diagnostic ignored "-Wold-style-cast"
  20017. #pragma clang diagnostic ignored "-Wglobal-constructors"
  20018. #if __has_warning("-Wreserved-id-macro")
  20019. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  20020. #endif
  20021. #pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
  20022. #pragma clang diagnostic ignored "-Wpadded"
  20023. #pragma clang diagnostic ignored "-Wc++98-compat"
  20024. #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
  20025. #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
  20026. #pragma clang diagnostic ignored "-Wswitch-enum"
  20027. #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
  20028. #pragma clang diagnostic ignored "-Wweak-vtables"
  20029. #pragma clang diagnostic ignored "-Wcovered-switch-default"
  20030. #if __has_warning("-Wdouble-promotion")
  20031. #pragma clang diagnostic ignored "-Wdouble-promotion"
  20032. #endif
  20033. #if __has_warning("-Wcomma")
  20034. #pragma clang diagnostic ignored "-Wcomma"
  20035. #endif
  20036. #if __has_warning("-Wzero-as-null-pointer-constant")
  20037. #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  20038. #endif
  20039. #if __has_warning("-Wcast-qual")
  20040. #pragma clang diagnostic ignored "-Wcast-qual"
  20041. #endif
  20042. #if __has_warning("-Wmissing-variable-declarations")
  20043. #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
  20044. #endif
  20045. #if __has_warning("-Wmissing-prototypes")
  20046. #pragma clang diagnostic ignored "-Wmissing-prototypes"
  20047. #endif
  20048. #if __has_warning("-Wcast-align")
  20049. #pragma clang diagnostic ignored "-Wcast-align"
  20050. #endif
  20051. #if __has_warning("-Wnewline-eof")
  20052. #pragma clang diagnostic ignored "-Wnewline-eof"
  20053. #endif
  20054. #if __has_warning("-Wunused-parameter")
  20055. #pragma clang diagnostic ignored "-Wunused-parameter"
  20056. #endif
  20057. #if __has_warning("-Wmismatched-tags")
  20058. #pragma clang diagnostic ignored "-Wmismatched-tags"
  20059. #endif
  20060. #if __has_warning("-Wextra-semi-stmt")
  20061. #pragma clang diagnostic ignored "-Wextra-semi-stmt"
  20062. #endif
  20063. #endif
  20064. // Disable GCC warnigs
  20065. #ifdef __GNUC__
  20066. #pragma GCC diagnostic push
  20067. #pragma GCC diagnostic ignored "-Wtype-limits"
  20068. #endif // __GNUC__
  20069. #ifndef TINYGLTF_NO_INCLUDE_JSON
  20070. #ifndef TINYGLTF_USE_RAPIDJSON
  20071. #else
  20072. #include "document.h"
  20073. #include "prettywriter.h"
  20074. #include "rapidjson.h"
  20075. #include "stringbuffer.h"
  20076. #include "writer.h"
  20077. #endif
  20078. #endif
  20079. #ifdef TINYGLTF_ENABLE_DRACO
  20080. #include "draco/compression/decode.h"
  20081. #include "draco/core/decoder_buffer.h"
  20082. #endif
  20083. #ifndef TINYGLTF_NO_STB_IMAGE
  20084. #ifndef TINYGLTF_NO_INCLUDE_STB_IMAGE
  20085. #include "stb_image.h"
  20086. #endif
  20087. #endif
  20088. #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
  20089. #ifndef TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE
  20090. #endif
  20091. #endif
  20092. #ifdef __clang__
  20093. #pragma clang diagnostic pop
  20094. #endif
  20095. #ifdef __GNUC__
  20096. #pragma GCC diagnostic pop
  20097. #endif
  20098. #ifdef _WIN32
  20099. // issue 143.
  20100. // Define NOMINMAX to avoid min/max defines,
  20101. // but undef it after included windows.h
  20102. #ifndef NOMINMAX
  20103. #define TINYGLTF_INTERNAL_NOMINMAX
  20104. #define NOMINMAX
  20105. #endif
  20106. #ifndef WIN32_LEAN_AND_MEAN
  20107. #define WIN32_LEAN_AND_MEAN
  20108. #define TINYGLTF_INTERNAL_WIN32_LEAN_AND_MEAN
  20109. #endif
  20110. #include <windows.h> // include API for expanding a file path
  20111. #ifdef TINYGLTF_INTERNAL_WIN32_LEAN_AND_MEAN
  20112. #undef WIN32_LEAN_AND_MEAN
  20113. #endif
  20114. #if defined(TINYGLTF_INTERNAL_NOMINMAX)
  20115. #undef NOMINMAX
  20116. #endif
  20117. #if defined(__GLIBCXX__) // mingw
  20118. #include <fcntl.h> // _O_RDONLY
  20119. #include <ext/stdio_filebuf.h> // fstream (all sorts of IO stuff) + stdio_filebuf (=streambuf)
  20120. #endif
  20121. #elif !defined(__ANDROID__)
  20122. #include <wordexp.h>
  20123. #endif
  20124. #if defined(__sparcv9)
  20125. // Big endian
  20126. #else
  20127. #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
  20128. #define TINYGLTF_LITTLE_ENDIAN 1
  20129. #endif
  20130. #endif
  20131. namespace
  20132. {
  20133. #ifdef TINYGLTF_USE_RAPIDJSON
  20134. #ifdef TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
  20135. // This uses the RapidJSON CRTAllocator. It is thread safe and multiple
  20136. // documents may be active at once.
  20137. using json =
  20138. rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
  20139. using json_const_iterator = json::ConstMemberIterator;
  20140. using json_const_array_iterator = json const *;
  20141. using JsonDocument =
  20142. rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
  20143. rapidjson::CrtAllocator s_CrtAllocator; // stateless and thread safe
  20144. rapidjson::CrtAllocator &GetAllocator() { return s_CrtAllocator; }
  20145. #else
  20146. // This uses the default RapidJSON MemoryPoolAllocator. It is very fast, but
  20147. // not thread safe. Only a single JsonDocument may be active at any one time,
  20148. // meaning only a single gltf load/save can be active any one time.
  20149. using json = rapidjson::Value;
  20150. using json_const_iterator = json::ConstMemberIterator;
  20151. using json_const_array_iterator = json const *;
  20152. rapidjson::Document *s_pActiveDocument = nullptr;
  20153. rapidjson::Document::AllocatorType &GetAllocator()
  20154. {
  20155. assert(s_pActiveDocument); // Root json node must be JsonDocument type
  20156. return s_pActiveDocument->GetAllocator();
  20157. }
  20158. #ifdef __clang__
  20159. #pragma clang diagnostic push
  20160. // Suppress JsonDocument(JsonDocument &&rhs) noexcept
  20161. #pragma clang diagnostic ignored "-Wunused-member-function"
  20162. #endif
  20163. struct JsonDocument : public rapidjson::Document
  20164. {
  20165. JsonDocument()
  20166. {
  20167. assert(s_pActiveDocument ==
  20168. nullptr); // When using default allocator, only one document can be
  20169. // active at a time, if you need multiple active at once,
  20170. // define TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
  20171. s_pActiveDocument = this;
  20172. }
  20173. JsonDocument(const JsonDocument &) = delete;
  20174. JsonDocument(JsonDocument &&rhs) noexcept
  20175. : rapidjson::Document(std::move(rhs))
  20176. {
  20177. s_pActiveDocument = this;
  20178. rhs.isNil = true;
  20179. }
  20180. ~JsonDocument()
  20181. {
  20182. if (!isNil)
  20183. {
  20184. s_pActiveDocument = nullptr;
  20185. }
  20186. }
  20187. private:
  20188. bool isNil = false;
  20189. };
  20190. #ifdef __clang__
  20191. #pragma clang diagnostic pop
  20192. #endif
  20193. #endif // TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
  20194. #else
  20195. using nlohmann::json;
  20196. using json_const_iterator = json::const_iterator;
  20197. using json_const_array_iterator = json_const_iterator;
  20198. using JsonDocument = json;
  20199. #endif
  20200. void JsonParse(JsonDocument &doc, const char *str, size_t length,
  20201. bool throwExc = false)
  20202. {
  20203. #ifdef TINYGLTF_USE_RAPIDJSON
  20204. (void)throwExc;
  20205. doc.Parse(str, length);
  20206. #else
  20207. doc = json::parse(str, str + length, nullptr, throwExc);
  20208. #endif
  20209. }
  20210. } // namespace
  20211. #ifdef __APPLE__
  20212. #include "TargetConditionals.h"
  20213. #endif
  20214. #ifdef __clang__
  20215. #pragma clang diagnostic push
  20216. #pragma clang diagnostic ignored "-Wc++98-compat"
  20217. #endif
  20218. namespace tinygltf
  20219. {
  20220. ///
  20221. /// Internal LoadImageDataOption struct.
  20222. /// This struct is passed through `user_pointer` in LoadImageData.
  20223. /// The struct is not passed when the user supply their own LoadImageData callbacks.
  20224. ///
  20225. struct LoadImageDataOption
  20226. {
  20227. // true: preserve image channels(e.g. load as RGB image if the image has RGB channels)
  20228. // default `false`(channels are expanded to RGBA for backward compatiblity).
  20229. bool preserve_channels{ false };
  20230. };
  20231. // Equals function for Value, for recursivity
  20232. static bool Equals(const tinygltf::Value &one, const tinygltf::Value &other)
  20233. {
  20234. if (one.Type() != other.Type()) return false;
  20235. switch (one.Type())
  20236. {
  20237. case NULL_TYPE:
  20238. return true;
  20239. case BOOL_TYPE:
  20240. return one.Get<bool>() == other.Get<bool>();
  20241. case REAL_TYPE:
  20242. return TINYGLTF_DOUBLE_EQUAL(one.Get<double>(), other.Get<double>());
  20243. case INT_TYPE:
  20244. return one.Get<int>() == other.Get<int>();
  20245. case OBJECT_TYPE:
  20246. {
  20247. auto oneObj = one.Get<tinygltf::Value::Object>();
  20248. auto otherObj = other.Get<tinygltf::Value::Object>();
  20249. if (oneObj.size() != otherObj.size()) return false;
  20250. for (auto &it : oneObj)
  20251. {
  20252. auto otherIt = otherObj.find(it.first);
  20253. if (otherIt == otherObj.end()) return false;
  20254. if (!Equals(it.second, otherIt->second)) return false;
  20255. }
  20256. return true;
  20257. }
  20258. case ARRAY_TYPE:
  20259. {
  20260. if (one.Size() != other.Size()) return false;
  20261. for (int i = 0; i < int(one.Size()); ++i)
  20262. if (!Equals(one.Get(i), other.Get(i))) return false;
  20263. return true;
  20264. }
  20265. case STRING_TYPE:
  20266. return one.Get<std::string>() == other.Get<std::string>();
  20267. case BINARY_TYPE:
  20268. return one.Get<std::vector<unsigned char> >() ==
  20269. other.Get<std::vector<unsigned char> >();
  20270. default:
  20271. {
  20272. // unhandled type
  20273. return false;
  20274. }
  20275. }
  20276. }
  20277. // Equals function for std::vector<double> using TINYGLTF_DOUBLE_EPSILON
  20278. static bool Equals(const std::vector<double> &one,
  20279. const std::vector<double> &other)
  20280. {
  20281. if (one.size() != other.size()) return false;
  20282. for (int i = 0; i < int(one.size()); ++i)
  20283. {
  20284. if (!TINYGLTF_DOUBLE_EQUAL(one[size_t(i)], other[size_t(i)])) return false;
  20285. }
  20286. return true;
  20287. }
  20288. bool Accessor::operator==(const Accessor &other) const
  20289. {
  20290. return this->bufferView == other.bufferView &&
  20291. this->byteOffset == other.byteOffset &&
  20292. this->componentType == other.componentType &&
  20293. this->count == other.count && this->extensions == other.extensions &&
  20294. this->extras == other.extras &&
  20295. Equals(this->maxValues, other.maxValues) &&
  20296. Equals(this->minValues, other.minValues) && this->name == other.name &&
  20297. this->normalized == other.normalized && this->type == other.type;
  20298. }
  20299. bool Animation::operator==(const Animation &other) const
  20300. {
  20301. return this->channels == other.channels &&
  20302. this->extensions == other.extensions && this->extras == other.extras &&
  20303. this->name == other.name && this->samplers == other.samplers;
  20304. }
  20305. bool AnimationChannel::operator==(const AnimationChannel &other) const
  20306. {
  20307. return this->extensions == other.extensions && this->extras == other.extras &&
  20308. this->target_node == other.target_node &&
  20309. this->target_path == other.target_path &&
  20310. this->sampler == other.sampler;
  20311. }
  20312. bool AnimationSampler::operator==(const AnimationSampler &other) const
  20313. {
  20314. return this->extras == other.extras && this->extensions == other.extensions &&
  20315. this->input == other.input &&
  20316. this->interpolation == other.interpolation &&
  20317. this->output == other.output;
  20318. }
  20319. bool Asset::operator==(const Asset &other) const
  20320. {
  20321. return this->copyright == other.copyright &&
  20322. this->extensions == other.extensions && this->extras == other.extras &&
  20323. this->generator == other.generator &&
  20324. this->minVersion == other.minVersion && this->version == other.version;
  20325. }
  20326. bool Buffer::operator==(const Buffer &other) const
  20327. {
  20328. return this->data == other.data && this->extensions == other.extensions &&
  20329. this->extras == other.extras && this->name == other.name &&
  20330. this->uri == other.uri;
  20331. }
  20332. bool BufferView::operator==(const BufferView &other) const
  20333. {
  20334. return this->buffer == other.buffer && this->byteLength == other.byteLength &&
  20335. this->byteOffset == other.byteOffset &&
  20336. this->byteStride == other.byteStride && this->name == other.name &&
  20337. this->target == other.target && this->extensions == other.extensions &&
  20338. this->extras == other.extras &&
  20339. this->dracoDecoded == other.dracoDecoded;
  20340. }
  20341. bool Camera::operator==(const Camera &other) const
  20342. {
  20343. return this->name == other.name && this->extensions == other.extensions &&
  20344. this->extras == other.extras &&
  20345. this->orthographic == other.orthographic &&
  20346. this->perspective == other.perspective && this->type == other.type;
  20347. }
  20348. bool Image::operator==(const Image &other) const
  20349. {
  20350. return this->bufferView == other.bufferView &&
  20351. this->component == other.component &&
  20352. this->extensions == other.extensions && this->extras == other.extras &&
  20353. this->height == other.height && this->image == other.image &&
  20354. this->mimeType == other.mimeType && this->name == other.name &&
  20355. this->uri == other.uri && this->width == other.width;
  20356. }
  20357. bool Light::operator==(const Light &other) const
  20358. {
  20359. return Equals(this->color, other.color) && this->name == other.name &&
  20360. this->type == other.type;
  20361. }
  20362. bool Material::operator==(const Material &other) const
  20363. {
  20364. return (this->pbrMetallicRoughness == other.pbrMetallicRoughness) &&
  20365. (this->normalTexture == other.normalTexture) &&
  20366. (this->occlusionTexture == other.occlusionTexture) &&
  20367. (this->emissiveTexture == other.emissiveTexture) &&
  20368. Equals(this->emissiveFactor, other.emissiveFactor) &&
  20369. (this->alphaMode == other.alphaMode) &&
  20370. TINYGLTF_DOUBLE_EQUAL(this->alphaCutoff, other.alphaCutoff) &&
  20371. (this->doubleSided == other.doubleSided) &&
  20372. (this->extensions == other.extensions) &&
  20373. (this->extras == other.extras) && (this->values == other.values) &&
  20374. (this->additionalValues == other.additionalValues) &&
  20375. (this->name == other.name);
  20376. }
  20377. bool Mesh::operator==(const Mesh &other) const
  20378. {
  20379. return this->extensions == other.extensions && this->extras == other.extras &&
  20380. this->name == other.name && Equals(this->weights, other.weights) &&
  20381. this->primitives == other.primitives;
  20382. }
  20383. bool Model::operator==(const Model &other) const
  20384. {
  20385. return this->accessors == other.accessors &&
  20386. this->animations == other.animations && this->asset == other.asset &&
  20387. this->buffers == other.buffers &&
  20388. this->bufferViews == other.bufferViews &&
  20389. this->cameras == other.cameras &&
  20390. this->defaultScene == other.defaultScene &&
  20391. this->extensions == other.extensions &&
  20392. this->extensionsRequired == other.extensionsRequired &&
  20393. this->extensionsUsed == other.extensionsUsed &&
  20394. this->extras == other.extras && this->images == other.images &&
  20395. this->lights == other.lights && this->materials == other.materials &&
  20396. this->meshes == other.meshes && this->nodes == other.nodes &&
  20397. this->samplers == other.samplers && this->scenes == other.scenes &&
  20398. this->skins == other.skins && this->textures == other.textures;
  20399. }
  20400. bool Node::operator==(const Node &other) const
  20401. {
  20402. return this->camera == other.camera && this->children == other.children &&
  20403. this->extensions == other.extensions && this->extras == other.extras &&
  20404. Equals(this->matrix, other.matrix) && this->mesh == other.mesh &&
  20405. this->name == other.name && Equals(this->rotation, other.rotation) &&
  20406. Equals(this->scale, other.scale) && this->skin == other.skin &&
  20407. Equals(this->translation, other.translation) &&
  20408. Equals(this->weights, other.weights);
  20409. }
  20410. bool SpotLight::operator==(const SpotLight &other) const
  20411. {
  20412. return this->extensions == other.extensions && this->extras == other.extras &&
  20413. TINYGLTF_DOUBLE_EQUAL(this->innerConeAngle, other.innerConeAngle) &&
  20414. TINYGLTF_DOUBLE_EQUAL(this->outerConeAngle, other.outerConeAngle);
  20415. }
  20416. bool OrthographicCamera::operator==(const OrthographicCamera &other) const
  20417. {
  20418. return this->extensions == other.extensions && this->extras == other.extras &&
  20419. TINYGLTF_DOUBLE_EQUAL(this->xmag, other.xmag) &&
  20420. TINYGLTF_DOUBLE_EQUAL(this->ymag, other.ymag) &&
  20421. TINYGLTF_DOUBLE_EQUAL(this->zfar, other.zfar) &&
  20422. TINYGLTF_DOUBLE_EQUAL(this->znear, other.znear);
  20423. }
  20424. bool Parameter::operator==(const Parameter &other) const
  20425. {
  20426. if (this->bool_value != other.bool_value ||
  20427. this->has_number_value != other.has_number_value)
  20428. return false;
  20429. if (!TINYGLTF_DOUBLE_EQUAL(this->number_value, other.number_value))
  20430. return false;
  20431. if (this->json_double_value.size() != other.json_double_value.size())
  20432. return false;
  20433. for (auto &it : this->json_double_value)
  20434. {
  20435. auto otherIt = other.json_double_value.find(it.first);
  20436. if (otherIt == other.json_double_value.end()) return false;
  20437. if (!TINYGLTF_DOUBLE_EQUAL(it.second, otherIt->second)) return false;
  20438. }
  20439. if (!Equals(this->number_array, other.number_array)) return false;
  20440. if (this->string_value != other.string_value) return false;
  20441. return true;
  20442. }
  20443. bool PerspectiveCamera::operator==(const PerspectiveCamera &other) const
  20444. {
  20445. return TINYGLTF_DOUBLE_EQUAL(this->aspectRatio, other.aspectRatio) &&
  20446. this->extensions == other.extensions && this->extras == other.extras &&
  20447. TINYGLTF_DOUBLE_EQUAL(this->yfov, other.yfov) &&
  20448. TINYGLTF_DOUBLE_EQUAL(this->zfar, other.zfar) &&
  20449. TINYGLTF_DOUBLE_EQUAL(this->znear, other.znear);
  20450. }
  20451. bool Primitive::operator==(const Primitive &other) const
  20452. {
  20453. return this->attributes == other.attributes && this->extras == other.extras &&
  20454. this->indices == other.indices && this->material == other.material &&
  20455. this->mode == other.mode && this->targets == other.targets;
  20456. }
  20457. bool Sampler::operator==(const Sampler &other) const
  20458. {
  20459. return this->extensions == other.extensions && this->extras == other.extras &&
  20460. this->magFilter == other.magFilter &&
  20461. this->minFilter == other.minFilter && this->name == other.name &&
  20462. this->wrapR == other.wrapR && this->wrapS == other.wrapS &&
  20463. this->wrapT == other.wrapT;
  20464. }
  20465. bool Scene::operator==(const Scene &other) const
  20466. {
  20467. return this->extensions == other.extensions && this->extras == other.extras &&
  20468. this->name == other.name && this->nodes == other.nodes;
  20469. }
  20470. bool Skin::operator==(const Skin &other) const
  20471. {
  20472. return this->extensions == other.extensions && this->extras == other.extras &&
  20473. this->inverseBindMatrices == other.inverseBindMatrices &&
  20474. this->joints == other.joints && this->name == other.name &&
  20475. this->skeleton == other.skeleton;
  20476. }
  20477. bool Texture::operator==(const Texture &other) const
  20478. {
  20479. return this->extensions == other.extensions && this->extras == other.extras &&
  20480. this->name == other.name && this->sampler == other.sampler &&
  20481. this->source == other.source;
  20482. }
  20483. bool TextureInfo::operator==(const TextureInfo &other) const
  20484. {
  20485. return this->extensions == other.extensions && this->extras == other.extras &&
  20486. this->index == other.index && this->texCoord == other.texCoord;
  20487. }
  20488. bool NormalTextureInfo::operator==(const NormalTextureInfo &other) const
  20489. {
  20490. return this->extensions == other.extensions && this->extras == other.extras &&
  20491. this->index == other.index && this->texCoord == other.texCoord &&
  20492. TINYGLTF_DOUBLE_EQUAL(this->scale, other.scale);
  20493. }
  20494. bool OcclusionTextureInfo::operator==(const OcclusionTextureInfo &other) const
  20495. {
  20496. return this->extensions == other.extensions && this->extras == other.extras &&
  20497. this->index == other.index && this->texCoord == other.texCoord &&
  20498. TINYGLTF_DOUBLE_EQUAL(this->strength, other.strength);
  20499. }
  20500. bool PbrMetallicRoughness::operator==(const PbrMetallicRoughness &other) const
  20501. {
  20502. return this->extensions == other.extensions && this->extras == other.extras &&
  20503. (this->baseColorTexture == other.baseColorTexture) &&
  20504. (this->metallicRoughnessTexture == other.metallicRoughnessTexture) &&
  20505. Equals(this->baseColorFactor, other.baseColorFactor) &&
  20506. TINYGLTF_DOUBLE_EQUAL(this->metallicFactor, other.metallicFactor) &&
  20507. TINYGLTF_DOUBLE_EQUAL(this->roughnessFactor, other.roughnessFactor);
  20508. }
  20509. bool Value::operator==(const Value &other) const
  20510. {
  20511. return Equals(*this, other);
  20512. }
  20513. static void swap4(unsigned int *val)
  20514. {
  20515. #ifdef TINYGLTF_LITTLE_ENDIAN
  20516. (void)val;
  20517. #else
  20518. unsigned int tmp = *val;
  20519. unsigned char *dst = reinterpret_cast<unsigned char *>(val);
  20520. unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
  20521. dst[0] = src[3];
  20522. dst[1] = src[2];
  20523. dst[2] = src[1];
  20524. dst[3] = src[0];
  20525. #endif
  20526. }
  20527. static std::string JoinPath(const std::string &path0,
  20528. const std::string &path1)
  20529. {
  20530. if (path0.empty())
  20531. {
  20532. return path1;
  20533. }
  20534. else
  20535. {
  20536. // check '/'
  20537. char lastChar = *path0.rbegin();
  20538. if (lastChar != '/')
  20539. {
  20540. return path0 + std::string("/") + path1;
  20541. }
  20542. else
  20543. {
  20544. return path0 + path1;
  20545. }
  20546. }
  20547. }
  20548. static std::string FindFile(const std::vector<std::string> &paths,
  20549. const std::string &filepath, FsCallbacks *fs)
  20550. {
  20551. if (fs == nullptr || fs->ExpandFilePath == nullptr ||
  20552. fs->FileExists == nullptr)
  20553. {
  20554. // Error, fs callback[s] missing
  20555. return std::string();
  20556. }
  20557. for (size_t i = 0; i < paths.size(); i++)
  20558. {
  20559. std::string absPath =
  20560. fs->ExpandFilePath(JoinPath(paths[i], filepath), fs->user_data);
  20561. if (fs->FileExists(absPath, fs->user_data))
  20562. {
  20563. return absPath;
  20564. }
  20565. }
  20566. return std::string();
  20567. }
  20568. static std::string GetFilePathExtension(const std::string &FileName)
  20569. {
  20570. if (FileName.find_last_of(".") != std::string::npos)
  20571. return FileName.substr(FileName.find_last_of(".") + 1);
  20572. return "";
  20573. }
  20574. static std::string GetBaseDir(const std::string &filepath)
  20575. {
  20576. if (filepath.find_last_of("/\\") != std::string::npos)
  20577. return filepath.substr(0, filepath.find_last_of("/\\"));
  20578. return "";
  20579. }
  20580. // https://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path
  20581. static std::string GetBaseFilename(const std::string &filepath)
  20582. {
  20583. return filepath.substr(filepath.find_last_of("/\\") + 1);
  20584. }
  20585. std::string base64_encode(unsigned char const *, unsigned int len);
  20586. std::string base64_decode(std::string const &s);
  20587. /*
  20588. base64.cpp and base64.h
  20589. Copyright (C) 2004-2008 René Nyffenegger
  20590. This source code is provided 'as-is', without any express or implied
  20591. warranty. In no event will the author be held liable for any damages
  20592. arising from the use of this software.
  20593. Permission is granted to anyone to use this software for any purpose,
  20594. including commercial applications, and to alter it and redistribute it
  20595. freely, subject to the following restrictions:
  20596. 1. The origin of this source code must not be misrepresented; you must not
  20597. claim that you wrote the original source code. If you use this source code
  20598. in a product, an acknowledgment in the product documentation would be
  20599. appreciated but is not required.
  20600. 2. Altered source versions must be plainly marked as such, and must not be
  20601. misrepresented as being the original source code.
  20602. 3. This notice may not be removed or altered from any source distribution.
  20603. René Nyffenegger [email protected]
  20604. */
  20605. #ifdef __clang__
  20606. #pragma clang diagnostic push
  20607. #pragma clang diagnostic ignored "-Wsign-conversion"
  20608. #pragma clang diagnostic ignored "-Wconversion"
  20609. #endif
  20610. static inline bool is_base64(unsigned char c)
  20611. {
  20612. return (isalnum(c) || (c == '+') || (c == '/'));
  20613. }
  20614. std::string base64_encode(unsigned char const *bytes_to_encode,
  20615. unsigned int in_len)
  20616. {
  20617. std::string ret;
  20618. int i = 0;
  20619. int j = 0;
  20620. unsigned char char_array_3[3];
  20621. unsigned char char_array_4[4];
  20622. const char *base64_chars =
  20623. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  20624. "abcdefghijklmnopqrstuvwxyz"
  20625. "0123456789+/";
  20626. while (in_len--)
  20627. {
  20628. char_array_3[i++] = *(bytes_to_encode++);
  20629. if (i == 3)
  20630. {
  20631. char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
  20632. char_array_4[1] =
  20633. ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
  20634. char_array_4[2] =
  20635. ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
  20636. char_array_4[3] = char_array_3[2] & 0x3f;
  20637. for (i = 0; (i < 4); i++) ret += base64_chars[char_array_4[i]];
  20638. i = 0;
  20639. }
  20640. }
  20641. if (i)
  20642. {
  20643. for (j = i; j < 3; j++) char_array_3[j] = '\0';
  20644. char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
  20645. char_array_4[1] =
  20646. ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
  20647. char_array_4[2] =
  20648. ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
  20649. for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]];
  20650. while ((i++ < 3)) ret += '=';
  20651. }
  20652. return ret;
  20653. }
  20654. std::string base64_decode(std::string const &encoded_string)
  20655. {
  20656. int in_len = static_cast<int>(encoded_string.size());
  20657. int i = 0;
  20658. int j = 0;
  20659. int in_ = 0;
  20660. unsigned char char_array_4[4], char_array_3[3];
  20661. std::string ret;
  20662. const std::string base64_chars =
  20663. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  20664. "abcdefghijklmnopqrstuvwxyz"
  20665. "0123456789+/";
  20666. while (in_len-- && (encoded_string[in_] != '=') &&
  20667. is_base64(encoded_string[in_]))
  20668. {
  20669. char_array_4[i++] = encoded_string[in_];
  20670. in_++;
  20671. if (i == 4)
  20672. {
  20673. for (i = 0; i < 4; i++)
  20674. char_array_4[i] =
  20675. static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
  20676. char_array_3[0] =
  20677. (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
  20678. char_array_3[1] =
  20679. ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
  20680. char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
  20681. for (i = 0; (i < 3); i++) ret += char_array_3[i];
  20682. i = 0;
  20683. }
  20684. }
  20685. if (i)
  20686. {
  20687. for (j = i; j < 4; j++) char_array_4[j] = 0;
  20688. for (j = 0; j < 4; j++)
  20689. char_array_4[j] =
  20690. static_cast<unsigned char>(base64_chars.find(char_array_4[j]));
  20691. char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
  20692. char_array_3[1] =
  20693. ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
  20694. char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
  20695. for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
  20696. }
  20697. return ret;
  20698. }
  20699. #ifdef __clang__
  20700. #pragma clang diagnostic pop
  20701. #endif
  20702. // https://github.com/syoyo/tinygltf/issues/228
  20703. // TODO(syoyo): Use uriparser https://uriparser.github.io/ for stricter Uri
  20704. // decoding?
  20705. //
  20706. // https://stackoverflow.com/questions/18307429/encode-decode-url-in-c
  20707. // http://dlib.net/dlib/server/server_http.cpp.html
  20708. // --- dlib beign ------------------------------------------------------------
  20709. // Copyright (C) 2003 Davis E. King ([email protected])
  20710. // License: Boost Software License See LICENSE.txt for the full license.
  20711. namespace dlib
  20712. {
  20713. #if 0
  20714. inline unsigned char to_hex(unsigned char x)
  20715. {
  20716. return x + (x > 9 ? ('A' - 10) : '0');
  20717. }
  20718. const std::string urlencode(const std::string &s)
  20719. {
  20720. std::ostringstream os;
  20721. for (std::string::const_iterator ci = s.begin(); ci != s.end(); ++ci)
  20722. {
  20723. if ((*ci >= 'a' && *ci <= 'z') ||
  20724. (*ci >= 'A' && *ci <= 'Z') ||
  20725. (*ci >= '0' && *ci <= '9'))
  20726. { // allowed
  20727. os << *ci;
  20728. }
  20729. else if (*ci == ' ')
  20730. {
  20731. os << '+';
  20732. }
  20733. else
  20734. {
  20735. os << '%' << to_hex(static_cast<unsigned char>(*ci >> 4)) << to_hex(static_cast<unsigned char>(*ci % 16));
  20736. }
  20737. }
  20738. return os.str();
  20739. }
  20740. #endif
  20741. inline unsigned char from_hex(unsigned char ch)
  20742. {
  20743. if (ch <= '9' && ch >= '0')
  20744. ch -= '0';
  20745. else if (ch <= 'f' && ch >= 'a')
  20746. ch -= 'a' - 10;
  20747. else if (ch <= 'F' && ch >= 'A')
  20748. ch -= 'A' - 10;
  20749. else
  20750. ch = 0;
  20751. return ch;
  20752. }
  20753. static const std::string urldecode(const std::string &str)
  20754. {
  20755. using namespace std;
  20756. string result;
  20757. string::size_type i;
  20758. for (i = 0; i < str.size(); ++i)
  20759. {
  20760. if (str[i] == '+')
  20761. {
  20762. result += ' ';
  20763. }
  20764. else if (str[i] == '%' && str.size() > i + 2)
  20765. {
  20766. const unsigned char ch1 =
  20767. from_hex(static_cast<unsigned char>(str[i + 1]));
  20768. const unsigned char ch2 =
  20769. from_hex(static_cast<unsigned char>(str[i + 2]));
  20770. const unsigned char ch = static_cast<unsigned char>((ch1 << 4) | ch2);
  20771. result += static_cast<char>(ch);
  20772. i += 2;
  20773. }
  20774. else
  20775. {
  20776. result += str[i];
  20777. }
  20778. }
  20779. return result;
  20780. }
  20781. } // namespace dlib
  20782. // --- dlib end --------------------------------------------------------------
  20783. static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
  20784. std::string *warn, const std::string &filename,
  20785. const std::string &basedir, bool required,
  20786. size_t reqBytes, bool checkSize, FsCallbacks *fs)
  20787. {
  20788. if (fs == nullptr || fs->FileExists == nullptr ||
  20789. fs->ExpandFilePath == nullptr || fs->ReadWholeFile == nullptr)
  20790. {
  20791. // This is a developer error, assert() ?
  20792. if (err)
  20793. {
  20794. (*err) += "FS callback[s] not set\n";
  20795. }
  20796. return false;
  20797. }
  20798. std::string *failMsgOut = required ? err : warn;
  20799. out->clear();
  20800. std::vector<std::string> paths;
  20801. paths.push_back(basedir);
  20802. paths.push_back(".");
  20803. std::string filepath = FindFile(paths, filename, fs);
  20804. if (filepath.empty() || filename.empty())
  20805. {
  20806. if (failMsgOut)
  20807. {
  20808. (*failMsgOut) += "File not found : " + filename + "\n";
  20809. }
  20810. return false;
  20811. }
  20812. std::vector<unsigned char> buf;
  20813. std::string fileReadErr;
  20814. bool fileRead =
  20815. fs->ReadWholeFile(&buf, &fileReadErr, filepath, fs->user_data);
  20816. if (!fileRead)
  20817. {
  20818. if (failMsgOut)
  20819. {
  20820. (*failMsgOut) +=
  20821. "File read error : " + filepath + " : " + fileReadErr + "\n";
  20822. }
  20823. return false;
  20824. }
  20825. size_t sz = buf.size();
  20826. if (sz == 0)
  20827. {
  20828. if (failMsgOut)
  20829. {
  20830. (*failMsgOut) += "File is empty : " + filepath + "\n";
  20831. }
  20832. return false;
  20833. }
  20834. if (checkSize)
  20835. {
  20836. if (reqBytes == sz)
  20837. {
  20838. out->swap(buf);
  20839. return true;
  20840. }
  20841. else
  20842. {
  20843. std::stringstream ss;
  20844. ss << "File size mismatch : " << filepath << ", requestedBytes "
  20845. << reqBytes << ", but got " << sz << std::endl;
  20846. if (failMsgOut)
  20847. {
  20848. (*failMsgOut) += ss.str();
  20849. }
  20850. return false;
  20851. }
  20852. }
  20853. out->swap(buf);
  20854. return true;
  20855. }
  20856. void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data)
  20857. {
  20858. LoadImageData = func;
  20859. load_image_user_data_ = user_data;
  20860. user_image_loader_ = true;
  20861. }
  20862. void TinyGLTF::RemoveImageLoader()
  20863. {
  20864. LoadImageData =
  20865. #ifndef TINYGLTF_NO_STB_IMAGE
  20866. & tinygltf::LoadImageData;
  20867. #else
  20868. nullptr;
  20869. #endif
  20870. load_image_user_data_ = nullptr;
  20871. user_image_loader_ = false;
  20872. }
  20873. #ifndef TINYGLTF_NO_STB_IMAGE
  20874. bool LoadImageData(Image *image, const int image_idx, std::string *err,
  20875. std::string *warn, int req_width, int req_height,
  20876. const unsigned char *bytes, int size, void *user_data)
  20877. {
  20878. (void)warn;
  20879. LoadImageDataOption option;
  20880. if (user_data)
  20881. {
  20882. option = *reinterpret_cast<LoadImageDataOption *>(user_data);
  20883. }
  20884. int w = 0, h = 0, comp = 0, req_comp = 0;
  20885. unsigned char *data = nullptr;
  20886. // preserve_channels true: Use channels stored in the image file.
  20887. // false: force 32-bit textures for common Vulkan compatibility. It appears that
  20888. // some GPU drivers do not support 24-bit images for Vulkan
  20889. req_comp = option.preserve_channels ? 0 : 4;
  20890. int bits = 8;
  20891. int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
  20892. // It is possible that the image we want to load is a 16bit per channel image
  20893. // We are going to attempt to load it as 16bit per channel, and if it worked,
  20894. // set the image data accodingly. We are casting the returned pointer into
  20895. // unsigned char, because we are representing "bytes". But we are updating
  20896. // the Image metadata to signal that this image uses 2 bytes (16bits) per
  20897. // channel:
  20898. if (stbi_is_16_bit_from_memory(bytes, size))
  20899. {
  20900. data = reinterpret_cast<unsigned char *>(
  20901. stbi_load_16_from_memory(bytes, size, &w, &h, &comp, req_comp));
  20902. if (data)
  20903. {
  20904. bits = 16;
  20905. pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
  20906. }
  20907. }
  20908. // at this point, if data is still NULL, it means that the image wasn't
  20909. // 16bit per channel, we are going to load it as a normal 8bit per channel
  20910. // mage as we used to do:
  20911. // if image cannot be decoded, ignore parsing and keep it by its path
  20912. // don't break in this case
  20913. // FIXME we should only enter this function if the image is embedded. If
  20914. // image->uri references
  20915. // an image file, it should be left as it is. Image loading should not be
  20916. // mandatory (to support other formats)
  20917. if (!data) data = stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp);
  20918. if (!data)
  20919. {
  20920. // NOTE: you can use `warn` instead of `err`
  20921. if (err)
  20922. {
  20923. (*err) +=
  20924. "Unknown image format. STB cannot decode image data for image[" +
  20925. std::to_string(image_idx) + "] name = \"" + image->name + "\".\n";
  20926. }
  20927. return false;
  20928. }
  20929. if ((w < 1) || (h < 1))
  20930. {
  20931. stbi_image_free(data);
  20932. if (err)
  20933. {
  20934. (*err) += "Invalid image data for image[" + std::to_string(image_idx) +
  20935. "] name = \"" + image->name + "\"\n";
  20936. }
  20937. return false;
  20938. }
  20939. if (req_width > 0)
  20940. {
  20941. if (req_width != w)
  20942. {
  20943. stbi_image_free(data);
  20944. if (err)
  20945. {
  20946. (*err) += "Image width mismatch for image[" +
  20947. std::to_string(image_idx) + "] name = \"" + image->name +
  20948. "\"\n";
  20949. }
  20950. return false;
  20951. }
  20952. }
  20953. if (req_height > 0)
  20954. {
  20955. if (req_height != h)
  20956. {
  20957. stbi_image_free(data);
  20958. if (err)
  20959. {
  20960. (*err) += "Image height mismatch. for image[" +
  20961. std::to_string(image_idx) + "] name = \"" + image->name +
  20962. "\"\n";
  20963. }
  20964. return false;
  20965. }
  20966. }
  20967. if (req_comp != 0)
  20968. {
  20969. // loaded data has `req_comp` channels(components)
  20970. comp = req_comp;
  20971. }
  20972. image->width = w;
  20973. image->height = h;
  20974. image->component = comp;
  20975. image->bits = bits;
  20976. image->pixel_type = pixel_type;
  20977. image->image.resize(static_cast<size_t>(w * h * comp) * size_t(bits / 8));
  20978. std::copy(data, data + w * h * comp * (bits / 8), image->image.begin());
  20979. stbi_image_free(data);
  20980. return true;
  20981. }
  20982. #endif
  20983. void TinyGLTF::SetImageWriter(WriteImageDataFunction func, void *user_data)
  20984. {
  20985. WriteImageData = func;
  20986. write_image_user_data_ = user_data;
  20987. }
  20988. #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
  20989. static void WriteToMemory_stbi(void *context, void *data, int size)
  20990. {
  20991. std::vector<unsigned char> *buffer =
  20992. reinterpret_cast<std::vector<unsigned char> *>(context);
  20993. unsigned char *pData = reinterpret_cast<unsigned char *>(data);
  20994. buffer->insert(buffer->end(), pData, pData + size);
  20995. }
  20996. bool WriteImageData(const std::string *basepath, const std::string *filename,
  20997. Image *image, bool embedImages, void *fsPtr)
  20998. {
  20999. const std::string ext = GetFilePathExtension(*filename);
  21000. // Write image to temporary buffer
  21001. std::string header;
  21002. std::vector<unsigned char> data;
  21003. if (ext == "png")
  21004. {
  21005. if ((image->bits != 8) ||
  21006. (image->pixel_type != TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE))
  21007. {
  21008. // Unsupported pixel format
  21009. return false;
  21010. }
  21011. if (!stbi_write_png_to_func(WriteToMemory_stbi, &data, image->width,
  21012. image->height, image->component,
  21013. &image->image[0], 0))
  21014. {
  21015. return false;
  21016. }
  21017. header = "data:image/png;base64,";
  21018. }
  21019. else if (ext == "jpg")
  21020. {
  21021. if (!stbi_write_jpg_to_func(WriteToMemory_stbi, &data, image->width,
  21022. image->height, image->component,
  21023. &image->image[0], 100))
  21024. {
  21025. return false;
  21026. }
  21027. header = "data:image/jpeg;base64,";
  21028. }
  21029. else if (ext == "bmp")
  21030. {
  21031. if (!stbi_write_bmp_to_func(WriteToMemory_stbi, &data, image->width,
  21032. image->height, image->component,
  21033. &image->image[0]))
  21034. {
  21035. return false;
  21036. }
  21037. header = "data:image/bmp;base64,";
  21038. }
  21039. else if (!embedImages)
  21040. {
  21041. // Error: can't output requested format to file
  21042. return false;
  21043. }
  21044. if (embedImages)
  21045. {
  21046. // Embed base64-encoded image into URI
  21047. if (data.size())
  21048. {
  21049. image->uri =
  21050. header +
  21051. base64_encode(&data[0], static_cast<unsigned int>(data.size()));
  21052. }
  21053. else
  21054. {
  21055. // Throw error?
  21056. }
  21057. }
  21058. else
  21059. {
  21060. // Write image to disc
  21061. FsCallbacks *fs = reinterpret_cast<FsCallbacks *>(fsPtr);
  21062. if ((fs != nullptr) && (fs->WriteWholeFile != nullptr))
  21063. {
  21064. const std::string imagefilepath = JoinPath(*basepath, *filename);
  21065. std::string writeError;
  21066. if (!fs->WriteWholeFile(&writeError, imagefilepath, data,
  21067. fs->user_data))
  21068. {
  21069. // Could not write image file to disc; Throw error ?
  21070. return false;
  21071. }
  21072. }
  21073. else
  21074. {
  21075. // Throw error?
  21076. }
  21077. image->uri = *filename;
  21078. }
  21079. return true;
  21080. }
  21081. #endif
  21082. void TinyGLTF::SetFsCallbacks(FsCallbacks callbacks) { fs = callbacks; }
  21083. #ifdef _WIN32
  21084. static inline std::wstring UTF8ToWchar(const std::string &str)
  21085. {
  21086. int wstr_size =
  21087. MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), nullptr, 0);
  21088. std::wstring wstr(wstr_size, 0);
  21089. MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
  21090. (int)wstr.size());
  21091. return wstr;
  21092. }
  21093. static inline std::string WcharToUTF8(const std::wstring &wstr)
  21094. {
  21095. int str_size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(),
  21096. nullptr, 0, NULL, NULL);
  21097. std::string str(str_size, 0);
  21098. WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), &str[0],
  21099. (int)str.size(), NULL, NULL);
  21100. return str;
  21101. }
  21102. #endif
  21103. #ifndef TINYGLTF_NO_FS
  21104. // Default implementations of filesystem functions
  21105. bool FileExists(const std::string &abs_filename, void *)
  21106. {
  21107. bool ret;
  21108. #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
  21109. if (asset_manager)
  21110. {
  21111. AAsset *asset = AAssetManager_open(asset_manager, abs_filename.c_str(),
  21112. AASSET_MODE_STREAMING);
  21113. if (!asset)
  21114. {
  21115. return false;
  21116. }
  21117. AAsset_close(asset);
  21118. ret = true;
  21119. }
  21120. else
  21121. {
  21122. return false;
  21123. }
  21124. #else
  21125. #ifdef _WIN32
  21126. #if defined(_MSC_VER) || defined(__GLIBCXX__)
  21127. FILE *fp = nullptr;
  21128. errno_t err = _wfopen_s(&fp, UTF8ToWchar(abs_filename).c_str(), L"rb");
  21129. if (err != 0)
  21130. {
  21131. return false;
  21132. }
  21133. #else
  21134. FILE *fp = nullptr;
  21135. errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb");
  21136. if (err != 0)
  21137. {
  21138. return false;
  21139. }
  21140. #endif
  21141. #else
  21142. FILE *fp = fopen(abs_filename.c_str(), "rb");
  21143. #endif
  21144. if (fp)
  21145. {
  21146. ret = true;
  21147. fclose(fp);
  21148. }
  21149. else
  21150. {
  21151. ret = false;
  21152. }
  21153. #endif
  21154. return ret;
  21155. }
  21156. std::string ExpandFilePath(const std::string &filepath, void *)
  21157. {
  21158. #ifdef _WIN32
  21159. // Assume input `filepath` is encoded in UTF-8
  21160. std::wstring wfilepath = UTF8ToWchar(filepath);
  21161. DWORD wlen = ExpandEnvironmentStringsW(wfilepath.c_str(), nullptr, 0);
  21162. wchar_t *wstr = new wchar_t[wlen];
  21163. ExpandEnvironmentStringsW(wfilepath.c_str(), wstr, wlen);
  21164. std::wstring ws(wstr);
  21165. delete[] wstr;
  21166. return WcharToUTF8(ws);
  21167. #else
  21168. #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \
  21169. defined(__ANDROID__) || defined(__EMSCRIPTEN__)
  21170. // no expansion
  21171. std::string s = filepath;
  21172. #else
  21173. std::string s;
  21174. wordexp_t p;
  21175. if (filepath.empty())
  21176. {
  21177. return "";
  21178. }
  21179. // Quote the string to keep any spaces in filepath intact.
  21180. std::string quoted_path = "\"" + filepath + "\"";
  21181. // char** w;
  21182. int ret = wordexp(quoted_path.c_str(), &p, 0);
  21183. if (ret)
  21184. {
  21185. // err
  21186. s = filepath;
  21187. return s;
  21188. }
  21189. // Use first element only.
  21190. if (p.we_wordv)
  21191. {
  21192. s = std::string(p.we_wordv[0]);
  21193. wordfree(&p);
  21194. }
  21195. else
  21196. {
  21197. s = filepath;
  21198. }
  21199. #endif
  21200. return s;
  21201. #endif
  21202. }
  21203. //removed default write
  21204. bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
  21205. const std::string &filepath, void *)
  21206. {
  21207. assert(0);
  21208. /*
  21209. #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
  21210. if (asset_manager)
  21211. {
  21212. AAsset *asset = AAssetManager_open(asset_manager, filepath.c_str(),
  21213. AASSET_MODE_STREAMING);
  21214. if (!asset)
  21215. {
  21216. if (err)
  21217. {
  21218. (*err) += "File open error : " + filepath + "\n";
  21219. }
  21220. return false;
  21221. }
  21222. size_t size = AAsset_getLength(asset);
  21223. if (size == 0)
  21224. {
  21225. if (err)
  21226. {
  21227. (*err) += "Invalid file size : " + filepath +
  21228. " (does the path point to a directory?)";
  21229. }
  21230. return false;
  21231. }
  21232. out->resize(size);
  21233. AAsset_read(asset, reinterpret_cast<char *>(&out->at(0)), size);
  21234. AAsset_close(asset);
  21235. return true;
  21236. }
  21237. else
  21238. {
  21239. if (err)
  21240. {
  21241. (*err) += "No asset manager specified : " + filepath + "\n";
  21242. }
  21243. return false;
  21244. }
  21245. #else
  21246. #ifdef _WIN32
  21247. #if defined(__GLIBCXX__) // mingw
  21248. int file_descriptor =
  21249. _wopen(UTF8ToWchar(filepath).c_str(), _O_RDONLY | _O_BINARY);
  21250. __gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor, std::ios_base::in);
  21251. std::istream f(&wfile_buf);
  21252. #elif defined(_MSC_VER) || defined(_LIBCPP_VERSION)
  21253. // For libcxx, assume _LIBCPP_HAS_OPEN_WITH_WCHAR is defined to accept
  21254. // `wchar_t *`
  21255. std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary);
  21256. #else
  21257. // Unknown compiler/runtime
  21258. std::ifstream f(filepath.c_str(), std::ifstream::binary);
  21259. #endif
  21260. #else
  21261. std::ifstream f(filepath.c_str(), std::ifstream::binary);
  21262. #endif
  21263. if (!f)
  21264. {
  21265. if (err)
  21266. {
  21267. (*err) += "File open error : " + filepath + "\n";
  21268. }
  21269. return false;
  21270. }
  21271. f.seekg(0, f.end);
  21272. size_t sz = static_cast<size_t>(f.tellg());
  21273. f.seekg(0, f.beg);
  21274. if (int64_t(sz) < 0)
  21275. {
  21276. if (err)
  21277. {
  21278. (*err) += "Invalid file size : " + filepath +
  21279. " (does the path point to a directory?)";
  21280. }
  21281. return false;
  21282. }
  21283. else if (sz == 0)
  21284. {
  21285. if (err)
  21286. {
  21287. (*err) += "File is empty : " + filepath + "\n";
  21288. }
  21289. return false;
  21290. }
  21291. out->resize(sz);
  21292. f.read(reinterpret_cast<char *>(&out->at(0)),
  21293. static_cast<std::streamsize>(sz));
  21294. return true;
  21295. #endif
  21296. */
  21297. return false;
  21298. }
  21299. //removed writing data
  21300. bool WriteWholeFile(std::string *err, const std::string &filepath,
  21301. const std::vector<unsigned char> &contents, void *)
  21302. {
  21303. assert(0);
  21304. /*
  21305. #ifdef _WIN32
  21306. #if defined(__GLIBCXX__) // mingw
  21307. int file_descriptor = _wopen(UTF8ToWchar(filepath).c_str(),
  21308. _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
  21309. __gnu_cxx::stdio_filebuf<char> wfile_buf(
  21310. file_descriptor, std::ios_base::out | std::ios_base::binary);
  21311. std::ostream f(&wfile_buf);
  21312. #elif defined(_MSC_VER)
  21313. std::ofstream f(UTF8ToWchar(filepath).c_str(), std::ofstream::binary);
  21314. #else // clang?
  21315. std::ofstream f(filepath.c_str(), std::ofstream::binary);
  21316. #endif
  21317. #else
  21318. std::ofstream f(filepath.c_str(), std::ofstream::binary);
  21319. #endif
  21320. if (!f)
  21321. {
  21322. if (err)
  21323. {
  21324. (*err) += "File open error for writing : " + filepath + "\n";
  21325. }
  21326. return false;
  21327. }
  21328. f.write(reinterpret_cast<const char *>(&contents.at(0)),
  21329. static_cast<std::streamsize>(contents.size()));
  21330. if (!f)
  21331. {
  21332. if (err)
  21333. {
  21334. (*err) += "File write error: " + filepath + "\n";
  21335. }
  21336. return false;
  21337. }
  21338. */
  21339. return true;
  21340. }
  21341. #endif // TINYGLTF_NO_FS
  21342. static std::string MimeToExt(const std::string &mimeType)
  21343. {
  21344. if (mimeType == "image/jpeg")
  21345. {
  21346. return "jpg";
  21347. }
  21348. else if (mimeType == "image/png")
  21349. {
  21350. return "png";
  21351. }
  21352. else if (mimeType == "image/bmp")
  21353. {
  21354. return "bmp";
  21355. }
  21356. else if (mimeType == "image/gif")
  21357. {
  21358. return "gif";
  21359. }
  21360. return "";
  21361. }
  21362. static void UpdateImageObject(Image &image, std::string &baseDir, int index,
  21363. bool embedImages,
  21364. WriteImageDataFunction *WriteImageData = nullptr,
  21365. void *user_data = nullptr)
  21366. {
  21367. std::string filename;
  21368. std::string ext;
  21369. // If image has uri, use it it as a filename
  21370. if (image.uri.size())
  21371. {
  21372. filename = GetBaseFilename(image.uri);
  21373. ext = GetFilePathExtension(filename);
  21374. }
  21375. else if (image.bufferView != -1)
  21376. {
  21377. // If there's no URI and the data exists in a buffer,
  21378. // don't change properties or write images
  21379. }
  21380. else if (image.name.size())
  21381. {
  21382. ext = MimeToExt(image.mimeType);
  21383. // Otherwise use name as filename
  21384. filename = image.name + "." + ext;
  21385. }
  21386. else
  21387. {
  21388. ext = MimeToExt(image.mimeType);
  21389. // Fallback to index of image as filename
  21390. filename = std::to_string(index) + "." + ext;
  21391. }
  21392. // If callback is set, modify image data object
  21393. if (*WriteImageData != nullptr && !filename.empty())
  21394. {
  21395. std::string uri;
  21396. (*WriteImageData)(&baseDir, &filename, &image, embedImages, user_data);
  21397. }
  21398. }
  21399. bool IsDataURI(const std::string &in)
  21400. {
  21401. std::string header = "data:application/octet-stream;base64,";
  21402. if (in.find(header) == 0)
  21403. {
  21404. return true;
  21405. }
  21406. header = "data:image/jpeg;base64,";
  21407. if (in.find(header) == 0)
  21408. {
  21409. return true;
  21410. }
  21411. header = "data:image/png;base64,";
  21412. if (in.find(header) == 0)
  21413. {
  21414. return true;
  21415. }
  21416. header = "data:image/bmp;base64,";
  21417. if (in.find(header) == 0)
  21418. {
  21419. return true;
  21420. }
  21421. header = "data:image/gif;base64,";
  21422. if (in.find(header) == 0)
  21423. {
  21424. return true;
  21425. }
  21426. header = "data:text/plain;base64,";
  21427. if (in.find(header) == 0)
  21428. {
  21429. return true;
  21430. }
  21431. header = "data:application/gltf-buffer;base64,";
  21432. if (in.find(header) == 0)
  21433. {
  21434. return true;
  21435. }
  21436. return false;
  21437. }
  21438. bool DecodeDataURI(std::vector<unsigned char> *out, std::string &mime_type,
  21439. const std::string &in, size_t reqBytes, bool checkSize)
  21440. {
  21441. std::string header = "data:application/octet-stream;base64,";
  21442. std::string data;
  21443. if (in.find(header) == 0)
  21444. {
  21445. data = base64_decode(in.substr(header.size())); // cut mime string.
  21446. }
  21447. if (data.empty())
  21448. {
  21449. header = "data:image/jpeg;base64,";
  21450. if (in.find(header) == 0)
  21451. {
  21452. mime_type = "image/jpeg";
  21453. data = base64_decode(in.substr(header.size())); // cut mime string.
  21454. }
  21455. }
  21456. if (data.empty())
  21457. {
  21458. header = "data:image/png;base64,";
  21459. if (in.find(header) == 0)
  21460. {
  21461. mime_type = "image/png";
  21462. data = base64_decode(in.substr(header.size())); // cut mime string.
  21463. }
  21464. }
  21465. if (data.empty())
  21466. {
  21467. header = "data:image/bmp;base64,";
  21468. if (in.find(header) == 0)
  21469. {
  21470. mime_type = "image/bmp";
  21471. data = base64_decode(in.substr(header.size())); // cut mime string.
  21472. }
  21473. }
  21474. if (data.empty())
  21475. {
  21476. header = "data:image/gif;base64,";
  21477. if (in.find(header) == 0)
  21478. {
  21479. mime_type = "image/gif";
  21480. data = base64_decode(in.substr(header.size())); // cut mime string.
  21481. }
  21482. }
  21483. if (data.empty())
  21484. {
  21485. header = "data:text/plain;base64,";
  21486. if (in.find(header) == 0)
  21487. {
  21488. mime_type = "text/plain";
  21489. data = base64_decode(in.substr(header.size()));
  21490. }
  21491. }
  21492. if (data.empty())
  21493. {
  21494. header = "data:application/gltf-buffer;base64,";
  21495. if (in.find(header) == 0)
  21496. {
  21497. data = base64_decode(in.substr(header.size()));
  21498. }
  21499. }
  21500. // TODO(syoyo): Allow empty buffer? #229
  21501. if (data.empty())
  21502. {
  21503. return false;
  21504. }
  21505. if (checkSize)
  21506. {
  21507. if (data.size() != reqBytes)
  21508. {
  21509. return false;
  21510. }
  21511. out->resize(reqBytes);
  21512. }
  21513. else
  21514. {
  21515. out->resize(data.size());
  21516. }
  21517. std::copy(data.begin(), data.end(), out->begin());
  21518. return true;
  21519. }
  21520. namespace
  21521. {
  21522. bool GetInt(const json &o, int &val)
  21523. {
  21524. #ifdef TINYGLTF_USE_RAPIDJSON
  21525. if (!o.IsDouble())
  21526. {
  21527. if (o.IsInt())
  21528. {
  21529. val = o.GetInt();
  21530. return true;
  21531. }
  21532. else if (o.IsUint())
  21533. {
  21534. val = static_cast<int>(o.GetUint());
  21535. return true;
  21536. }
  21537. else if (o.IsInt64())
  21538. {
  21539. val = static_cast<int>(o.GetInt64());
  21540. return true;
  21541. }
  21542. else if (o.IsUint64())
  21543. {
  21544. val = static_cast<int>(o.GetUint64());
  21545. return true;
  21546. }
  21547. }
  21548. return false;
  21549. #else
  21550. auto type = o.type();
  21551. if ((type == json::value_t::number_integer) ||
  21552. (type == json::value_t::number_unsigned))
  21553. {
  21554. val = static_cast<int>(o.get<int64_t>());
  21555. return true;
  21556. }
  21557. return false;
  21558. #endif
  21559. }
  21560. #ifdef TINYGLTF_USE_RAPIDJSON
  21561. bool GetDouble(const json &o, double &val)
  21562. {
  21563. if (o.IsDouble())
  21564. {
  21565. val = o.GetDouble();
  21566. return true;
  21567. }
  21568. return false;
  21569. }
  21570. #endif
  21571. bool GetNumber(const json &o, double &val)
  21572. {
  21573. #ifdef TINYGLTF_USE_RAPIDJSON
  21574. if (o.IsNumber())
  21575. {
  21576. val = o.GetDouble();
  21577. return true;
  21578. }
  21579. return false;
  21580. #else
  21581. if (o.is_number())
  21582. {
  21583. val = o.get<double>();
  21584. return true;
  21585. }
  21586. return false;
  21587. #endif
  21588. }
  21589. bool GetString(const json &o, std::string &val)
  21590. {
  21591. #ifdef TINYGLTF_USE_RAPIDJSON
  21592. if (o.IsString())
  21593. {
  21594. val = o.GetString();
  21595. return true;
  21596. }
  21597. return false;
  21598. #else
  21599. if (o.type() == json::value_t::string)
  21600. {
  21601. val = o.get<std::string>();
  21602. return true;
  21603. }
  21604. return false;
  21605. #endif
  21606. }
  21607. bool IsArray(const json &o)
  21608. {
  21609. #ifdef TINYGLTF_USE_RAPIDJSON
  21610. return o.IsArray();
  21611. #else
  21612. return o.is_array();
  21613. #endif
  21614. }
  21615. json_const_array_iterator ArrayBegin(const json &o)
  21616. {
  21617. #ifdef TINYGLTF_USE_RAPIDJSON
  21618. return o.Begin();
  21619. #else
  21620. return o.begin();
  21621. #endif
  21622. }
  21623. json_const_array_iterator ArrayEnd(const json &o)
  21624. {
  21625. #ifdef TINYGLTF_USE_RAPIDJSON
  21626. return o.End();
  21627. #else
  21628. return o.end();
  21629. #endif
  21630. }
  21631. bool IsObject(const json &o)
  21632. {
  21633. #ifdef TINYGLTF_USE_RAPIDJSON
  21634. return o.IsObject();
  21635. #else
  21636. return o.is_object();
  21637. #endif
  21638. }
  21639. json_const_iterator ObjectBegin(const json &o)
  21640. {
  21641. #ifdef TINYGLTF_USE_RAPIDJSON
  21642. return o.MemberBegin();
  21643. #else
  21644. return o.begin();
  21645. #endif
  21646. }
  21647. json_const_iterator ObjectEnd(const json &o)
  21648. {
  21649. #ifdef TINYGLTF_USE_RAPIDJSON
  21650. return o.MemberEnd();
  21651. #else
  21652. return o.end();
  21653. #endif
  21654. }
  21655. // Making this a const char* results in a pointer to a temporary when
  21656. // TINYGLTF_USE_RAPIDJSON is off.
  21657. std::string GetKey(json_const_iterator &it)
  21658. {
  21659. #ifdef TINYGLTF_USE_RAPIDJSON
  21660. return it->name.GetString();
  21661. #else
  21662. return it.key().c_str();
  21663. #endif
  21664. }
  21665. bool FindMember(const json &o, const char *member, json_const_iterator &it)
  21666. {
  21667. #ifdef TINYGLTF_USE_RAPIDJSON
  21668. if (!o.IsObject())
  21669. {
  21670. return false;
  21671. }
  21672. it = o.FindMember(member);
  21673. return it != o.MemberEnd();
  21674. #else
  21675. it = o.find(member);
  21676. return it != o.end();
  21677. #endif
  21678. }
  21679. const json &GetValue(json_const_iterator &it)
  21680. {
  21681. #ifdef TINYGLTF_USE_RAPIDJSON
  21682. return it->value;
  21683. #else
  21684. return it.value();
  21685. #endif
  21686. }
  21687. std::string JsonToString(const json &o, int spacing = -1)
  21688. {
  21689. #ifdef TINYGLTF_USE_RAPIDJSON
  21690. using namespace rapidjson;
  21691. StringBuffer buffer;
  21692. if (spacing == -1)
  21693. {
  21694. Writer<StringBuffer> writer(buffer);
  21695. o.Accept(writer);
  21696. }
  21697. else
  21698. {
  21699. PrettyWriter<StringBuffer> writer(buffer);
  21700. writer.SetIndent(' ', uint32_t(spacing));
  21701. o.Accept(writer);
  21702. }
  21703. return buffer.GetString();
  21704. #else
  21705. return o.dump(spacing);
  21706. #endif
  21707. }
  21708. } // namespace
  21709. static bool ParseJsonAsValue(Value *ret, const json &o)
  21710. {
  21711. Value val{};
  21712. #ifdef TINYGLTF_USE_RAPIDJSON
  21713. using rapidjson::Type;
  21714. switch (o.GetType())
  21715. {
  21716. case Type::kObjectType:
  21717. {
  21718. Value::Object value_object;
  21719. for (auto it = o.MemberBegin(); it != o.MemberEnd(); ++it)
  21720. {
  21721. Value entry;
  21722. ParseJsonAsValue(&entry, it->value);
  21723. if (entry.Type() != NULL_TYPE)
  21724. value_object.emplace(GetKey(it), std::move(entry));
  21725. }
  21726. if (value_object.size() > 0) val = Value(std::move(value_object));
  21727. } break;
  21728. case Type::kArrayType:
  21729. {
  21730. Value::Array value_array;
  21731. value_array.reserve(o.Size());
  21732. for (auto it = o.Begin(); it != o.End(); ++it)
  21733. {
  21734. Value entry;
  21735. ParseJsonAsValue(&entry, *it);
  21736. if (entry.Type() != NULL_TYPE)
  21737. value_array.emplace_back(std::move(entry));
  21738. }
  21739. if (value_array.size() > 0) val = Value(std::move(value_array));
  21740. } break;
  21741. case Type::kStringType:
  21742. val = Value(std::string(o.GetString()));
  21743. break;
  21744. case Type::kFalseType:
  21745. case Type::kTrueType:
  21746. val = Value(o.GetBool());
  21747. break;
  21748. case Type::kNumberType:
  21749. if (!o.IsDouble())
  21750. {
  21751. int i = 0;
  21752. GetInt(o, i);
  21753. val = Value(i);
  21754. }
  21755. else
  21756. {
  21757. double d = 0.0;
  21758. GetDouble(o, d);
  21759. val = Value(d);
  21760. }
  21761. break;
  21762. case Type::kNullType:
  21763. break;
  21764. // all types are covered, so no `case default`
  21765. }
  21766. #else
  21767. switch (o.type())
  21768. {
  21769. case json::value_t::object:
  21770. {
  21771. Value::Object value_object;
  21772. for (auto it = o.begin(); it != o.end(); it++)
  21773. {
  21774. Value entry;
  21775. ParseJsonAsValue(&entry, it.value());
  21776. if (entry.Type() != NULL_TYPE)
  21777. value_object.emplace(it.key(), std::move(entry));
  21778. }
  21779. if (value_object.size() > 0) val = Value(std::move(value_object));
  21780. } break;
  21781. case json::value_t::array:
  21782. {
  21783. Value::Array value_array;
  21784. value_array.reserve(o.size());
  21785. for (auto it = o.begin(); it != o.end(); it++)
  21786. {
  21787. Value entry;
  21788. ParseJsonAsValue(&entry, it.value());
  21789. if (entry.Type() != NULL_TYPE)
  21790. value_array.emplace_back(std::move(entry));
  21791. }
  21792. if (value_array.size() > 0) val = Value(std::move(value_array));
  21793. } break;
  21794. case json::value_t::string:
  21795. val = Value(o.get<std::string>());
  21796. break;
  21797. case json::value_t::boolean:
  21798. val = Value(o.get<bool>());
  21799. break;
  21800. case json::value_t::number_integer:
  21801. case json::value_t::number_unsigned:
  21802. val = Value(static_cast<int>(o.get<int64_t>()));
  21803. break;
  21804. case json::value_t::number_float:
  21805. val = Value(o.get<double>());
  21806. break;
  21807. case json::value_t::null:
  21808. case json::value_t::discarded:
  21809. // default:
  21810. break;
  21811. }
  21812. #endif
  21813. if (ret) *ret = std::move(val);
  21814. return val.Type() != NULL_TYPE;
  21815. }
  21816. static bool ParseExtrasProperty(Value *ret, const json &o)
  21817. {
  21818. json_const_iterator it;
  21819. if (!FindMember(o, "extras", it))
  21820. {
  21821. return false;
  21822. }
  21823. return ParseJsonAsValue(ret, GetValue(it));
  21824. }
  21825. static bool ParseBooleanProperty(bool *ret, std::string *err, const json &o,
  21826. const std::string &property,
  21827. const bool required,
  21828. const std::string &parent_node = "")
  21829. {
  21830. json_const_iterator it;
  21831. if (!FindMember(o, property.c_str(), it))
  21832. {
  21833. if (required)
  21834. {
  21835. if (err)
  21836. {
  21837. (*err) += "'" + property + "' property is missing";
  21838. if (!parent_node.empty())
  21839. {
  21840. (*err) += " in " + parent_node;
  21841. }
  21842. (*err) += ".\n";
  21843. }
  21844. }
  21845. return false;
  21846. }
  21847. auto &value = GetValue(it);
  21848. bool isBoolean;
  21849. bool boolValue = false;
  21850. #ifdef TINYGLTF_USE_RAPIDJSON
  21851. isBoolean = value.IsBool();
  21852. if (isBoolean)
  21853. {
  21854. boolValue = value.GetBool();
  21855. }
  21856. #else
  21857. isBoolean = value.is_boolean();
  21858. if (isBoolean)
  21859. {
  21860. boolValue = value.get<bool>();
  21861. }
  21862. #endif
  21863. if (!isBoolean)
  21864. {
  21865. if (required)
  21866. {
  21867. if (err)
  21868. {
  21869. (*err) += "'" + property + "' property is not a bool type.\n";
  21870. }
  21871. }
  21872. return false;
  21873. }
  21874. if (ret)
  21875. {
  21876. (*ret) = boolValue;
  21877. }
  21878. return true;
  21879. }
  21880. static bool ParseIntegerProperty(int *ret, std::string *err, const json &o,
  21881. const std::string &property,
  21882. const bool required,
  21883. const std::string &parent_node = "")
  21884. {
  21885. json_const_iterator it;
  21886. if (!FindMember(o, property.c_str(), it))
  21887. {
  21888. if (required)
  21889. {
  21890. if (err)
  21891. {
  21892. (*err) += "'" + property + "' property is missing";
  21893. if (!parent_node.empty())
  21894. {
  21895. (*err) += " in " + parent_node;
  21896. }
  21897. (*err) += ".\n";
  21898. }
  21899. }
  21900. return false;
  21901. }
  21902. int intValue;
  21903. bool isInt = GetInt(GetValue(it), intValue);
  21904. if (!isInt)
  21905. {
  21906. if (required)
  21907. {
  21908. if (err)
  21909. {
  21910. (*err) += "'" + property + "' property is not an integer type.\n";
  21911. }
  21912. }
  21913. return false;
  21914. }
  21915. if (ret)
  21916. {
  21917. (*ret) = intValue;
  21918. }
  21919. return true;
  21920. }
  21921. static bool ParseUnsignedProperty(size_t *ret, std::string *err, const json &o,
  21922. const std::string &property,
  21923. const bool required,
  21924. const std::string &parent_node = "")
  21925. {
  21926. json_const_iterator it;
  21927. if (!FindMember(o, property.c_str(), it))
  21928. {
  21929. if (required)
  21930. {
  21931. if (err)
  21932. {
  21933. (*err) += "'" + property + "' property is missing";
  21934. if (!parent_node.empty())
  21935. {
  21936. (*err) += " in " + parent_node;
  21937. }
  21938. (*err) += ".\n";
  21939. }
  21940. }
  21941. return false;
  21942. }
  21943. auto &value = GetValue(it);
  21944. size_t uValue = 0;
  21945. bool isUValue;
  21946. #ifdef TINYGLTF_USE_RAPIDJSON
  21947. isUValue = false;
  21948. if (value.IsUint())
  21949. {
  21950. uValue = value.GetUint();
  21951. isUValue = true;
  21952. }
  21953. else if (value.IsUint64())
  21954. {
  21955. uValue = value.GetUint64();
  21956. isUValue = true;
  21957. }
  21958. #else
  21959. isUValue = value.is_number_unsigned();
  21960. if (isUValue)
  21961. {
  21962. uValue = value.get<size_t>();
  21963. }
  21964. #endif
  21965. if (!isUValue)
  21966. {
  21967. if (required)
  21968. {
  21969. if (err)
  21970. {
  21971. (*err) += "'" + property + "' property is not a positive integer.\n";
  21972. }
  21973. }
  21974. return false;
  21975. }
  21976. if (ret)
  21977. {
  21978. (*ret) = uValue;
  21979. }
  21980. return true;
  21981. }
  21982. static bool ParseNumberProperty(double *ret, std::string *err, const json &o,
  21983. const std::string &property,
  21984. const bool required,
  21985. const std::string &parent_node = "")
  21986. {
  21987. json_const_iterator it;
  21988. if (!FindMember(o, property.c_str(), it))
  21989. {
  21990. if (required)
  21991. {
  21992. if (err)
  21993. {
  21994. (*err) += "'" + property + "' property is missing";
  21995. if (!parent_node.empty())
  21996. {
  21997. (*err) += " in " + parent_node;
  21998. }
  21999. (*err) += ".\n";
  22000. }
  22001. }
  22002. return false;
  22003. }
  22004. double numberValue;
  22005. bool isNumber = GetNumber(GetValue(it), numberValue);
  22006. if (!isNumber)
  22007. {
  22008. if (required)
  22009. {
  22010. if (err)
  22011. {
  22012. (*err) += "'" + property + "' property is not a number type.\n";
  22013. }
  22014. }
  22015. return false;
  22016. }
  22017. if (ret)
  22018. {
  22019. (*ret) = numberValue;
  22020. }
  22021. return true;
  22022. }
  22023. static bool ParseNumberArrayProperty(std::vector<double> *ret, std::string *err,
  22024. const json &o, const std::string &property,
  22025. bool required,
  22026. const std::string &parent_node = "")
  22027. {
  22028. json_const_iterator it;
  22029. if (!FindMember(o, property.c_str(), it))
  22030. {
  22031. if (required)
  22032. {
  22033. if (err)
  22034. {
  22035. (*err) += "'" + property + "' property is missing";
  22036. if (!parent_node.empty())
  22037. {
  22038. (*err) += " in " + parent_node;
  22039. }
  22040. (*err) += ".\n";
  22041. }
  22042. }
  22043. return false;
  22044. }
  22045. if (!IsArray(GetValue(it)))
  22046. {
  22047. if (required)
  22048. {
  22049. if (err)
  22050. {
  22051. (*err) += "'" + property + "' property is not an array";
  22052. if (!parent_node.empty())
  22053. {
  22054. (*err) += " in " + parent_node;
  22055. }
  22056. (*err) += ".\n";
  22057. }
  22058. }
  22059. return false;
  22060. }
  22061. ret->clear();
  22062. auto end = ArrayEnd(GetValue(it));
  22063. for (auto i = ArrayBegin(GetValue(it)); i != end; ++i)
  22064. {
  22065. double numberValue;
  22066. const bool isNumber = GetNumber(*i, numberValue);
  22067. if (!isNumber)
  22068. {
  22069. if (required)
  22070. {
  22071. if (err)
  22072. {
  22073. (*err) += "'" + property + "' property is not a number.\n";
  22074. if (!parent_node.empty())
  22075. {
  22076. (*err) += " in " + parent_node;
  22077. }
  22078. (*err) += ".\n";
  22079. }
  22080. }
  22081. return false;
  22082. }
  22083. ret->push_back(numberValue);
  22084. }
  22085. return true;
  22086. }
  22087. static bool ParseIntegerArrayProperty(std::vector<int> *ret, std::string *err,
  22088. const json &o,
  22089. const std::string &property,
  22090. bool required,
  22091. const std::string &parent_node = "")
  22092. {
  22093. json_const_iterator it;
  22094. if (!FindMember(o, property.c_str(), it))
  22095. {
  22096. if (required)
  22097. {
  22098. if (err)
  22099. {
  22100. (*err) += "'" + property + "' property is missing";
  22101. if (!parent_node.empty())
  22102. {
  22103. (*err) += " in " + parent_node;
  22104. }
  22105. (*err) += ".\n";
  22106. }
  22107. }
  22108. return false;
  22109. }
  22110. if (!IsArray(GetValue(it)))
  22111. {
  22112. if (required)
  22113. {
  22114. if (err)
  22115. {
  22116. (*err) += "'" + property + "' property is not an array";
  22117. if (!parent_node.empty())
  22118. {
  22119. (*err) += " in " + parent_node;
  22120. }
  22121. (*err) += ".\n";
  22122. }
  22123. }
  22124. return false;
  22125. }
  22126. ret->clear();
  22127. auto end = ArrayEnd(GetValue(it));
  22128. for (auto i = ArrayBegin(GetValue(it)); i != end; ++i)
  22129. {
  22130. int numberValue;
  22131. bool isNumber = GetInt(*i, numberValue);
  22132. if (!isNumber)
  22133. {
  22134. if (required)
  22135. {
  22136. if (err)
  22137. {
  22138. (*err) += "'" + property + "' property is not an integer type.\n";
  22139. if (!parent_node.empty())
  22140. {
  22141. (*err) += " in " + parent_node;
  22142. }
  22143. (*err) += ".\n";
  22144. }
  22145. }
  22146. return false;
  22147. }
  22148. ret->push_back(numberValue);
  22149. }
  22150. return true;
  22151. }
  22152. static bool ParseStringProperty(
  22153. std::string *ret, std::string *err, const json &o,
  22154. const std::string &property, bool required,
  22155. const std::string &parent_node = std::string())
  22156. {
  22157. json_const_iterator it;
  22158. if (!FindMember(o, property.c_str(), it))
  22159. {
  22160. if (required)
  22161. {
  22162. if (err)
  22163. {
  22164. (*err) += "'" + property + "' property is missing";
  22165. if (parent_node.empty())
  22166. {
  22167. (*err) += ".\n";
  22168. }
  22169. else
  22170. {
  22171. (*err) += " in `" + parent_node + "'.\n";
  22172. }
  22173. }
  22174. }
  22175. return false;
  22176. }
  22177. std::string strValue;
  22178. if (!GetString(GetValue(it), strValue))
  22179. {
  22180. if (required)
  22181. {
  22182. if (err)
  22183. {
  22184. (*err) += "'" + property + "' property is not a string type.\n";
  22185. }
  22186. }
  22187. return false;
  22188. }
  22189. if (ret)
  22190. {
  22191. (*ret) = std::move(strValue);
  22192. }
  22193. return true;
  22194. }
  22195. static bool ParseStringIntegerProperty(std::map<std::string, int> *ret,
  22196. std::string *err, const json &o,
  22197. const std::string &property,
  22198. bool required,
  22199. const std::string &parent = "")
  22200. {
  22201. json_const_iterator it;
  22202. if (!FindMember(o, property.c_str(), it))
  22203. {
  22204. if (required)
  22205. {
  22206. if (err)
  22207. {
  22208. if (!parent.empty())
  22209. {
  22210. (*err) +=
  22211. "'" + property + "' property is missing in " + parent + ".\n";
  22212. }
  22213. else
  22214. {
  22215. (*err) += "'" + property + "' property is missing.\n";
  22216. }
  22217. }
  22218. }
  22219. return false;
  22220. }
  22221. const json &dict = GetValue(it);
  22222. // Make sure we are dealing with an object / dictionary.
  22223. if (!IsObject(dict))
  22224. {
  22225. if (required)
  22226. {
  22227. if (err)
  22228. {
  22229. (*err) += "'" + property + "' property is not an object.\n";
  22230. }
  22231. }
  22232. return false;
  22233. }
  22234. ret->clear();
  22235. json_const_iterator dictIt(ObjectBegin(dict));
  22236. json_const_iterator dictItEnd(ObjectEnd(dict));
  22237. for (; dictIt != dictItEnd; ++dictIt)
  22238. {
  22239. int intVal;
  22240. if (!GetInt(GetValue(dictIt), intVal))
  22241. {
  22242. if (required)
  22243. {
  22244. if (err)
  22245. {
  22246. (*err) += "'" + property + "' value is not an integer type.\n";
  22247. }
  22248. }
  22249. return false;
  22250. }
  22251. // Insert into the list.
  22252. (*ret)[GetKey(dictIt)] = intVal;
  22253. }
  22254. return true;
  22255. }
  22256. static bool ParseJSONProperty(std::map<std::string, double> *ret,
  22257. std::string *err, const json &o,
  22258. const std::string &property, bool required)
  22259. {
  22260. json_const_iterator it;
  22261. if (!FindMember(o, property.c_str(), it))
  22262. {
  22263. if (required)
  22264. {
  22265. if (err)
  22266. {
  22267. (*err) += "'" + property + "' property is missing. \n'";
  22268. }
  22269. }
  22270. return false;
  22271. }
  22272. const json &obj = GetValue(it);
  22273. if (!IsObject(obj))
  22274. {
  22275. if (required)
  22276. {
  22277. if (err)
  22278. {
  22279. (*err) += "'" + property + "' property is not a JSON object.\n";
  22280. }
  22281. }
  22282. return false;
  22283. }
  22284. ret->clear();
  22285. json_const_iterator it2(ObjectBegin(obj));
  22286. json_const_iterator itEnd(ObjectEnd(obj));
  22287. for (; it2 != itEnd; ++it2)
  22288. {
  22289. double numVal;
  22290. if (GetNumber(GetValue(it2), numVal))
  22291. ret->emplace(std::string(GetKey(it2)), numVal);
  22292. }
  22293. return true;
  22294. }
  22295. static bool ParseParameterProperty(Parameter *param, std::string *err,
  22296. const json &o, const std::string &prop,
  22297. bool required)
  22298. {
  22299. // A parameter value can either be a string or an array of either a boolean or
  22300. // a number. Booleans of any kind aren't supported here. Granted, it
  22301. // complicates the Parameter structure and breaks it semantically in the sense
  22302. // that the client probably works off the assumption that if the string is
  22303. // empty the vector is used, etc. Would a tagged union work?
  22304. if (ParseStringProperty(&param->string_value, err, o, prop, false))
  22305. {
  22306. // Found string property.
  22307. return true;
  22308. }
  22309. else if (ParseNumberArrayProperty(&param->number_array, err, o, prop,
  22310. false))
  22311. {
  22312. // Found a number array.
  22313. return true;
  22314. }
  22315. else if (ParseNumberProperty(&param->number_value, err, o, prop, false))
  22316. {
  22317. return param->has_number_value = true;
  22318. }
  22319. else if (ParseJSONProperty(&param->json_double_value, err, o, prop,
  22320. false))
  22321. {
  22322. return true;
  22323. }
  22324. else if (ParseBooleanProperty(&param->bool_value, err, o, prop, false))
  22325. {
  22326. return true;
  22327. }
  22328. else
  22329. {
  22330. if (required)
  22331. {
  22332. if (err)
  22333. {
  22334. (*err) += "parameter must be a string or number / number array.\n";
  22335. }
  22336. }
  22337. return false;
  22338. }
  22339. }
  22340. static bool ParseExtensionsProperty(ExtensionMap *ret, std::string *err,
  22341. const json &o)
  22342. {
  22343. (void)err;
  22344. json_const_iterator it;
  22345. if (!FindMember(o, "extensions", it))
  22346. {
  22347. return false;
  22348. }
  22349. auto &obj = GetValue(it);
  22350. if (!IsObject(obj))
  22351. {
  22352. return false;
  22353. }
  22354. ExtensionMap extensions;
  22355. json_const_iterator extIt = ObjectBegin(obj); // it.value().begin();
  22356. json_const_iterator extEnd = ObjectEnd(obj);
  22357. for (; extIt != extEnd; ++extIt)
  22358. {
  22359. auto &itObj = GetValue(extIt);
  22360. if (!IsObject(itObj)) continue;
  22361. std::string key(GetKey(extIt));
  22362. if (!ParseJsonAsValue(&extensions[key], itObj))
  22363. {
  22364. if (!key.empty())
  22365. {
  22366. // create empty object so that an extension object is still of type
  22367. // object
  22368. extensions[key] = Value{ Value::Object{} };
  22369. }
  22370. }
  22371. }
  22372. if (ret)
  22373. {
  22374. (*ret) = std::move(extensions);
  22375. }
  22376. return true;
  22377. }
  22378. static bool ParseAsset(Asset *asset, std::string *err, const json &o,
  22379. bool store_original_json_for_extras_and_extensions)
  22380. {
  22381. ParseStringProperty(&asset->version, err, o, "version", true, "Asset");
  22382. ParseStringProperty(&asset->generator, err, o, "generator", false, "Asset");
  22383. ParseStringProperty(&asset->minVersion, err, o, "minVersion", false, "Asset");
  22384. ParseStringProperty(&asset->copyright, err, o, "copyright", false, "Asset");
  22385. ParseExtensionsProperty(&asset->extensions, err, o);
  22386. // Unity exporter version is added as extra here
  22387. ParseExtrasProperty(&(asset->extras), o);
  22388. if (store_original_json_for_extras_and_extensions)
  22389. {
  22390. {
  22391. json_const_iterator it;
  22392. if (FindMember(o, "extensions", it))
  22393. {
  22394. asset->extensions_json_string = JsonToString(GetValue(it));
  22395. }
  22396. }
  22397. {
  22398. json_const_iterator it;
  22399. if (FindMember(o, "extras", it))
  22400. {
  22401. asset->extras_json_string = JsonToString(GetValue(it));
  22402. }
  22403. }
  22404. }
  22405. return true;
  22406. }
  22407. static bool ParseImage(Image *image, const int image_idx, std::string *err,
  22408. std::string *warn, const json &o,
  22409. bool store_original_json_for_extras_and_extensions,
  22410. const std::string &basedir, FsCallbacks *fs,
  22411. LoadImageDataFunction *LoadImageData = nullptr,
  22412. void *load_image_user_data = nullptr)
  22413. {
  22414. // A glTF image must either reference a bufferView or an image uri
  22415. // schema says oneOf [`bufferView`, `uri`]
  22416. // TODO(syoyo): Check the type of each parameters.
  22417. json_const_iterator it;
  22418. bool hasBufferView = FindMember(o, "bufferView", it);
  22419. bool hasURI = FindMember(o, "uri", it);
  22420. ParseStringProperty(&image->name, err, o, "name", false);
  22421. if (hasBufferView && hasURI)
  22422. {
  22423. // Should not both defined.
  22424. if (err)
  22425. {
  22426. (*err) +=
  22427. "Only one of `bufferView` or `uri` should be defined, but both are "
  22428. "defined for image[" +
  22429. std::to_string(image_idx) + "] name = \"" + image->name + "\"\n";
  22430. }
  22431. return false;
  22432. }
  22433. if (!hasBufferView && !hasURI)
  22434. {
  22435. if (err)
  22436. {
  22437. (*err) += "Neither required `bufferView` nor `uri` defined for image[" +
  22438. std::to_string(image_idx) + "] name = \"" + image->name +
  22439. "\"\n";
  22440. }
  22441. return false;
  22442. }
  22443. ParseExtensionsProperty(&image->extensions, err, o);
  22444. ParseExtrasProperty(&image->extras, o);
  22445. if (store_original_json_for_extras_and_extensions)
  22446. {
  22447. {
  22448. json_const_iterator eit;
  22449. if (FindMember(o, "extensions", eit))
  22450. {
  22451. image->extensions_json_string = JsonToString(GetValue(eit));
  22452. }
  22453. }
  22454. {
  22455. json_const_iterator eit;
  22456. if (FindMember(o, "extras", eit))
  22457. {
  22458. image->extras_json_string = JsonToString(GetValue(eit));
  22459. }
  22460. }
  22461. }
  22462. if (hasBufferView)
  22463. {
  22464. int bufferView = -1;
  22465. if (!ParseIntegerProperty(&bufferView, err, o, "bufferView", true))
  22466. {
  22467. if (err)
  22468. {
  22469. (*err) += "Failed to parse `bufferView` for image[" +
  22470. std::to_string(image_idx) + "] name = \"" + image->name +
  22471. "\"\n";
  22472. }
  22473. return false;
  22474. }
  22475. std::string mime_type;
  22476. ParseStringProperty(&mime_type, err, o, "mimeType", false);
  22477. int width = 0;
  22478. ParseIntegerProperty(&width, err, o, "width", false);
  22479. int height = 0;
  22480. ParseIntegerProperty(&height, err, o, "height", false);
  22481. // Just only save some information here. Loading actual image data from
  22482. // bufferView is done after this `ParseImage` function.
  22483. image->bufferView = bufferView;
  22484. image->mimeType = mime_type;
  22485. image->width = width;
  22486. image->height = height;
  22487. return true;
  22488. }
  22489. // Parse URI & Load image data.
  22490. std::string uri;
  22491. std::string tmp_err;
  22492. if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true))
  22493. {
  22494. if (err)
  22495. {
  22496. (*err) += "Failed to parse `uri` for image[" + std::to_string(image_idx) +
  22497. "] name = \"" + image->name + "\".\n";
  22498. }
  22499. return false;
  22500. }
  22501. std::vector<unsigned char> img;
  22502. if (IsDataURI(uri))
  22503. {
  22504. if (!DecodeDataURI(&img, image->mimeType, uri, 0, false))
  22505. {
  22506. if (err)
  22507. {
  22508. (*err) += "Failed to decode 'uri' for image[" +
  22509. std::to_string(image_idx) + "] name = [" + image->name +
  22510. "]\n";
  22511. }
  22512. return false;
  22513. }
  22514. }
  22515. else
  22516. {
  22517. // Assume external file
  22518. // Keep texture path (for textures that cannot be decoded)
  22519. image->uri = uri;
  22520. #ifdef TINYGLTF_NO_EXTERNAL_IMAGE
  22521. return true;
  22522. #endif
  22523. std::string decoded_uri = dlib::urldecode(uri);
  22524. if (!LoadExternalFile(&img, err, warn, decoded_uri, basedir,
  22525. /* required */ false, /* required bytes */ 0,
  22526. /* checksize */ false, fs))
  22527. {
  22528. if (warn)
  22529. {
  22530. (*warn) += "Failed to load external 'uri' for image[" +
  22531. std::to_string(image_idx) + "] name = [" + image->name +
  22532. "]\n";
  22533. }
  22534. // If the image cannot be loaded, keep uri as image->uri.
  22535. return true;
  22536. }
  22537. if (img.empty())
  22538. {
  22539. if (warn)
  22540. {
  22541. (*warn) += "Image data is empty for image[" +
  22542. std::to_string(image_idx) + "] name = [" + image->name +
  22543. "] \n";
  22544. }
  22545. return false;
  22546. }
  22547. }
  22548. if (*LoadImageData == nullptr)
  22549. {
  22550. if (err)
  22551. {
  22552. (*err) += "No LoadImageData callback specified.\n";
  22553. }
  22554. return false;
  22555. }
  22556. return (*LoadImageData)(image, image_idx, err, warn, 0, 0, &img.at(0),
  22557. static_cast<int>(img.size()), load_image_user_data);
  22558. }
  22559. static bool ParseTexture(Texture *texture, std::string *err, const json &o,
  22560. bool store_original_json_for_extras_and_extensions,
  22561. const std::string &basedir)
  22562. {
  22563. (void)basedir;
  22564. int sampler = -1;
  22565. int source = -1;
  22566. ParseIntegerProperty(&sampler, err, o, "sampler", false);
  22567. ParseIntegerProperty(&source, err, o, "source", false);
  22568. texture->sampler = sampler;
  22569. texture->source = source;
  22570. ParseExtensionsProperty(&texture->extensions, err, o);
  22571. ParseExtrasProperty(&texture->extras, o);
  22572. if (store_original_json_for_extras_and_extensions)
  22573. {
  22574. {
  22575. json_const_iterator it;
  22576. if (FindMember(o, "extensions", it))
  22577. {
  22578. texture->extensions_json_string = JsonToString(GetValue(it));
  22579. }
  22580. }
  22581. {
  22582. json_const_iterator it;
  22583. if (FindMember(o, "extras", it))
  22584. {
  22585. texture->extras_json_string = JsonToString(GetValue(it));
  22586. }
  22587. }
  22588. }
  22589. ParseStringProperty(&texture->name, err, o, "name", false);
  22590. return true;
  22591. }
  22592. static bool ParseTextureInfo(
  22593. TextureInfo *texinfo, std::string *err, const json &o,
  22594. bool store_original_json_for_extras_and_extensions)
  22595. {
  22596. if (texinfo == nullptr)
  22597. {
  22598. return false;
  22599. }
  22600. if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
  22601. /* required */ true, "TextureInfo"))
  22602. {
  22603. return false;
  22604. }
  22605. ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
  22606. ParseExtensionsProperty(&texinfo->extensions, err, o);
  22607. ParseExtrasProperty(&texinfo->extras, o);
  22608. if (store_original_json_for_extras_and_extensions)
  22609. {
  22610. {
  22611. json_const_iterator it;
  22612. if (FindMember(o, "extensions", it))
  22613. {
  22614. texinfo->extensions_json_string = JsonToString(GetValue(it));
  22615. }
  22616. }
  22617. {
  22618. json_const_iterator it;
  22619. if (FindMember(o, "extras", it))
  22620. {
  22621. texinfo->extras_json_string = JsonToString(GetValue(it));
  22622. }
  22623. }
  22624. }
  22625. return true;
  22626. }
  22627. static bool ParseNormalTextureInfo(
  22628. NormalTextureInfo *texinfo, std::string *err, const json &o,
  22629. bool store_original_json_for_extras_and_extensions)
  22630. {
  22631. if (texinfo == nullptr)
  22632. {
  22633. return false;
  22634. }
  22635. if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
  22636. /* required */ true, "NormalTextureInfo"))
  22637. {
  22638. return false;
  22639. }
  22640. ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
  22641. ParseNumberProperty(&texinfo->scale, err, o, "scale", false);
  22642. ParseExtensionsProperty(&texinfo->extensions, err, o);
  22643. ParseExtrasProperty(&texinfo->extras, o);
  22644. if (store_original_json_for_extras_and_extensions)
  22645. {
  22646. {
  22647. json_const_iterator it;
  22648. if (FindMember(o, "extensions", it))
  22649. {
  22650. texinfo->extensions_json_string = JsonToString(GetValue(it));
  22651. }
  22652. }
  22653. {
  22654. json_const_iterator it;
  22655. if (FindMember(o, "extras", it))
  22656. {
  22657. texinfo->extras_json_string = JsonToString(GetValue(it));
  22658. }
  22659. }
  22660. }
  22661. return true;
  22662. }
  22663. static bool ParseOcclusionTextureInfo(
  22664. OcclusionTextureInfo *texinfo, std::string *err, const json &o,
  22665. bool store_original_json_for_extras_and_extensions)
  22666. {
  22667. if (texinfo == nullptr)
  22668. {
  22669. return false;
  22670. }
  22671. if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
  22672. /* required */ true, "NormalTextureInfo"))
  22673. {
  22674. return false;
  22675. }
  22676. ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
  22677. ParseNumberProperty(&texinfo->strength, err, o, "strength", false);
  22678. ParseExtensionsProperty(&texinfo->extensions, err, o);
  22679. ParseExtrasProperty(&texinfo->extras, o);
  22680. if (store_original_json_for_extras_and_extensions)
  22681. {
  22682. {
  22683. json_const_iterator it;
  22684. if (FindMember(o, "extensions", it))
  22685. {
  22686. texinfo->extensions_json_string = JsonToString(GetValue(it));
  22687. }
  22688. }
  22689. {
  22690. json_const_iterator it;
  22691. if (FindMember(o, "extras", it))
  22692. {
  22693. texinfo->extras_json_string = JsonToString(GetValue(it));
  22694. }
  22695. }
  22696. }
  22697. return true;
  22698. }
  22699. static bool ParseBuffer(Buffer *buffer, std::string *err, const json &o,
  22700. bool store_original_json_for_extras_and_extensions,
  22701. FsCallbacks *fs, const std::string &basedir,
  22702. bool is_binary = false,
  22703. const unsigned char *bin_data = nullptr,
  22704. size_t bin_size = 0)
  22705. {
  22706. size_t byteLength;
  22707. if (!ParseUnsignedProperty(&byteLength, err, o, "byteLength", true,
  22708. "Buffer"))
  22709. {
  22710. return false;
  22711. }
  22712. // In glTF 2.0, uri is not mandatory anymore
  22713. buffer->uri.clear();
  22714. ParseStringProperty(&buffer->uri, err, o, "uri", false, "Buffer");
  22715. // having an empty uri for a non embedded image should not be valid
  22716. if (!is_binary && buffer->uri.empty())
  22717. {
  22718. if (err)
  22719. {
  22720. (*err) += "'uri' is missing from non binary glTF file buffer.\n";
  22721. }
  22722. }
  22723. json_const_iterator type;
  22724. if (FindMember(o, "type", type))
  22725. {
  22726. std::string typeStr;
  22727. if (GetString(GetValue(type), typeStr))
  22728. {
  22729. if (typeStr.compare("arraybuffer") == 0)
  22730. {
  22731. // buffer.type = "arraybuffer";
  22732. }
  22733. }
  22734. }
  22735. if (is_binary)
  22736. {
  22737. // Still binary glTF accepts external dataURI.
  22738. if (!buffer->uri.empty())
  22739. {
  22740. // First try embedded data URI.
  22741. if (IsDataURI(buffer->uri))
  22742. {
  22743. std::string mime_type;
  22744. if (!DecodeDataURI(&buffer->data, mime_type, buffer->uri, byteLength,
  22745. true))
  22746. {
  22747. if (err)
  22748. {
  22749. (*err) +=
  22750. "Failed to decode 'uri' : " + buffer->uri + " in Buffer\n";
  22751. }
  22752. return false;
  22753. }
  22754. }
  22755. else
  22756. {
  22757. // External .bin file.
  22758. std::string decoded_uri = dlib::urldecode(buffer->uri);
  22759. if (!LoadExternalFile(&buffer->data, err, /* warn */ nullptr,
  22760. decoded_uri, basedir, /* required */ true,
  22761. byteLength, /* checkSize */ true, fs))
  22762. {
  22763. return false;
  22764. }
  22765. }
  22766. }
  22767. else
  22768. {
  22769. // load data from (embedded) binary data
  22770. if ((bin_size == 0) || (bin_data == nullptr))
  22771. {
  22772. if (err)
  22773. {
  22774. (*err) += "Invalid binary data in `Buffer'.\n";
  22775. }
  22776. return false;
  22777. }
  22778. if (byteLength > bin_size)
  22779. {
  22780. if (err)
  22781. {
  22782. std::stringstream ss;
  22783. ss << "Invalid `byteLength'. Must be equal or less than binary size: "
  22784. "`byteLength' = "
  22785. << byteLength << ", binary size = " << bin_size << std::endl;
  22786. (*err) += ss.str();
  22787. }
  22788. return false;
  22789. }
  22790. // Read buffer data
  22791. buffer->data.resize(static_cast<size_t>(byteLength));
  22792. memcpy(&(buffer->data.at(0)), bin_data, static_cast<size_t>(byteLength));
  22793. }
  22794. }
  22795. else
  22796. {
  22797. if (IsDataURI(buffer->uri))
  22798. {
  22799. std::string mime_type;
  22800. if (!DecodeDataURI(&buffer->data, mime_type, buffer->uri, byteLength,
  22801. true))
  22802. {
  22803. if (err)
  22804. {
  22805. (*err) += "Failed to decode 'uri' : " + buffer->uri + " in Buffer\n";
  22806. }
  22807. return false;
  22808. }
  22809. }
  22810. else
  22811. {
  22812. // Assume external .bin file.
  22813. std::string decoded_uri = dlib::urldecode(buffer->uri);
  22814. if (!LoadExternalFile(&buffer->data, err, /* warn */ nullptr, decoded_uri,
  22815. basedir, /* required */ true, byteLength,
  22816. /* checkSize */ true, fs))
  22817. {
  22818. return false;
  22819. }
  22820. }
  22821. }
  22822. ParseStringProperty(&buffer->name, err, o, "name", false);
  22823. ParseExtensionsProperty(&buffer->extensions, err, o);
  22824. ParseExtrasProperty(&buffer->extras, o);
  22825. if (store_original_json_for_extras_and_extensions)
  22826. {
  22827. {
  22828. json_const_iterator it;
  22829. if (FindMember(o, "extensions", it))
  22830. {
  22831. buffer->extensions_json_string = JsonToString(GetValue(it));
  22832. }
  22833. }
  22834. {
  22835. json_const_iterator it;
  22836. if (FindMember(o, "extras", it))
  22837. {
  22838. buffer->extras_json_string = JsonToString(GetValue(it));
  22839. }
  22840. }
  22841. }
  22842. return true;
  22843. }
  22844. static bool ParseBufferView(
  22845. BufferView *bufferView, std::string *err, const json &o,
  22846. bool store_original_json_for_extras_and_extensions)
  22847. {
  22848. int buffer = -1;
  22849. if (!ParseIntegerProperty(&buffer, err, o, "buffer", true, "BufferView"))
  22850. {
  22851. return false;
  22852. }
  22853. size_t byteOffset = 0;
  22854. ParseUnsignedProperty(&byteOffset, err, o, "byteOffset", false);
  22855. size_t byteLength = 1;
  22856. if (!ParseUnsignedProperty(&byteLength, err, o, "byteLength", true,
  22857. "BufferView"))
  22858. {
  22859. return false;
  22860. }
  22861. size_t byteStride = 0;
  22862. if (!ParseUnsignedProperty(&byteStride, err, o, "byteStride", false))
  22863. {
  22864. // Spec says: When byteStride of referenced bufferView is not defined, it
  22865. // means that accessor elements are tightly packed, i.e., effective stride
  22866. // equals the size of the element.
  22867. // We cannot determine the actual byteStride until Accessor are parsed, thus
  22868. // set 0(= tightly packed) here(as done in OpenGL's VertexAttribPoiner)
  22869. byteStride = 0;
  22870. }
  22871. if ((byteStride > 252) || ((byteStride % 4) != 0))
  22872. {
  22873. if (err)
  22874. {
  22875. std::stringstream ss;
  22876. ss << "Invalid `byteStride' value. `byteStride' must be the multiple of "
  22877. "4 : "
  22878. << byteStride << std::endl;
  22879. (*err) += ss.str();
  22880. }
  22881. return false;
  22882. }
  22883. int target = 0;
  22884. ParseIntegerProperty(&target, err, o, "target", false);
  22885. if ((target == TINYGLTF_TARGET_ARRAY_BUFFER) ||
  22886. (target == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER))
  22887. {
  22888. // OK
  22889. }
  22890. else
  22891. {
  22892. target = 0;
  22893. }
  22894. bufferView->target = target;
  22895. ParseStringProperty(&bufferView->name, err, o, "name", false);
  22896. ParseExtensionsProperty(&bufferView->extensions, err, o);
  22897. ParseExtrasProperty(&bufferView->extras, o);
  22898. if (store_original_json_for_extras_and_extensions)
  22899. {
  22900. {
  22901. json_const_iterator it;
  22902. if (FindMember(o, "extensions", it))
  22903. {
  22904. bufferView->extensions_json_string = JsonToString(GetValue(it));
  22905. }
  22906. }
  22907. {
  22908. json_const_iterator it;
  22909. if (FindMember(o, "extras", it))
  22910. {
  22911. bufferView->extras_json_string = JsonToString(GetValue(it));
  22912. }
  22913. }
  22914. }
  22915. bufferView->buffer = buffer;
  22916. bufferView->byteOffset = byteOffset;
  22917. bufferView->byteLength = byteLength;
  22918. bufferView->byteStride = byteStride;
  22919. return true;
  22920. }
  22921. static bool ParseSparseAccessor(Accessor *accessor, std::string *err,
  22922. const json &o)
  22923. {
  22924. accessor->sparse.isSparse = true;
  22925. int count = 0;
  22926. ParseIntegerProperty(&count, err, o, "count", true);
  22927. json_const_iterator indices_iterator;
  22928. json_const_iterator values_iterator;
  22929. if (!FindMember(o, "indices", indices_iterator))
  22930. {
  22931. (*err) = "the sparse object of this accessor doesn't have indices";
  22932. return false;
  22933. }
  22934. if (!FindMember(o, "values", values_iterator))
  22935. {
  22936. (*err) = "the sparse object ob ths accessor doesn't have values";
  22937. return false;
  22938. }
  22939. const json &indices_obj = GetValue(indices_iterator);
  22940. const json &values_obj = GetValue(values_iterator);
  22941. int indices_buffer_view = 0, indices_byte_offset = 0, component_type = 0;
  22942. ParseIntegerProperty(&indices_buffer_view, err, indices_obj, "bufferView",
  22943. true);
  22944. ParseIntegerProperty(&indices_byte_offset, err, indices_obj, "byteOffset",
  22945. true);
  22946. ParseIntegerProperty(&component_type, err, indices_obj, "componentType",
  22947. true);
  22948. int values_buffer_view = 0, values_byte_offset = 0;
  22949. ParseIntegerProperty(&values_buffer_view, err, values_obj, "bufferView",
  22950. true);
  22951. ParseIntegerProperty(&values_byte_offset, err, values_obj, "byteOffset",
  22952. true);
  22953. accessor->sparse.count = count;
  22954. accessor->sparse.indices.bufferView = indices_buffer_view;
  22955. accessor->sparse.indices.byteOffset = indices_byte_offset;
  22956. accessor->sparse.indices.componentType = component_type;
  22957. accessor->sparse.values.bufferView = values_buffer_view;
  22958. accessor->sparse.values.byteOffset = values_byte_offset;
  22959. // todo check theses values
  22960. return true;
  22961. }
  22962. static bool ParseAccessor(Accessor *accessor, std::string *err, const json &o,
  22963. bool store_original_json_for_extras_and_extensions)
  22964. {
  22965. int bufferView = -1;
  22966. ParseIntegerProperty(&bufferView, err, o, "bufferView", false, "Accessor");
  22967. size_t byteOffset = 0;
  22968. ParseUnsignedProperty(&byteOffset, err, o, "byteOffset", false, "Accessor");
  22969. bool normalized = false;
  22970. ParseBooleanProperty(&normalized, err, o, "normalized", false, "Accessor");
  22971. size_t componentType = 0;
  22972. if (!ParseUnsignedProperty(&componentType, err, o, "componentType", true,
  22973. "Accessor"))
  22974. {
  22975. return false;
  22976. }
  22977. size_t count = 0;
  22978. if (!ParseUnsignedProperty(&count, err, o, "count", true, "Accessor"))
  22979. {
  22980. return false;
  22981. }
  22982. std::string type;
  22983. if (!ParseStringProperty(&type, err, o, "type", true, "Accessor"))
  22984. {
  22985. return false;
  22986. }
  22987. if (type.compare("SCALAR") == 0)
  22988. {
  22989. accessor->type = TINYGLTF_TYPE_SCALAR;
  22990. }
  22991. else if (type.compare("VEC2") == 0)
  22992. {
  22993. accessor->type = TINYGLTF_TYPE_VEC2;
  22994. }
  22995. else if (type.compare("VEC3") == 0)
  22996. {
  22997. accessor->type = TINYGLTF_TYPE_VEC3;
  22998. }
  22999. else if (type.compare("VEC4") == 0)
  23000. {
  23001. accessor->type = TINYGLTF_TYPE_VEC4;
  23002. }
  23003. else if (type.compare("MAT2") == 0)
  23004. {
  23005. accessor->type = TINYGLTF_TYPE_MAT2;
  23006. }
  23007. else if (type.compare("MAT3") == 0)
  23008. {
  23009. accessor->type = TINYGLTF_TYPE_MAT3;
  23010. }
  23011. else if (type.compare("MAT4") == 0)
  23012. {
  23013. accessor->type = TINYGLTF_TYPE_MAT4;
  23014. }
  23015. else
  23016. {
  23017. std::stringstream ss;
  23018. ss << "Unsupported `type` for accessor object. Got \"" << type << "\"\n";
  23019. if (err)
  23020. {
  23021. (*err) += ss.str();
  23022. }
  23023. return false;
  23024. }
  23025. ParseStringProperty(&accessor->name, err, o, "name", false);
  23026. accessor->minValues.clear();
  23027. accessor->maxValues.clear();
  23028. ParseNumberArrayProperty(&accessor->minValues, err, o, "min", false,
  23029. "Accessor");
  23030. ParseNumberArrayProperty(&accessor->maxValues, err, o, "max", false,
  23031. "Accessor");
  23032. accessor->count = count;
  23033. accessor->bufferView = bufferView;
  23034. accessor->byteOffset = byteOffset;
  23035. accessor->normalized = normalized;
  23036. {
  23037. if (componentType >= TINYGLTF_COMPONENT_TYPE_BYTE &&
  23038. componentType <= TINYGLTF_COMPONENT_TYPE_DOUBLE)
  23039. {
  23040. // OK
  23041. accessor->componentType = int(componentType);
  23042. }
  23043. else
  23044. {
  23045. std::stringstream ss;
  23046. ss << "Invalid `componentType` in accessor. Got " << componentType
  23047. << "\n";
  23048. if (err)
  23049. {
  23050. (*err) += ss.str();
  23051. }
  23052. return false;
  23053. }
  23054. }
  23055. ParseExtensionsProperty(&(accessor->extensions), err, o);
  23056. ParseExtrasProperty(&(accessor->extras), o);
  23057. if (store_original_json_for_extras_and_extensions)
  23058. {
  23059. {
  23060. json_const_iterator it;
  23061. if (FindMember(o, "extensions", it))
  23062. {
  23063. accessor->extensions_json_string = JsonToString(GetValue(it));
  23064. }
  23065. }
  23066. {
  23067. json_const_iterator it;
  23068. if (FindMember(o, "extras", it))
  23069. {
  23070. accessor->extras_json_string = JsonToString(GetValue(it));
  23071. }
  23072. }
  23073. }
  23074. // check if accessor has a "sparse" object:
  23075. json_const_iterator iterator;
  23076. if (FindMember(o, "sparse", iterator))
  23077. {
  23078. // here this accessor has a "sparse" subobject
  23079. return ParseSparseAccessor(accessor, err, GetValue(iterator));
  23080. }
  23081. return true;
  23082. }
  23083. #ifdef TINYGLTF_ENABLE_DRACO
  23084. static void DecodeIndexBuffer(draco::Mesh *mesh, size_t componentSize,
  23085. std::vector<uint8_t> &outBuffer)
  23086. {
  23087. if (componentSize == 4)
  23088. {
  23089. assert(sizeof(mesh->face(draco::FaceIndex(0))[0]) == componentSize);
  23090. memcpy(outBuffer.data(), &mesh->face(draco::FaceIndex(0))[0],
  23091. outBuffer.size());
  23092. }
  23093. else
  23094. {
  23095. size_t faceStride = componentSize * 3;
  23096. for (draco::FaceIndex f(0); f < mesh->num_faces(); ++f)
  23097. {
  23098. const draco::Mesh::Face &face = mesh->face(f);
  23099. if (componentSize == 2)
  23100. {
  23101. uint16_t indices[3] = { (uint16_t)face[0].value(),
  23102. (uint16_t)face[1].value(),
  23103. (uint16_t)face[2].value() };
  23104. memcpy(outBuffer.data() + f.value() * faceStride, &indices[0],
  23105. faceStride);
  23106. }
  23107. else
  23108. {
  23109. uint8_t indices[3] = { (uint8_t)face[0].value(),
  23110. (uint8_t)face[1].value(),
  23111. (uint8_t)face[2].value() };
  23112. memcpy(outBuffer.data() + f.value() * faceStride, &indices[0],
  23113. faceStride);
  23114. }
  23115. }
  23116. }
  23117. }
  23118. template <typename T>
  23119. static bool GetAttributeForAllPoints(draco::Mesh *mesh,
  23120. const draco::PointAttribute *pAttribute,
  23121. std::vector<uint8_t> &outBuffer)
  23122. {
  23123. size_t byteOffset = 0;
  23124. T values[4] = { 0, 0, 0, 0 };
  23125. for (draco::PointIndex i(0); i < mesh->num_points(); ++i)
  23126. {
  23127. const draco::AttributeValueIndex val_index = pAttribute->mapped_index(i);
  23128. if (!pAttribute->ConvertValue<T>(val_index, pAttribute->num_components(),
  23129. values))
  23130. return false;
  23131. memcpy(outBuffer.data() + byteOffset, &values[0],
  23132. sizeof(T) * pAttribute->num_components());
  23133. byteOffset += sizeof(T) * pAttribute->num_components();
  23134. }
  23135. return true;
  23136. }
  23137. static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh *mesh,
  23138. const draco::PointAttribute *pAttribute,
  23139. std::vector<uint8_t> &outBuffer)
  23140. {
  23141. bool decodeResult = false;
  23142. switch (componentType)
  23143. {
  23144. case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
  23145. decodeResult =
  23146. GetAttributeForAllPoints<uint8_t>(mesh, pAttribute, outBuffer);
  23147. break;
  23148. case TINYGLTF_COMPONENT_TYPE_BYTE:
  23149. decodeResult =
  23150. GetAttributeForAllPoints<int8_t>(mesh, pAttribute, outBuffer);
  23151. break;
  23152. case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
  23153. decodeResult =
  23154. GetAttributeForAllPoints<uint16_t>(mesh, pAttribute, outBuffer);
  23155. break;
  23156. case TINYGLTF_COMPONENT_TYPE_SHORT:
  23157. decodeResult =
  23158. GetAttributeForAllPoints<int16_t>(mesh, pAttribute, outBuffer);
  23159. break;
  23160. case TINYGLTF_COMPONENT_TYPE_INT:
  23161. decodeResult =
  23162. GetAttributeForAllPoints<int32_t>(mesh, pAttribute, outBuffer);
  23163. break;
  23164. case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
  23165. decodeResult =
  23166. GetAttributeForAllPoints<uint32_t>(mesh, pAttribute, outBuffer);
  23167. break;
  23168. case TINYGLTF_COMPONENT_TYPE_FLOAT:
  23169. decodeResult =
  23170. GetAttributeForAllPoints<float>(mesh, pAttribute, outBuffer);
  23171. break;
  23172. case TINYGLTF_COMPONENT_TYPE_DOUBLE:
  23173. decodeResult =
  23174. GetAttributeForAllPoints<double>(mesh, pAttribute, outBuffer);
  23175. break;
  23176. default:
  23177. return false;
  23178. }
  23179. return decodeResult;
  23180. }
  23181. static bool ParseDracoExtension(Primitive *primitive, Model *model,
  23182. std::string *err,
  23183. const Value &dracoExtensionValue)
  23184. {
  23185. auto bufferViewValue = dracoExtensionValue.Get("bufferView");
  23186. if (!bufferViewValue.IsInt()) return false;
  23187. auto attributesValue = dracoExtensionValue.Get("attributes");
  23188. if (!attributesValue.IsObject()) return false;
  23189. auto attributesObject = attributesValue.Get<Value::Object>();
  23190. int bufferView = bufferViewValue.Get<int>();
  23191. BufferView &view = model->bufferViews[bufferView];
  23192. Buffer &buffer = model->buffers[view.buffer];
  23193. // BufferView has already been decoded
  23194. if (view.dracoDecoded) return true;
  23195. view.dracoDecoded = true;
  23196. const char *bufferViewData =
  23197. reinterpret_cast<const char *>(buffer.data.data() + view.byteOffset);
  23198. size_t bufferViewSize = view.byteLength;
  23199. // decode draco
  23200. draco::DecoderBuffer decoderBuffer;
  23201. decoderBuffer.Init(bufferViewData, bufferViewSize);
  23202. draco::Decoder decoder;
  23203. auto decodeResult = decoder.DecodeMeshFromBuffer(&decoderBuffer);
  23204. if (!decodeResult.ok())
  23205. {
  23206. return false;
  23207. }
  23208. const std::unique_ptr<draco::Mesh> &mesh = decodeResult.value();
  23209. // create new bufferView for indices
  23210. if (primitive->indices >= 0)
  23211. {
  23212. int32_t componentSize = GetComponentSizeInBytes(
  23213. model->accessors[primitive->indices].componentType);
  23214. Buffer decodedIndexBuffer;
  23215. decodedIndexBuffer.data.resize(mesh->num_faces() * 3 * componentSize);
  23216. DecodeIndexBuffer(mesh.get(), componentSize, decodedIndexBuffer.data);
  23217. model->buffers.emplace_back(std::move(decodedIndexBuffer));
  23218. BufferView decodedIndexBufferView;
  23219. decodedIndexBufferView.buffer = int(model->buffers.size() - 1);
  23220. decodedIndexBufferView.byteLength =
  23221. int(mesh->num_faces() * 3 * componentSize);
  23222. decodedIndexBufferView.byteOffset = 0;
  23223. decodedIndexBufferView.byteStride = 0;
  23224. decodedIndexBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER;
  23225. model->bufferViews.emplace_back(std::move(decodedIndexBufferView));
  23226. model->accessors[primitive->indices].bufferView =
  23227. int(model->bufferViews.size() - 1);
  23228. model->accessors[primitive->indices].count = int(mesh->num_faces() * 3);
  23229. }
  23230. for (const auto &attribute : attributesObject)
  23231. {
  23232. if (!attribute.second.IsInt()) return false;
  23233. auto primitiveAttribute = primitive->attributes.find(attribute.first);
  23234. if (primitiveAttribute == primitive->attributes.end()) return false;
  23235. int dracoAttributeIndex = attribute.second.Get<int>();
  23236. const auto pAttribute = mesh->GetAttributeByUniqueId(dracoAttributeIndex);
  23237. const auto pBuffer = pAttribute->buffer();
  23238. const auto componentType =
  23239. model->accessors[primitiveAttribute->second].componentType;
  23240. // Create a new buffer for this decoded buffer
  23241. Buffer decodedBuffer;
  23242. size_t bufferSize = mesh->num_points() * pAttribute->num_components() *
  23243. GetComponentSizeInBytes(componentType);
  23244. decodedBuffer.data.resize(bufferSize);
  23245. if (!GetAttributeForAllPoints(componentType, mesh.get(), pAttribute,
  23246. decodedBuffer.data))
  23247. return false;
  23248. model->buffers.emplace_back(std::move(decodedBuffer));
  23249. BufferView decodedBufferView;
  23250. decodedBufferView.buffer = int(model->buffers.size() - 1);
  23251. decodedBufferView.byteLength = bufferSize;
  23252. decodedBufferView.byteOffset = pAttribute->byte_offset();
  23253. decodedBufferView.byteStride = pAttribute->byte_stride();
  23254. decodedBufferView.target = primitive->indices >= 0
  23255. ? TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER
  23256. : TINYGLTF_TARGET_ARRAY_BUFFER;
  23257. model->bufferViews.emplace_back(std::move(decodedBufferView));
  23258. model->accessors[primitiveAttribute->second].bufferView =
  23259. int(model->bufferViews.size() - 1);
  23260. model->accessors[primitiveAttribute->second].count =
  23261. int(mesh->num_points());
  23262. }
  23263. return true;
  23264. }
  23265. #endif
  23266. static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
  23267. const json &o,
  23268. bool store_original_json_for_extras_and_extensions)
  23269. {
  23270. int material = -1;
  23271. ParseIntegerProperty(&material, err, o, "material", false);
  23272. primitive->material = material;
  23273. int mode = TINYGLTF_MODE_TRIANGLES;
  23274. ParseIntegerProperty(&mode, err, o, "mode", false);
  23275. primitive->mode = mode; // Why only triangled were supported ?
  23276. int indices = -1;
  23277. ParseIntegerProperty(&indices, err, o, "indices", false);
  23278. primitive->indices = indices;
  23279. if (!ParseStringIntegerProperty(&primitive->attributes, err, o, "attributes",
  23280. true, "Primitive"))
  23281. {
  23282. return false;
  23283. }
  23284. // Look for morph targets
  23285. json_const_iterator targetsObject;
  23286. if (FindMember(o, "targets", targetsObject) &&
  23287. IsArray(GetValue(targetsObject)))
  23288. {
  23289. auto targetsObjectEnd = ArrayEnd(GetValue(targetsObject));
  23290. for (json_const_array_iterator i = ArrayBegin(GetValue(targetsObject));
  23291. i != targetsObjectEnd; ++i)
  23292. {
  23293. std::map<std::string, int> targetAttribues;
  23294. const json &dict = *i;
  23295. if (IsObject(dict))
  23296. {
  23297. json_const_iterator dictIt(ObjectBegin(dict));
  23298. json_const_iterator dictItEnd(ObjectEnd(dict));
  23299. for (; dictIt != dictItEnd; ++dictIt)
  23300. {
  23301. int iVal;
  23302. if (GetInt(GetValue(dictIt), iVal))
  23303. targetAttribues[GetKey(dictIt)] = iVal;
  23304. }
  23305. primitive->targets.emplace_back(std::move(targetAttribues));
  23306. }
  23307. }
  23308. }
  23309. ParseExtrasProperty(&(primitive->extras), o);
  23310. ParseExtensionsProperty(&primitive->extensions, err, o);
  23311. if (store_original_json_for_extras_and_extensions)
  23312. {
  23313. {
  23314. json_const_iterator it;
  23315. if (FindMember(o, "extensions", it))
  23316. {
  23317. primitive->extensions_json_string = JsonToString(GetValue(it));
  23318. }
  23319. }
  23320. {
  23321. json_const_iterator it;
  23322. if (FindMember(o, "extras", it))
  23323. {
  23324. primitive->extras_json_string = JsonToString(GetValue(it));
  23325. }
  23326. }
  23327. }
  23328. #ifdef TINYGLTF_ENABLE_DRACO
  23329. auto dracoExtension =
  23330. primitive->extensions.find("KHR_draco_mesh_compression");
  23331. if (dracoExtension != primitive->extensions.end())
  23332. {
  23333. ParseDracoExtension(primitive, model, err, dracoExtension->second);
  23334. }
  23335. #else
  23336. (void)model;
  23337. #endif
  23338. return true;
  23339. }
  23340. static bool ParseMesh(Mesh *mesh, Model *model, std::string *err, const json &o,
  23341. bool store_original_json_for_extras_and_extensions)
  23342. {
  23343. ParseStringProperty(&mesh->name, err, o, "name", false);
  23344. mesh->primitives.clear();
  23345. json_const_iterator primObject;
  23346. if (FindMember(o, "primitives", primObject) &&
  23347. IsArray(GetValue(primObject)))
  23348. {
  23349. json_const_array_iterator primEnd = ArrayEnd(GetValue(primObject));
  23350. for (json_const_array_iterator i = ArrayBegin(GetValue(primObject));
  23351. i != primEnd; ++i)
  23352. {
  23353. Primitive primitive;
  23354. if (ParsePrimitive(&primitive, model, err, *i,
  23355. store_original_json_for_extras_and_extensions))
  23356. {
  23357. // Only add the primitive if the parsing succeeds.
  23358. mesh->primitives.emplace_back(std::move(primitive));
  23359. }
  23360. }
  23361. }
  23362. // Should probably check if has targets and if dimensions fit
  23363. ParseNumberArrayProperty(&mesh->weights, err, o, "weights", false);
  23364. ParseExtensionsProperty(&mesh->extensions, err, o);
  23365. ParseExtrasProperty(&(mesh->extras), o);
  23366. if (store_original_json_for_extras_and_extensions)
  23367. {
  23368. {
  23369. json_const_iterator it;
  23370. if (FindMember(o, "extensions", it))
  23371. {
  23372. mesh->extensions_json_string = JsonToString(GetValue(it));
  23373. }
  23374. }
  23375. {
  23376. json_const_iterator it;
  23377. if (FindMember(o, "extras", it))
  23378. {
  23379. mesh->extras_json_string = JsonToString(GetValue(it));
  23380. }
  23381. }
  23382. }
  23383. return true;
  23384. }
  23385. static bool ParseNode(Node *node, std::string *err, const json &o,
  23386. bool store_original_json_for_extras_and_extensions)
  23387. {
  23388. ParseStringProperty(&node->name, err, o, "name", false);
  23389. int skin = -1;
  23390. ParseIntegerProperty(&skin, err, o, "skin", false);
  23391. node->skin = skin;
  23392. // Matrix and T/R/S are exclusive
  23393. if (!ParseNumberArrayProperty(&node->matrix, err, o, "matrix", false))
  23394. {
  23395. ParseNumberArrayProperty(&node->rotation, err, o, "rotation", false);
  23396. ParseNumberArrayProperty(&node->scale, err, o, "scale", false);
  23397. ParseNumberArrayProperty(&node->translation, err, o, "translation", false);
  23398. }
  23399. int camera = -1;
  23400. ParseIntegerProperty(&camera, err, o, "camera", false);
  23401. node->camera = camera;
  23402. int mesh = -1;
  23403. ParseIntegerProperty(&mesh, err, o, "mesh", false);
  23404. node->mesh = mesh;
  23405. node->children.clear();
  23406. ParseIntegerArrayProperty(&node->children, err, o, "children", false);
  23407. ParseNumberArrayProperty(&node->weights, err, o, "weights", false);
  23408. ParseExtensionsProperty(&node->extensions, err, o);
  23409. ParseExtrasProperty(&(node->extras), o);
  23410. if (store_original_json_for_extras_and_extensions)
  23411. {
  23412. {
  23413. json_const_iterator it;
  23414. if (FindMember(o, "extensions", it))
  23415. {
  23416. node->extensions_json_string = JsonToString(GetValue(it));
  23417. }
  23418. }
  23419. {
  23420. json_const_iterator it;
  23421. if (FindMember(o, "extras", it))
  23422. {
  23423. node->extras_json_string = JsonToString(GetValue(it));
  23424. }
  23425. }
  23426. }
  23427. return true;
  23428. }
  23429. static bool ParsePbrMetallicRoughness(
  23430. PbrMetallicRoughness *pbr, std::string *err, const json &o,
  23431. bool store_original_json_for_extras_and_extensions)
  23432. {
  23433. if (pbr == nullptr)
  23434. {
  23435. return false;
  23436. }
  23437. std::vector<double> baseColorFactor;
  23438. if (ParseNumberArrayProperty(&baseColorFactor, err, o, "baseColorFactor",
  23439. /* required */ false))
  23440. {
  23441. if (baseColorFactor.size() != 4)
  23442. {
  23443. if (err)
  23444. {
  23445. (*err) +=
  23446. "Array length of `baseColorFactor` parameter in "
  23447. "pbrMetallicRoughness must be 4, but got " +
  23448. std::to_string(baseColorFactor.size()) + "\n";
  23449. }
  23450. return false;
  23451. }
  23452. pbr->baseColorFactor = baseColorFactor;
  23453. }
  23454. {
  23455. json_const_iterator it;
  23456. if (FindMember(o, "baseColorTexture", it))
  23457. {
  23458. ParseTextureInfo(&pbr->baseColorTexture, err, GetValue(it),
  23459. store_original_json_for_extras_and_extensions);
  23460. }
  23461. }
  23462. {
  23463. json_const_iterator it;
  23464. if (FindMember(o, "metallicRoughnessTexture", it))
  23465. {
  23466. ParseTextureInfo(&pbr->metallicRoughnessTexture, err, GetValue(it),
  23467. store_original_json_for_extras_and_extensions);
  23468. }
  23469. }
  23470. ParseNumberProperty(&pbr->metallicFactor, err, o, "metallicFactor", false);
  23471. ParseNumberProperty(&pbr->roughnessFactor, err, o, "roughnessFactor", false);
  23472. ParseExtensionsProperty(&pbr->extensions, err, o);
  23473. ParseExtrasProperty(&pbr->extras, o);
  23474. if (store_original_json_for_extras_and_extensions)
  23475. {
  23476. {
  23477. json_const_iterator it;
  23478. if (FindMember(o, "extensions", it))
  23479. {
  23480. pbr->extensions_json_string = JsonToString(GetValue(it));
  23481. }
  23482. }
  23483. {
  23484. json_const_iterator it;
  23485. if (FindMember(o, "extras", it))
  23486. {
  23487. pbr->extras_json_string = JsonToString(GetValue(it));
  23488. }
  23489. }
  23490. }
  23491. return true;
  23492. }
  23493. static bool ParseMaterial(Material *material, std::string *err, const json &o,
  23494. bool store_original_json_for_extras_and_extensions)
  23495. {
  23496. ParseStringProperty(&material->name, err, o, "name", /* required */ false);
  23497. if (ParseNumberArrayProperty(&material->emissiveFactor, err, o,
  23498. "emissiveFactor",
  23499. /* required */ false))
  23500. {
  23501. if (material->emissiveFactor.size() != 3)
  23502. {
  23503. if (err)
  23504. {
  23505. (*err) +=
  23506. "Array length of `emissiveFactor` parameter in "
  23507. "material must be 3, but got " +
  23508. std::to_string(material->emissiveFactor.size()) + "\n";
  23509. }
  23510. return false;
  23511. }
  23512. }
  23513. else
  23514. {
  23515. // fill with default values
  23516. material->emissiveFactor = { 0.0, 0.0, 0.0 };
  23517. }
  23518. ParseStringProperty(&material->alphaMode, err, o, "alphaMode",
  23519. /* required */ false);
  23520. ParseNumberProperty(&material->alphaCutoff, err, o, "alphaCutoff",
  23521. /* required */ false);
  23522. ParseBooleanProperty(&material->doubleSided, err, o, "doubleSided",
  23523. /* required */ false);
  23524. {
  23525. json_const_iterator it;
  23526. if (FindMember(o, "pbrMetallicRoughness", it))
  23527. {
  23528. ParsePbrMetallicRoughness(&material->pbrMetallicRoughness, err,
  23529. GetValue(it),
  23530. store_original_json_for_extras_and_extensions);
  23531. }
  23532. }
  23533. {
  23534. json_const_iterator it;
  23535. if (FindMember(o, "normalTexture", it))
  23536. {
  23537. ParseNormalTextureInfo(&material->normalTexture, err, GetValue(it),
  23538. store_original_json_for_extras_and_extensions);
  23539. }
  23540. }
  23541. {
  23542. json_const_iterator it;
  23543. if (FindMember(o, "occlusionTexture", it))
  23544. {
  23545. ParseOcclusionTextureInfo(&material->occlusionTexture, err, GetValue(it),
  23546. store_original_json_for_extras_and_extensions);
  23547. }
  23548. }
  23549. {
  23550. json_const_iterator it;
  23551. if (FindMember(o, "emissiveTexture", it))
  23552. {
  23553. ParseTextureInfo(&material->emissiveTexture, err, GetValue(it),
  23554. store_original_json_for_extras_and_extensions);
  23555. }
  23556. }
  23557. // Old code path. For backward compatibility, we still store material values
  23558. // as Parameter. This will create duplicated information for
  23559. // example(pbrMetallicRoughness), but should be neglible in terms of memory
  23560. // consumption.
  23561. // TODO(syoyo): Remove in the next major release.
  23562. material->values.clear();
  23563. material->additionalValues.clear();
  23564. json_const_iterator it(ObjectBegin(o));
  23565. json_const_iterator itEnd(ObjectEnd(o));
  23566. for (; it != itEnd; ++it)
  23567. {
  23568. std::string key(GetKey(it));
  23569. if (key == "pbrMetallicRoughness")
  23570. {
  23571. if (IsObject(GetValue(it)))
  23572. {
  23573. const json &values_object = GetValue(it);
  23574. json_const_iterator itVal(ObjectBegin(values_object));
  23575. json_const_iterator itValEnd(ObjectEnd(values_object));
  23576. for (; itVal != itValEnd; ++itVal)
  23577. {
  23578. Parameter param;
  23579. if (ParseParameterProperty(&param, err, values_object, GetKey(itVal),
  23580. false))
  23581. {
  23582. material->values.emplace(GetKey(itVal), std::move(param));
  23583. }
  23584. }
  23585. }
  23586. }
  23587. else if (key == "extensions" || key == "extras")
  23588. {
  23589. // done later, skip, otherwise poorly parsed contents will be saved in the
  23590. // parametermap and serialized again later
  23591. }
  23592. else
  23593. {
  23594. Parameter param;
  23595. if (ParseParameterProperty(&param, err, o, key, false))
  23596. {
  23597. // names of materials have already been parsed. Putting it in this map
  23598. // doesn't correctly reflext the glTF specification
  23599. if (key != "name")
  23600. material->additionalValues.emplace(std::move(key), std::move(param));
  23601. }
  23602. }
  23603. }
  23604. material->extensions.clear();
  23605. ParseExtensionsProperty(&material->extensions, err, o);
  23606. ParseExtrasProperty(&(material->extras), o);
  23607. if (store_original_json_for_extras_and_extensions)
  23608. {
  23609. {
  23610. json_const_iterator eit;
  23611. if (FindMember(o, "extensions", eit))
  23612. {
  23613. material->extensions_json_string = JsonToString(GetValue(eit));
  23614. }
  23615. }
  23616. {
  23617. json_const_iterator eit;
  23618. if (FindMember(o, "extras", eit))
  23619. {
  23620. material->extras_json_string = JsonToString(GetValue(eit));
  23621. }
  23622. }
  23623. }
  23624. return true;
  23625. }
  23626. static bool ParseAnimationChannel(
  23627. AnimationChannel *channel, std::string *err, const json &o,
  23628. bool store_original_json_for_extras_and_extensions)
  23629. {
  23630. int samplerIndex = -1;
  23631. int targetIndex = -1;
  23632. if (!ParseIntegerProperty(&samplerIndex, err, o, "sampler", true,
  23633. "AnimationChannel"))
  23634. {
  23635. if (err)
  23636. {
  23637. (*err) += "`sampler` field is missing in animation channels\n";
  23638. }
  23639. return false;
  23640. }
  23641. json_const_iterator targetIt;
  23642. if (FindMember(o, "target", targetIt) && IsObject(GetValue(targetIt)))
  23643. {
  23644. const json &target_object = GetValue(targetIt);
  23645. if (!ParseIntegerProperty(&targetIndex, err, target_object, "node", true))
  23646. {
  23647. if (err)
  23648. {
  23649. (*err) += "`node` field is missing in animation.channels.target\n";
  23650. }
  23651. return false;
  23652. }
  23653. if (!ParseStringProperty(&channel->target_path, err, target_object, "path",
  23654. true))
  23655. {
  23656. if (err)
  23657. {
  23658. (*err) += "`path` field is missing in animation.channels.target\n";
  23659. }
  23660. return false;
  23661. }
  23662. ParseExtensionsProperty(&channel->target_extensions, err, target_object);
  23663. if (store_original_json_for_extras_and_extensions)
  23664. {
  23665. json_const_iterator it;
  23666. if (FindMember(target_object, "extensions", it))
  23667. {
  23668. channel->target_extensions_json_string = JsonToString(GetValue(it));
  23669. }
  23670. }
  23671. }
  23672. channel->sampler = samplerIndex;
  23673. channel->target_node = targetIndex;
  23674. ParseExtensionsProperty(&channel->extensions, err, o);
  23675. ParseExtrasProperty(&(channel->extras), o);
  23676. if (store_original_json_for_extras_and_extensions)
  23677. {
  23678. {
  23679. json_const_iterator it;
  23680. if (FindMember(o, "extensions", it))
  23681. {
  23682. channel->extensions_json_string = JsonToString(GetValue(it));
  23683. }
  23684. }
  23685. {
  23686. json_const_iterator it;
  23687. if (FindMember(o, "extras", it))
  23688. {
  23689. channel->extras_json_string = JsonToString(GetValue(it));
  23690. }
  23691. }
  23692. }
  23693. return true;
  23694. }
  23695. static bool ParseAnimation(Animation *animation, std::string *err,
  23696. const json &o,
  23697. bool store_original_json_for_extras_and_extensions)
  23698. {
  23699. {
  23700. json_const_iterator channelsIt;
  23701. if (FindMember(o, "channels", channelsIt) &&
  23702. IsArray(GetValue(channelsIt)))
  23703. {
  23704. json_const_array_iterator channelEnd = ArrayEnd(GetValue(channelsIt));
  23705. for (json_const_array_iterator i = ArrayBegin(GetValue(channelsIt));
  23706. i != channelEnd; ++i)
  23707. {
  23708. AnimationChannel channel;
  23709. if (ParseAnimationChannel(
  23710. &channel, err, *i,
  23711. store_original_json_for_extras_and_extensions))
  23712. {
  23713. // Only add the channel if the parsing succeeds.
  23714. animation->channels.emplace_back(std::move(channel));
  23715. }
  23716. }
  23717. }
  23718. }
  23719. {
  23720. json_const_iterator samplerIt;
  23721. if (FindMember(o, "samplers", samplerIt) && IsArray(GetValue(samplerIt)))
  23722. {
  23723. const json &sampler_array = GetValue(samplerIt);
  23724. json_const_array_iterator it = ArrayBegin(sampler_array);
  23725. json_const_array_iterator itEnd = ArrayEnd(sampler_array);
  23726. for (; it != itEnd; ++it)
  23727. {
  23728. const json &s = *it;
  23729. AnimationSampler sampler;
  23730. int inputIndex = -1;
  23731. int outputIndex = -1;
  23732. if (!ParseIntegerProperty(&inputIndex, err, s, "input", true))
  23733. {
  23734. if (err)
  23735. {
  23736. (*err) += "`input` field is missing in animation.sampler\n";
  23737. }
  23738. return false;
  23739. }
  23740. ParseStringProperty(&sampler.interpolation, err, s, "interpolation",
  23741. false);
  23742. if (!ParseIntegerProperty(&outputIndex, err, s, "output", true))
  23743. {
  23744. if (err)
  23745. {
  23746. (*err) += "`output` field is missing in animation.sampler\n";
  23747. }
  23748. return false;
  23749. }
  23750. sampler.input = inputIndex;
  23751. sampler.output = outputIndex;
  23752. ParseExtensionsProperty(&(sampler.extensions), err, o);
  23753. ParseExtrasProperty(&(sampler.extras), s);
  23754. if (store_original_json_for_extras_and_extensions)
  23755. {
  23756. {
  23757. json_const_iterator eit;
  23758. if (FindMember(o, "extensions", eit))
  23759. {
  23760. sampler.extensions_json_string = JsonToString(GetValue(eit));
  23761. }
  23762. }
  23763. {
  23764. json_const_iterator eit;
  23765. if (FindMember(o, "extras", eit))
  23766. {
  23767. sampler.extras_json_string = JsonToString(GetValue(eit));
  23768. }
  23769. }
  23770. }
  23771. animation->samplers.emplace_back(std::move(sampler));
  23772. }
  23773. }
  23774. }
  23775. ParseStringProperty(&animation->name, err, o, "name", false);
  23776. ParseExtensionsProperty(&animation->extensions, err, o);
  23777. ParseExtrasProperty(&(animation->extras), o);
  23778. if (store_original_json_for_extras_and_extensions)
  23779. {
  23780. {
  23781. json_const_iterator it;
  23782. if (FindMember(o, "extensions", it))
  23783. {
  23784. animation->extensions_json_string = JsonToString(GetValue(it));
  23785. }
  23786. }
  23787. {
  23788. json_const_iterator it;
  23789. if (FindMember(o, "extras", it))
  23790. {
  23791. animation->extras_json_string = JsonToString(GetValue(it));
  23792. }
  23793. }
  23794. }
  23795. return true;
  23796. }
  23797. static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
  23798. bool store_original_json_for_extras_and_extensions)
  23799. {
  23800. ParseStringProperty(&sampler->name, err, o, "name", false);
  23801. int minFilter = -1;
  23802. int magFilter = -1;
  23803. int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
  23804. int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
  23805. int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
  23806. ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
  23807. ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
  23808. ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
  23809. ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
  23810. ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
  23811. // TODO(syoyo): Check the value is alloed one.
  23812. // (e.g. we allow 9728(NEAREST), but don't allow 9727)
  23813. sampler->minFilter = minFilter;
  23814. sampler->magFilter = magFilter;
  23815. sampler->wrapS = wrapS;
  23816. sampler->wrapT = wrapT;
  23817. sampler->wrapR = wrapR;
  23818. ParseExtensionsProperty(&(sampler->extensions), err, o);
  23819. ParseExtrasProperty(&(sampler->extras), o);
  23820. if (store_original_json_for_extras_and_extensions)
  23821. {
  23822. {
  23823. json_const_iterator it;
  23824. if (FindMember(o, "extensions", it))
  23825. {
  23826. sampler->extensions_json_string = JsonToString(GetValue(it));
  23827. }
  23828. }
  23829. {
  23830. json_const_iterator it;
  23831. if (FindMember(o, "extras", it))
  23832. {
  23833. sampler->extras_json_string = JsonToString(GetValue(it));
  23834. }
  23835. }
  23836. }
  23837. return true;
  23838. }
  23839. static bool ParseSkin(Skin *skin, std::string *err, const json &o,
  23840. bool store_original_json_for_extras_and_extensions)
  23841. {
  23842. ParseStringProperty(&skin->name, err, o, "name", false, "Skin");
  23843. std::vector<int> joints;
  23844. if (!ParseIntegerArrayProperty(&joints, err, o, "joints", false, "Skin"))
  23845. {
  23846. return false;
  23847. }
  23848. skin->joints = std::move(joints);
  23849. int skeleton = -1;
  23850. ParseIntegerProperty(&skeleton, err, o, "skeleton", false, "Skin");
  23851. skin->skeleton = skeleton;
  23852. int invBind = -1;
  23853. ParseIntegerProperty(&invBind, err, o, "inverseBindMatrices", true, "Skin");
  23854. skin->inverseBindMatrices = invBind;
  23855. ParseExtensionsProperty(&(skin->extensions), err, o);
  23856. ParseExtrasProperty(&(skin->extras), o);
  23857. if (store_original_json_for_extras_and_extensions)
  23858. {
  23859. {
  23860. json_const_iterator it;
  23861. if (FindMember(o, "extensions", it))
  23862. {
  23863. skin->extensions_json_string = JsonToString(GetValue(it));
  23864. }
  23865. }
  23866. {
  23867. json_const_iterator it;
  23868. if (FindMember(o, "extras", it))
  23869. {
  23870. skin->extras_json_string = JsonToString(GetValue(it));
  23871. }
  23872. }
  23873. }
  23874. return true;
  23875. }
  23876. static bool ParsePerspectiveCamera(
  23877. PerspectiveCamera *camera, std::string *err, const json &o,
  23878. bool store_original_json_for_extras_and_extensions)
  23879. {
  23880. double yfov = 0.0;
  23881. if (!ParseNumberProperty(&yfov, err, o, "yfov", true, "OrthographicCamera"))
  23882. {
  23883. return false;
  23884. }
  23885. double znear = 0.0;
  23886. if (!ParseNumberProperty(&znear, err, o, "znear", true,
  23887. "PerspectiveCamera"))
  23888. {
  23889. return false;
  23890. }
  23891. double aspectRatio = 0.0; // = invalid
  23892. ParseNumberProperty(&aspectRatio, err, o, "aspectRatio", false,
  23893. "PerspectiveCamera");
  23894. double zfar = 0.0; // = invalid
  23895. ParseNumberProperty(&zfar, err, o, "zfar", false, "PerspectiveCamera");
  23896. camera->aspectRatio = aspectRatio;
  23897. camera->zfar = zfar;
  23898. camera->yfov = yfov;
  23899. camera->znear = znear;
  23900. ParseExtensionsProperty(&camera->extensions, err, o);
  23901. ParseExtrasProperty(&(camera->extras), o);
  23902. if (store_original_json_for_extras_and_extensions)
  23903. {
  23904. {
  23905. json_const_iterator it;
  23906. if (FindMember(o, "extensions", it))
  23907. {
  23908. camera->extensions_json_string = JsonToString(GetValue(it));
  23909. }
  23910. }
  23911. {
  23912. json_const_iterator it;
  23913. if (FindMember(o, "extras", it))
  23914. {
  23915. camera->extras_json_string = JsonToString(GetValue(it));
  23916. }
  23917. }
  23918. }
  23919. // TODO(syoyo): Validate parameter values.
  23920. return true;
  23921. }
  23922. static bool ParseSpotLight(SpotLight *light, std::string *err, const json &o,
  23923. bool store_original_json_for_extras_and_extensions)
  23924. {
  23925. ParseNumberProperty(&light->innerConeAngle, err, o, "innerConeAngle", false);
  23926. ParseNumberProperty(&light->outerConeAngle, err, o, "outerConeAngle", false);
  23927. ParseExtensionsProperty(&light->extensions, err, o);
  23928. ParseExtrasProperty(&light->extras, o);
  23929. if (store_original_json_for_extras_and_extensions)
  23930. {
  23931. {
  23932. json_const_iterator it;
  23933. if (FindMember(o, "extensions", it))
  23934. {
  23935. light->extensions_json_string = JsonToString(GetValue(it));
  23936. }
  23937. }
  23938. {
  23939. json_const_iterator it;
  23940. if (FindMember(o, "extras", it))
  23941. {
  23942. light->extras_json_string = JsonToString(GetValue(it));
  23943. }
  23944. }
  23945. }
  23946. // TODO(syoyo): Validate parameter values.
  23947. return true;
  23948. }
  23949. static bool ParseOrthographicCamera(
  23950. OrthographicCamera *camera, std::string *err, const json &o,
  23951. bool store_original_json_for_extras_and_extensions)
  23952. {
  23953. double xmag = 0.0;
  23954. if (!ParseNumberProperty(&xmag, err, o, "xmag", true, "OrthographicCamera"))
  23955. {
  23956. return false;
  23957. }
  23958. double ymag = 0.0;
  23959. if (!ParseNumberProperty(&ymag, err, o, "ymag", true, "OrthographicCamera"))
  23960. {
  23961. return false;
  23962. }
  23963. double zfar = 0.0;
  23964. if (!ParseNumberProperty(&zfar, err, o, "zfar", true, "OrthographicCamera"))
  23965. {
  23966. return false;
  23967. }
  23968. double znear = 0.0;
  23969. if (!ParseNumberProperty(&znear, err, o, "znear", true,
  23970. "OrthographicCamera"))
  23971. {
  23972. return false;
  23973. }
  23974. ParseExtensionsProperty(&camera->extensions, err, o);
  23975. ParseExtrasProperty(&(camera->extras), o);
  23976. if (store_original_json_for_extras_and_extensions)
  23977. {
  23978. {
  23979. json_const_iterator it;
  23980. if (FindMember(o, "extensions", it))
  23981. {
  23982. camera->extensions_json_string = JsonToString(GetValue(it));
  23983. }
  23984. }
  23985. {
  23986. json_const_iterator it;
  23987. if (FindMember(o, "extras", it))
  23988. {
  23989. camera->extras_json_string = JsonToString(GetValue(it));
  23990. }
  23991. }
  23992. }
  23993. camera->xmag = xmag;
  23994. camera->ymag = ymag;
  23995. camera->zfar = zfar;
  23996. camera->znear = znear;
  23997. // TODO(syoyo): Validate parameter values.
  23998. return true;
  23999. }
  24000. static bool ParseCamera(Camera *camera, std::string *err, const json &o,
  24001. bool store_original_json_for_extras_and_extensions)
  24002. {
  24003. if (!ParseStringProperty(&camera->type, err, o, "type", true, "Camera"))
  24004. {
  24005. return false;
  24006. }
  24007. if (camera->type.compare("orthographic") == 0)
  24008. {
  24009. json_const_iterator orthoIt;
  24010. if (!FindMember(o, "orthographic", orthoIt))
  24011. {
  24012. if (err)
  24013. {
  24014. std::stringstream ss;
  24015. ss << "Orhographic camera description not found." << std::endl;
  24016. (*err) += ss.str();
  24017. }
  24018. return false;
  24019. }
  24020. const json &v = GetValue(orthoIt);
  24021. if (!IsObject(v))
  24022. {
  24023. if (err)
  24024. {
  24025. std::stringstream ss;
  24026. ss << "\"orthographic\" is not a JSON object." << std::endl;
  24027. (*err) += ss.str();
  24028. }
  24029. return false;
  24030. }
  24031. if (!ParseOrthographicCamera(
  24032. &camera->orthographic, err, v,
  24033. store_original_json_for_extras_and_extensions))
  24034. {
  24035. return false;
  24036. }
  24037. }
  24038. else if (camera->type.compare("perspective") == 0)
  24039. {
  24040. json_const_iterator perspIt;
  24041. if (!FindMember(o, "perspective", perspIt))
  24042. {
  24043. if (err)
  24044. {
  24045. std::stringstream ss;
  24046. ss << "Perspective camera description not found." << std::endl;
  24047. (*err) += ss.str();
  24048. }
  24049. return false;
  24050. }
  24051. const json &v = GetValue(perspIt);
  24052. if (!IsObject(v))
  24053. {
  24054. if (err)
  24055. {
  24056. std::stringstream ss;
  24057. ss << "\"perspective\" is not a JSON object." << std::endl;
  24058. (*err) += ss.str();
  24059. }
  24060. return false;
  24061. }
  24062. if (!ParsePerspectiveCamera(
  24063. &camera->perspective, err, v,
  24064. store_original_json_for_extras_and_extensions))
  24065. {
  24066. return false;
  24067. }
  24068. }
  24069. else
  24070. {
  24071. if (err)
  24072. {
  24073. std::stringstream ss;
  24074. ss << "Invalid camera type: \"" << camera->type
  24075. << "\". Must be \"perspective\" or \"orthographic\"" << std::endl;
  24076. (*err) += ss.str();
  24077. }
  24078. return false;
  24079. }
  24080. ParseStringProperty(&camera->name, err, o, "name", false);
  24081. ParseExtensionsProperty(&camera->extensions, err, o);
  24082. ParseExtrasProperty(&(camera->extras), o);
  24083. if (store_original_json_for_extras_and_extensions)
  24084. {
  24085. {
  24086. json_const_iterator it;
  24087. if (FindMember(o, "extensions", it))
  24088. {
  24089. camera->extensions_json_string = JsonToString(GetValue(it));
  24090. }
  24091. }
  24092. {
  24093. json_const_iterator it;
  24094. if (FindMember(o, "extras", it))
  24095. {
  24096. camera->extras_json_string = JsonToString(GetValue(it));
  24097. }
  24098. }
  24099. }
  24100. return true;
  24101. }
  24102. static bool ParseLight(Light *light, std::string *err, const json &o,
  24103. bool store_original_json_for_extras_and_extensions)
  24104. {
  24105. if (!ParseStringProperty(&light->type, err, o, "type", true))
  24106. {
  24107. return false;
  24108. }
  24109. if (light->type == "spot")
  24110. {
  24111. json_const_iterator spotIt;
  24112. if (!FindMember(o, "spot", spotIt))
  24113. {
  24114. if (err)
  24115. {
  24116. std::stringstream ss;
  24117. ss << "Spot light description not found." << std::endl;
  24118. (*err) += ss.str();
  24119. }
  24120. return false;
  24121. }
  24122. const json &v = GetValue(spotIt);
  24123. if (!IsObject(v))
  24124. {
  24125. if (err)
  24126. {
  24127. std::stringstream ss;
  24128. ss << "\"spot\" is not a JSON object." << std::endl;
  24129. (*err) += ss.str();
  24130. }
  24131. return false;
  24132. }
  24133. if (!ParseSpotLight(&light->spot, err, v,
  24134. store_original_json_for_extras_and_extensions))
  24135. {
  24136. return false;
  24137. }
  24138. }
  24139. ParseStringProperty(&light->name, err, o, "name", false);
  24140. ParseNumberArrayProperty(&light->color, err, o, "color", false);
  24141. ParseNumberProperty(&light->range, err, o, "range", false);
  24142. ParseNumberProperty(&light->intensity, err, o, "intensity", false);
  24143. ParseExtensionsProperty(&light->extensions, err, o);
  24144. ParseExtrasProperty(&(light->extras), o);
  24145. if (store_original_json_for_extras_and_extensions)
  24146. {
  24147. {
  24148. json_const_iterator it;
  24149. if (FindMember(o, "extensions", it))
  24150. {
  24151. light->extensions_json_string = JsonToString(GetValue(it));
  24152. }
  24153. }
  24154. {
  24155. json_const_iterator it;
  24156. if (FindMember(o, "extras", it))
  24157. {
  24158. light->extras_json_string = JsonToString(GetValue(it));
  24159. }
  24160. }
  24161. }
  24162. return true;
  24163. }
  24164. bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
  24165. const char *json_str,
  24166. unsigned int json_str_length,
  24167. const std::string &base_dir,
  24168. unsigned int check_sections)
  24169. {
  24170. if (json_str_length < 4)
  24171. {
  24172. if (err)
  24173. {
  24174. (*err) = "JSON string too short.\n";
  24175. }
  24176. return false;
  24177. }
  24178. JsonDocument v;
  24179. #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
  24180. defined(_CPPUNWIND)) && \
  24181. !defined(TINYGLTF_NOEXCEPTION)
  24182. try
  24183. {
  24184. JsonParse(v, json_str, json_str_length, true);
  24185. }
  24186. catch (const std::exception &e)
  24187. {
  24188. if (err)
  24189. {
  24190. (*err) = e.what();
  24191. }
  24192. return false;
  24193. }
  24194. #else
  24195. {
  24196. JsonParse(v, json_str, json_str_length);
  24197. if (!IsObject(v))
  24198. {
  24199. // Assume parsing was failed.
  24200. if (err)
  24201. {
  24202. (*err) = "Failed to parse JSON object\n";
  24203. }
  24204. return false;
  24205. }
  24206. }
  24207. #endif
  24208. if (!IsObject(v))
  24209. {
  24210. // root is not an object.
  24211. if (err)
  24212. {
  24213. (*err) = "Root element is not a JSON object\n";
  24214. }
  24215. return false;
  24216. }
  24217. {
  24218. bool version_found = false;
  24219. json_const_iterator it;
  24220. if (FindMember(v, "asset", it) && IsObject(GetValue(it)))
  24221. {
  24222. auto &itObj = GetValue(it);
  24223. json_const_iterator version_it;
  24224. std::string versionStr;
  24225. if (FindMember(itObj, "version", version_it) &&
  24226. GetString(GetValue(version_it), versionStr))
  24227. {
  24228. version_found = true;
  24229. }
  24230. }
  24231. if (version_found)
  24232. {
  24233. // OK
  24234. }
  24235. else if (check_sections & REQUIRE_VERSION)
  24236. {
  24237. if (err)
  24238. {
  24239. (*err) += "\"asset\" object not found in .gltf or not an object type\n";
  24240. }
  24241. return false;
  24242. }
  24243. }
  24244. // scene is not mandatory.
  24245. // FIXME Maybe a better way to handle it than removing the code
  24246. auto IsArrayMemberPresent = [](const json &_v, const char *name) -> bool
  24247. {
  24248. json_const_iterator it;
  24249. return FindMember(_v, name, it) && IsArray(GetValue(it));
  24250. };
  24251. {
  24252. if ((check_sections & REQUIRE_SCENES) &&
  24253. !IsArrayMemberPresent(v, "scenes"))
  24254. {
  24255. if (err)
  24256. {
  24257. (*err) += "\"scenes\" object not found in .gltf or not an array type\n";
  24258. }
  24259. return false;
  24260. }
  24261. }
  24262. {
  24263. if ((check_sections & REQUIRE_NODES) && !IsArrayMemberPresent(v, "nodes"))
  24264. {
  24265. if (err)
  24266. {
  24267. (*err) += "\"nodes\" object not found in .gltf\n";
  24268. }
  24269. return false;
  24270. }
  24271. }
  24272. {
  24273. if ((check_sections & REQUIRE_ACCESSORS) &&
  24274. !IsArrayMemberPresent(v, "accessors"))
  24275. {
  24276. if (err)
  24277. {
  24278. (*err) += "\"accessors\" object not found in .gltf\n";
  24279. }
  24280. return false;
  24281. }
  24282. }
  24283. {
  24284. if ((check_sections & REQUIRE_BUFFERS) &&
  24285. !IsArrayMemberPresent(v, "buffers"))
  24286. {
  24287. if (err)
  24288. {
  24289. (*err) += "\"buffers\" object not found in .gltf\n";
  24290. }
  24291. return false;
  24292. }
  24293. }
  24294. {
  24295. if ((check_sections & REQUIRE_BUFFER_VIEWS) &&
  24296. !IsArrayMemberPresent(v, "bufferViews"))
  24297. {
  24298. if (err)
  24299. {
  24300. (*err) += "\"bufferViews\" object not found in .gltf\n";
  24301. }
  24302. return false;
  24303. }
  24304. }
  24305. model->buffers.clear();
  24306. model->bufferViews.clear();
  24307. model->accessors.clear();
  24308. model->meshes.clear();
  24309. model->cameras.clear();
  24310. model->nodes.clear();
  24311. model->extensionsUsed.clear();
  24312. model->extensionsRequired.clear();
  24313. model->extensions.clear();
  24314. model->defaultScene = -1;
  24315. // 1. Parse Asset
  24316. {
  24317. json_const_iterator it;
  24318. if (FindMember(v, "asset", it) && IsObject(GetValue(it)))
  24319. {
  24320. const json &root = GetValue(it);
  24321. ParseAsset(&model->asset, err, root,
  24322. store_original_json_for_extras_and_extensions_);
  24323. }
  24324. }
  24325. #ifdef TINYGLTF_USE_CPP14
  24326. auto ForEachInArray = [](const json &_v, const char *member,
  24327. const auto &cb) -> bool
  24328. #else
  24329. // The std::function<> implementation can be less efficient because it will
  24330. // allocate heap when the size of the captured lambda is above 16 bytes with
  24331. // clang and gcc, but it does not require C++14.
  24332. auto ForEachInArray = [](const json &_v, const char *member,
  24333. const std::function<bool(const json &)> &cb) -> bool
  24334. #endif
  24335. {
  24336. json_const_iterator itm;
  24337. if (FindMember(_v, member, itm) && IsArray(GetValue(itm)))
  24338. {
  24339. const json &root = GetValue(itm);
  24340. auto it = ArrayBegin(root);
  24341. auto end = ArrayEnd(root);
  24342. for (; it != end; ++it)
  24343. {
  24344. if (!cb(*it)) return false;
  24345. }
  24346. }
  24347. return true;
  24348. };
  24349. // 2. Parse extensionUsed
  24350. {
  24351. ForEachInArray(v, "extensionsUsed", [&](const json &o)
  24352. {
  24353. std::string str;
  24354. GetString(o, str);
  24355. model->extensionsUsed.emplace_back(std::move(str));
  24356. return true;
  24357. });
  24358. }
  24359. {
  24360. ForEachInArray(v, "extensionsRequired", [&](const json &o)
  24361. {
  24362. std::string str;
  24363. GetString(o, str);
  24364. model->extensionsRequired.emplace_back(std::move(str));
  24365. return true;
  24366. });
  24367. }
  24368. // 3. Parse Buffer
  24369. {
  24370. bool success = ForEachInArray(v, "buffers", [&](const json &o)
  24371. {
  24372. if (!IsObject(o))
  24373. {
  24374. if (err)
  24375. {
  24376. (*err) += "`buffers' does not contain an JSON object.";
  24377. }
  24378. return false;
  24379. }
  24380. Buffer buffer;
  24381. if (!ParseBuffer(&buffer, err, o,
  24382. store_original_json_for_extras_and_extensions_, &fs,
  24383. base_dir, is_binary_, bin_data_, bin_size_))
  24384. {
  24385. return false;
  24386. }
  24387. model->buffers.emplace_back(std::move(buffer));
  24388. return true;
  24389. });
  24390. if (!success)
  24391. {
  24392. return false;
  24393. }
  24394. }
  24395. // 4. Parse BufferView
  24396. {
  24397. bool success = ForEachInArray(v, "bufferViews", [&](const json &o)
  24398. {
  24399. if (!IsObject(o))
  24400. {
  24401. if (err)
  24402. {
  24403. (*err) += "`bufferViews' does not contain an JSON object.";
  24404. }
  24405. return false;
  24406. }
  24407. BufferView bufferView;
  24408. if (!ParseBufferView(&bufferView, err, o,
  24409. store_original_json_for_extras_and_extensions_))
  24410. {
  24411. return false;
  24412. }
  24413. model->bufferViews.emplace_back(std::move(bufferView));
  24414. return true;
  24415. });
  24416. if (!success)
  24417. {
  24418. return false;
  24419. }
  24420. }
  24421. // 5. Parse Accessor
  24422. {
  24423. bool success = ForEachInArray(v, "accessors", [&](const json &o)
  24424. {
  24425. if (!IsObject(o))
  24426. {
  24427. if (err)
  24428. {
  24429. (*err) += "`accessors' does not contain an JSON object.";
  24430. }
  24431. return false;
  24432. }
  24433. Accessor accessor;
  24434. if (!ParseAccessor(&accessor, err, o,
  24435. store_original_json_for_extras_and_extensions_))
  24436. {
  24437. return false;
  24438. }
  24439. model->accessors.emplace_back(std::move(accessor));
  24440. return true;
  24441. });
  24442. if (!success)
  24443. {
  24444. return false;
  24445. }
  24446. }
  24447. // 6. Parse Mesh
  24448. {
  24449. bool success = ForEachInArray(v, "meshes", [&](const json &o)
  24450. {
  24451. if (!IsObject(o))
  24452. {
  24453. if (err)
  24454. {
  24455. (*err) += "`meshes' does not contain an JSON object.";
  24456. }
  24457. return false;
  24458. }
  24459. Mesh mesh;
  24460. if (!ParseMesh(&mesh, model, err, o,
  24461. store_original_json_for_extras_and_extensions_))
  24462. {
  24463. return false;
  24464. }
  24465. model->meshes.emplace_back(std::move(mesh));
  24466. return true;
  24467. });
  24468. if (!success)
  24469. {
  24470. return false;
  24471. }
  24472. }
  24473. // Assign missing bufferView target types
  24474. // - Look for missing Mesh indices
  24475. // - Look for missing Mesh attributes
  24476. for (auto &mesh : model->meshes)
  24477. {
  24478. for (auto &primitive : mesh.primitives)
  24479. {
  24480. if (primitive.indices >
  24481. -1) // has indices from parsing step, must be Element Array Buffer
  24482. {
  24483. if (size_t(primitive.indices) >= model->accessors.size())
  24484. {
  24485. if (err)
  24486. {
  24487. (*err) += "primitive indices accessor out of bounds";
  24488. }
  24489. return false;
  24490. }
  24491. auto bufferView =
  24492. model->accessors[size_t(primitive.indices)].bufferView;
  24493. if (bufferView < 0 || size_t(bufferView) >= model->bufferViews.size())
  24494. {
  24495. if (err)
  24496. {
  24497. (*err) += "accessor[" + std::to_string(primitive.indices) +
  24498. "] invalid bufferView";
  24499. }
  24500. return false;
  24501. }
  24502. model->bufferViews[size_t(bufferView)].target =
  24503. TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
  24504. // we could optionally check if acessors' bufferView type is Scalar, as
  24505. // it should be
  24506. }
  24507. for (auto &attribute : primitive.attributes)
  24508. {
  24509. model
  24510. ->bufferViews[size_t(
  24511. model->accessors[size_t(attribute.second)].bufferView)]
  24512. .target = TINYGLTF_TARGET_ARRAY_BUFFER;
  24513. }
  24514. for (auto &target : primitive.targets)
  24515. {
  24516. for (auto &attribute : target)
  24517. {
  24518. auto bufferView =
  24519. model->accessors[size_t(attribute.second)].bufferView;
  24520. // bufferView could be null(-1) for sparse morph target
  24521. if (bufferView >= 0)
  24522. {
  24523. model->bufferViews[size_t(bufferView)].target =
  24524. TINYGLTF_TARGET_ARRAY_BUFFER;
  24525. }
  24526. }
  24527. }
  24528. }
  24529. }
  24530. // 7. Parse Node
  24531. {
  24532. bool success = ForEachInArray(v, "nodes", [&](const json &o)
  24533. {
  24534. if (!IsObject(o))
  24535. {
  24536. if (err)
  24537. {
  24538. (*err) += "`nodes' does not contain an JSON object.";
  24539. }
  24540. return false;
  24541. }
  24542. Node node;
  24543. if (!ParseNode(&node, err, o,
  24544. store_original_json_for_extras_and_extensions_))
  24545. {
  24546. return false;
  24547. }
  24548. model->nodes.emplace_back(std::move(node));
  24549. return true;
  24550. });
  24551. if (!success)
  24552. {
  24553. return false;
  24554. }
  24555. }
  24556. // 8. Parse scenes.
  24557. {
  24558. bool success = ForEachInArray(v, "scenes", [&](const json &o)
  24559. {
  24560. if (!IsObject(o))
  24561. {
  24562. if (err)
  24563. {
  24564. (*err) += "`scenes' does not contain an JSON object.";
  24565. }
  24566. return false;
  24567. }
  24568. std::vector<int> nodes;
  24569. ParseIntegerArrayProperty(&nodes, err, o, "nodes", false);
  24570. Scene scene;
  24571. scene.nodes = std::move(nodes);
  24572. ParseStringProperty(&scene.name, err, o, "name", false);
  24573. ParseExtensionsProperty(&scene.extensions, err, o);
  24574. ParseExtrasProperty(&scene.extras, o);
  24575. if (store_original_json_for_extras_and_extensions_)
  24576. {
  24577. {
  24578. json_const_iterator it;
  24579. if (FindMember(o, "extensions", it))
  24580. {
  24581. model->extensions_json_string = JsonToString(GetValue(it));
  24582. }
  24583. }
  24584. {
  24585. json_const_iterator it;
  24586. if (FindMember(o, "extras", it))
  24587. {
  24588. model->extras_json_string = JsonToString(GetValue(it));
  24589. }
  24590. }
  24591. }
  24592. model->scenes.emplace_back(std::move(scene));
  24593. return true;
  24594. });
  24595. if (!success)
  24596. {
  24597. return false;
  24598. }
  24599. }
  24600. // 9. Parse default scenes.
  24601. {
  24602. json_const_iterator rootIt;
  24603. int iVal;
  24604. if (FindMember(v, "scene", rootIt) && GetInt(GetValue(rootIt), iVal))
  24605. {
  24606. model->defaultScene = iVal;
  24607. }
  24608. }
  24609. // 10. Parse Material
  24610. {
  24611. bool success = ForEachInArray(v, "materials", [&](const json &o)
  24612. {
  24613. if (!IsObject(o))
  24614. {
  24615. if (err)
  24616. {
  24617. (*err) += "`materials' does not contain an JSON object.";
  24618. }
  24619. return false;
  24620. }
  24621. Material material;
  24622. ParseStringProperty(&material.name, err, o, "name", false);
  24623. if (!ParseMaterial(&material, err, o,
  24624. store_original_json_for_extras_and_extensions_))
  24625. {
  24626. return false;
  24627. }
  24628. model->materials.emplace_back(std::move(material));
  24629. return true;
  24630. });
  24631. if (!success)
  24632. {
  24633. return false;
  24634. }
  24635. }
  24636. // 11. Parse Image
  24637. void *load_image_user_data{ nullptr };
  24638. LoadImageDataOption load_image_option;
  24639. if (user_image_loader_)
  24640. {
  24641. // Use user supplied pointer
  24642. load_image_user_data = load_image_user_data_;
  24643. }
  24644. else
  24645. {
  24646. load_image_option.preserve_channels = preserve_image_channels_;
  24647. load_image_user_data = reinterpret_cast<void *>(&load_image_option);
  24648. }
  24649. {
  24650. int idx = 0;
  24651. bool success = ForEachInArray(v, "images", [&](const json &o)
  24652. {
  24653. if (!IsObject(o))
  24654. {
  24655. if (err)
  24656. {
  24657. (*err) += "image[" + std::to_string(idx) + "] is not a JSON object.";
  24658. }
  24659. return false;
  24660. }
  24661. Image image;
  24662. if (!ParseImage(&image, idx, err, warn, o,
  24663. store_original_json_for_extras_and_extensions_, base_dir,
  24664. &fs, &this->LoadImageData, load_image_user_data))
  24665. {
  24666. return false;
  24667. }
  24668. if (image.bufferView != -1)
  24669. {
  24670. // Load image from the buffer view.
  24671. if (size_t(image.bufferView) >= model->bufferViews.size())
  24672. {
  24673. if (err)
  24674. {
  24675. std::stringstream ss;
  24676. ss << "image[" << idx << "] bufferView \"" << image.bufferView
  24677. << "\" not found in the scene." << std::endl;
  24678. (*err) += ss.str();
  24679. }
  24680. return false;
  24681. }
  24682. const BufferView &bufferView =
  24683. model->bufferViews[size_t(image.bufferView)];
  24684. if (size_t(bufferView.buffer) >= model->buffers.size())
  24685. {
  24686. if (err)
  24687. {
  24688. std::stringstream ss;
  24689. ss << "image[" << idx << "] buffer \"" << bufferView.buffer
  24690. << "\" not found in the scene." << std::endl;
  24691. (*err) += ss.str();
  24692. }
  24693. return false;
  24694. }
  24695. const Buffer &buffer = model->buffers[size_t(bufferView.buffer)];
  24696. if (*LoadImageData == nullptr)
  24697. {
  24698. if (err)
  24699. {
  24700. (*err) += "No LoadImageData callback specified.\n";
  24701. }
  24702. return false;
  24703. }
  24704. bool ret = LoadImageData(
  24705. &image, idx, err, warn, image.width, image.height,
  24706. &buffer.data[bufferView.byteOffset],
  24707. static_cast<int>(bufferView.byteLength), load_image_user_data);
  24708. if (!ret)
  24709. {
  24710. return false;
  24711. }
  24712. }
  24713. model->images.emplace_back(std::move(image));
  24714. ++idx;
  24715. return true;
  24716. });
  24717. if (!success)
  24718. {
  24719. return false;
  24720. }
  24721. }
  24722. // 12. Parse Texture
  24723. {
  24724. bool success = ForEachInArray(v, "textures", [&](const json &o)
  24725. {
  24726. if (!IsObject(o))
  24727. {
  24728. if (err)
  24729. {
  24730. (*err) += "`textures' does not contain an JSON object.";
  24731. }
  24732. return false;
  24733. }
  24734. Texture texture;
  24735. if (!ParseTexture(&texture, err, o,
  24736. store_original_json_for_extras_and_extensions_,
  24737. base_dir))
  24738. {
  24739. return false;
  24740. }
  24741. model->textures.emplace_back(std::move(texture));
  24742. return true;
  24743. });
  24744. if (!success)
  24745. {
  24746. return false;
  24747. }
  24748. }
  24749. // 13. Parse Animation
  24750. {
  24751. bool success = ForEachInArray(v, "animations", [&](const json &o)
  24752. {
  24753. if (!IsObject(o))
  24754. {
  24755. if (err)
  24756. {
  24757. (*err) += "`animations' does not contain an JSON object.";
  24758. }
  24759. return false;
  24760. }
  24761. Animation animation;
  24762. if (!ParseAnimation(&animation, err, o,
  24763. store_original_json_for_extras_and_extensions_))
  24764. {
  24765. return false;
  24766. }
  24767. model->animations.emplace_back(std::move(animation));
  24768. return true;
  24769. });
  24770. if (!success)
  24771. {
  24772. return false;
  24773. }
  24774. }
  24775. // 14. Parse Skin
  24776. {
  24777. bool success = ForEachInArray(v, "skins", [&](const json &o)
  24778. {
  24779. if (!IsObject(o))
  24780. {
  24781. if (err)
  24782. {
  24783. (*err) += "`skins' does not contain an JSON object.";
  24784. }
  24785. return false;
  24786. }
  24787. Skin skin;
  24788. if (!ParseSkin(&skin, err, o,
  24789. store_original_json_for_extras_and_extensions_))
  24790. {
  24791. return false;
  24792. }
  24793. model->skins.emplace_back(std::move(skin));
  24794. return true;
  24795. });
  24796. if (!success)
  24797. {
  24798. return false;
  24799. }
  24800. }
  24801. // 15. Parse Sampler
  24802. {
  24803. bool success = ForEachInArray(v, "samplers", [&](const json &o)
  24804. {
  24805. if (!IsObject(o))
  24806. {
  24807. if (err)
  24808. {
  24809. (*err) += "`samplers' does not contain an JSON object.";
  24810. }
  24811. return false;
  24812. }
  24813. Sampler sampler;
  24814. if (!ParseSampler(&sampler, err, o,
  24815. store_original_json_for_extras_and_extensions_))
  24816. {
  24817. return false;
  24818. }
  24819. model->samplers.emplace_back(std::move(sampler));
  24820. return true;
  24821. });
  24822. if (!success)
  24823. {
  24824. return false;
  24825. }
  24826. }
  24827. // 16. Parse Camera
  24828. {
  24829. bool success = ForEachInArray(v, "cameras", [&](const json &o)
  24830. {
  24831. if (!IsObject(o))
  24832. {
  24833. if (err)
  24834. {
  24835. (*err) += "`cameras' does not contain an JSON object.";
  24836. }
  24837. return false;
  24838. }
  24839. Camera camera;
  24840. if (!ParseCamera(&camera, err, o,
  24841. store_original_json_for_extras_and_extensions_))
  24842. {
  24843. return false;
  24844. }
  24845. model->cameras.emplace_back(std::move(camera));
  24846. return true;
  24847. });
  24848. if (!success)
  24849. {
  24850. return false;
  24851. }
  24852. }
  24853. // 17. Parse Extensions
  24854. ParseExtensionsProperty(&model->extensions, err, v);
  24855. // 18. Specific extension implementations
  24856. {
  24857. json_const_iterator rootIt;
  24858. if (FindMember(v, "extensions", rootIt) && IsObject(GetValue(rootIt)))
  24859. {
  24860. const json &root = GetValue(rootIt);
  24861. json_const_iterator it(ObjectBegin(root));
  24862. json_const_iterator itEnd(ObjectEnd(root));
  24863. for (; it != itEnd; ++it)
  24864. {
  24865. // parse KHR_lights_punctual extension
  24866. std::string key(GetKey(it));
  24867. if ((key == "KHR_lights_punctual") && IsObject(GetValue(it)))
  24868. {
  24869. const json &object = GetValue(it);
  24870. json_const_iterator itLight;
  24871. if (FindMember(object, "lights", itLight))
  24872. {
  24873. const json &lights = GetValue(itLight);
  24874. if (!IsArray(lights))
  24875. {
  24876. continue;
  24877. }
  24878. auto arrayIt(ArrayBegin(lights));
  24879. auto arrayItEnd(ArrayEnd(lights));
  24880. for (; arrayIt != arrayItEnd; ++arrayIt)
  24881. {
  24882. Light light;
  24883. if (!ParseLight(&light, err, *arrayIt,
  24884. store_original_json_for_extras_and_extensions_))
  24885. {
  24886. return false;
  24887. }
  24888. model->lights.emplace_back(std::move(light));
  24889. }
  24890. }
  24891. }
  24892. }
  24893. }
  24894. }
  24895. // 19. Parse Extras
  24896. ParseExtrasProperty(&model->extras, v);
  24897. if (store_original_json_for_extras_and_extensions_)
  24898. {
  24899. model->extras_json_string = JsonToString(v["extras"]);
  24900. model->extensions_json_string = JsonToString(v["extensions"]);
  24901. }
  24902. return true;
  24903. }
  24904. bool TinyGLTF::LoadASCIIFromString(Model *model, std::string *err,
  24905. std::string *warn, const char *str,
  24906. unsigned int length,
  24907. const std::string &base_dir,
  24908. unsigned int check_sections)
  24909. {
  24910. is_binary_ = false;
  24911. bin_data_ = nullptr;
  24912. bin_size_ = 0;
  24913. return LoadFromString(model, err, warn, str, length, base_dir,
  24914. check_sections);
  24915. }
  24916. bool TinyGLTF::LoadASCIIFromFile(Model *model, std::string *err,
  24917. std::string *warn, const std::string &filename,
  24918. unsigned int check_sections)
  24919. {
  24920. std::stringstream ss;
  24921. if (fs.ReadWholeFile == nullptr)
  24922. {
  24923. // Programmer error, assert() ?
  24924. ss << "Failed to read file: " << filename
  24925. << ": one or more FS callback not set" << std::endl;
  24926. if (err)
  24927. {
  24928. (*err) = ss.str();
  24929. }
  24930. return false;
  24931. }
  24932. std::vector<unsigned char> data;
  24933. std::string fileerr;
  24934. bool fileread = fs.ReadWholeFile(&data, &fileerr, filename, fs.user_data);
  24935. if (!fileread)
  24936. {
  24937. ss << "Failed to read file: " << filename << ": " << fileerr << std::endl;
  24938. if (err)
  24939. {
  24940. (*err) = ss.str();
  24941. }
  24942. return false;
  24943. }
  24944. size_t sz = data.size();
  24945. if (sz == 0)
  24946. {
  24947. if (err)
  24948. {
  24949. (*err) = "Empty file.";
  24950. }
  24951. return false;
  24952. }
  24953. std::string basedir = GetBaseDir(filename);
  24954. bool ret = LoadASCIIFromString(
  24955. model, err, warn, reinterpret_cast<const char *>(&data.at(0)),
  24956. static_cast<unsigned int>(data.size()), basedir, check_sections);
  24957. return ret;
  24958. }
  24959. bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,
  24960. std::string *warn,
  24961. const unsigned char *bytes,
  24962. unsigned int size,
  24963. const std::string &base_dir,
  24964. unsigned int check_sections)
  24965. {
  24966. if (size < 20)
  24967. {
  24968. if (err)
  24969. {
  24970. (*err) = "Too short data size for glTF Binary.";
  24971. }
  24972. return false;
  24973. }
  24974. if (bytes[0] == 'g' && bytes[1] == 'l' && bytes[2] == 'T' &&
  24975. bytes[3] == 'F')
  24976. {
  24977. // ok
  24978. }
  24979. else
  24980. {
  24981. if (err)
  24982. {
  24983. (*err) = "Invalid magic.";
  24984. }
  24985. return false;
  24986. }
  24987. unsigned int version; // 4 bytes
  24988. unsigned int length; // 4 bytes
  24989. unsigned int model_length; // 4 bytes
  24990. unsigned int model_format; // 4 bytes;
  24991. // @todo { Endian swap for big endian machine. }
  24992. memcpy(&version, bytes + 4, 4);
  24993. swap4(&version);
  24994. memcpy(&length, bytes + 8, 4);
  24995. swap4(&length);
  24996. memcpy(&model_length, bytes + 12, 4);
  24997. swap4(&model_length);
  24998. memcpy(&model_format, bytes + 16, 4);
  24999. swap4(&model_format);
  25000. // In case the Bin buffer is not present, the size is exactly 20 + size of
  25001. // JSON contents,
  25002. // so use "greater than" operator.
  25003. if ((20 + model_length > size) || (model_length < 1) || (length > size) ||
  25004. (20 + model_length > length) ||
  25005. (model_format != 0x4E4F534A))
  25006. { // 0x4E4F534A = JSON format.
  25007. if (err)
  25008. {
  25009. (*err) = "Invalid glTF binary.";
  25010. }
  25011. return false;
  25012. }
  25013. // Extract JSON string.
  25014. std::string jsonString(reinterpret_cast<const char *>(&bytes[20]),
  25015. model_length);
  25016. is_binary_ = true;
  25017. bin_data_ = bytes + 20 + model_length +
  25018. 8; // 4 bytes (buffer_length) + 4 bytes(buffer_format)
  25019. bin_size_ =
  25020. length - (20 + model_length); // extract header + JSON scene data.
  25021. bool ret = LoadFromString(model, err, warn,
  25022. reinterpret_cast<const char *>(&bytes[20]),
  25023. model_length, base_dir, check_sections);
  25024. if (!ret)
  25025. {
  25026. return ret;
  25027. }
  25028. return true;
  25029. }
  25030. bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err,
  25031. std::string *warn,
  25032. const std::string &filename,
  25033. unsigned int check_sections)
  25034. {
  25035. std::stringstream ss;
  25036. if (fs.ReadWholeFile == nullptr)
  25037. {
  25038. // Programmer error, assert() ?
  25039. ss << "Failed to read file: " << filename
  25040. << ": one or more FS callback not set" << std::endl;
  25041. if (err)
  25042. {
  25043. (*err) = ss.str();
  25044. }
  25045. return false;
  25046. }
  25047. std::vector<unsigned char> data;
  25048. std::string fileerr;
  25049. bool fileread = fs.ReadWholeFile(&data, &fileerr, filename, fs.user_data);
  25050. if (!fileread)
  25051. {
  25052. ss << "Failed to read file: " << filename << ": " << fileerr << std::endl;
  25053. if (err)
  25054. {
  25055. (*err) = ss.str();
  25056. }
  25057. return false;
  25058. }
  25059. std::string basedir = GetBaseDir(filename);
  25060. bool ret = LoadBinaryFromMemory(model, err, warn, &data.at(0),
  25061. static_cast<unsigned int>(data.size()),
  25062. basedir, check_sections);
  25063. return ret;
  25064. }
  25065. ///////////////////////
  25066. // GLTF Serialization
  25067. ///////////////////////
  25068. namespace
  25069. {
  25070. json JsonFromString(const char *s)
  25071. {
  25072. #ifdef TINYGLTF_USE_RAPIDJSON
  25073. return json(s, GetAllocator());
  25074. #else
  25075. return json(s);
  25076. #endif
  25077. }
  25078. void JsonAssign(json &dest, const json &src)
  25079. {
  25080. #ifdef TINYGLTF_USE_RAPIDJSON
  25081. dest.CopyFrom(src, GetAllocator());
  25082. #else
  25083. dest = src;
  25084. #endif
  25085. }
  25086. void JsonAddMember(json &o, const char *key, json &&value)
  25087. {
  25088. #ifdef TINYGLTF_USE_RAPIDJSON
  25089. if (!o.IsObject())
  25090. {
  25091. o.SetObject();
  25092. }
  25093. o.AddMember(json(key, GetAllocator()), std::move(value), GetAllocator());
  25094. #else
  25095. o[key] = std::move(value);
  25096. #endif
  25097. }
  25098. void JsonPushBack(json &o, json &&value)
  25099. {
  25100. #ifdef TINYGLTF_USE_RAPIDJSON
  25101. o.PushBack(std::move(value), GetAllocator());
  25102. #else
  25103. o.push_back(std::move(value));
  25104. #endif
  25105. }
  25106. bool JsonIsNull(const json &o)
  25107. {
  25108. #ifdef TINYGLTF_USE_RAPIDJSON
  25109. return o.IsNull();
  25110. #else
  25111. return o.is_null();
  25112. #endif
  25113. }
  25114. void JsonSetObject(json &o)
  25115. {
  25116. #ifdef TINYGLTF_USE_RAPIDJSON
  25117. o.SetObject();
  25118. #else
  25119. o = o.object({});
  25120. #endif
  25121. }
  25122. void JsonReserveArray(json &o, size_t s)
  25123. {
  25124. #ifdef TINYGLTF_USE_RAPIDJSON
  25125. o.SetArray();
  25126. o.Reserve(static_cast<rapidjson::SizeType>(s), GetAllocator());
  25127. #endif
  25128. (void)(o);
  25129. (void)(s);
  25130. }
  25131. } // namespace
  25132. // typedef std::pair<std::string, json> json_object_pair;
  25133. template <typename T>
  25134. static void SerializeNumberProperty(const std::string &key, T number,
  25135. json &obj)
  25136. {
  25137. // obj.insert(
  25138. // json_object_pair(key, json(static_cast<double>(number))));
  25139. // obj[key] = static_cast<double>(number);
  25140. JsonAddMember(obj, key.c_str(), json(number));
  25141. }
  25142. #ifdef TINYGLTF_USE_RAPIDJSON
  25143. template <>
  25144. void SerializeNumberProperty(const std::string &key, size_t number, json &obj)
  25145. {
  25146. JsonAddMember(obj, key.c_str(), json(static_cast<uint64_t>(number)));
  25147. }
  25148. #endif
  25149. template <typename T>
  25150. static void SerializeNumberArrayProperty(const std::string &key,
  25151. const std::vector<T> &value,
  25152. json &obj)
  25153. {
  25154. if (value.empty()) return;
  25155. json ary;
  25156. JsonReserveArray(ary, value.size());
  25157. for (const auto &s : value)
  25158. {
  25159. JsonPushBack(ary, json(s));
  25160. }
  25161. JsonAddMember(obj, key.c_str(), std::move(ary));
  25162. }
  25163. static void SerializeStringProperty(const std::string &key,
  25164. const std::string &value, json &obj)
  25165. {
  25166. JsonAddMember(obj, key.c_str(), JsonFromString(value.c_str()));
  25167. }
  25168. static void SerializeStringArrayProperty(const std::string &key,
  25169. const std::vector<std::string> &value,
  25170. json &obj)
  25171. {
  25172. json ary;
  25173. JsonReserveArray(ary, value.size());
  25174. for (auto &s : value)
  25175. {
  25176. JsonPushBack(ary, JsonFromString(s.c_str()));
  25177. }
  25178. JsonAddMember(obj, key.c_str(), std::move(ary));
  25179. }
  25180. static bool ValueToJson(const Value &value, json *ret)
  25181. {
  25182. json obj;
  25183. #ifdef TINYGLTF_USE_RAPIDJSON
  25184. switch (value.Type())
  25185. {
  25186. case REAL_TYPE:
  25187. obj.SetDouble(value.Get<double>());
  25188. break;
  25189. case INT_TYPE:
  25190. obj.SetInt(value.Get<int>());
  25191. break;
  25192. case BOOL_TYPE:
  25193. obj.SetBool(value.Get<bool>());
  25194. break;
  25195. case STRING_TYPE:
  25196. obj.SetString(value.Get<std::string>().c_str(), GetAllocator());
  25197. break;
  25198. case ARRAY_TYPE:
  25199. {
  25200. obj.SetArray();
  25201. obj.Reserve(static_cast<rapidjson::SizeType>(value.ArrayLen()),
  25202. GetAllocator());
  25203. for (unsigned int i = 0; i < value.ArrayLen(); ++i)
  25204. {
  25205. Value elementValue = value.Get(int(i));
  25206. json elementJson;
  25207. if (ValueToJson(value.Get(int(i)), &elementJson))
  25208. obj.PushBack(std::move(elementJson), GetAllocator());
  25209. }
  25210. break;
  25211. }
  25212. case BINARY_TYPE:
  25213. // TODO
  25214. // obj = json(value.Get<std::vector<unsigned char>>());
  25215. return false;
  25216. break;
  25217. case OBJECT_TYPE:
  25218. {
  25219. obj.SetObject();
  25220. Value::Object objMap = value.Get<Value::Object>();
  25221. for (auto &it : objMap)
  25222. {
  25223. json elementJson;
  25224. if (ValueToJson(it.second, &elementJson))
  25225. {
  25226. obj.AddMember(json(it.first.c_str(), GetAllocator()),
  25227. std::move(elementJson), GetAllocator());
  25228. }
  25229. }
  25230. break;
  25231. }
  25232. case NULL_TYPE:
  25233. default:
  25234. return false;
  25235. }
  25236. #else
  25237. switch (value.Type())
  25238. {
  25239. case REAL_TYPE:
  25240. obj = json(value.Get<double>());
  25241. break;
  25242. case INT_TYPE:
  25243. obj = json(value.Get<int>());
  25244. break;
  25245. case BOOL_TYPE:
  25246. obj = json(value.Get<bool>());
  25247. break;
  25248. case STRING_TYPE:
  25249. obj = json(value.Get<std::string>());
  25250. break;
  25251. case ARRAY_TYPE:
  25252. {
  25253. for (unsigned int i = 0; i < value.ArrayLen(); ++i)
  25254. {
  25255. Value elementValue = value.Get(int(i));
  25256. json elementJson;
  25257. if (ValueToJson(value.Get(int(i)), &elementJson))
  25258. obj.push_back(elementJson);
  25259. }
  25260. break;
  25261. }
  25262. case BINARY_TYPE:
  25263. // TODO
  25264. // obj = json(value.Get<std::vector<unsigned char>>());
  25265. return false;
  25266. break;
  25267. case OBJECT_TYPE:
  25268. {
  25269. Value::Object objMap = value.Get<Value::Object>();
  25270. for (auto &it : objMap)
  25271. {
  25272. json elementJson;
  25273. if (ValueToJson(it.second, &elementJson)) obj[it.first] = elementJson;
  25274. }
  25275. break;
  25276. }
  25277. case NULL_TYPE:
  25278. default:
  25279. return false;
  25280. }
  25281. #endif
  25282. if (ret) *ret = std::move(obj);
  25283. return true;
  25284. }
  25285. static void SerializeValue(const std::string &key, const Value &value,
  25286. json &obj)
  25287. {
  25288. json ret;
  25289. if (ValueToJson(value, &ret))
  25290. {
  25291. JsonAddMember(obj, key.c_str(), std::move(ret));
  25292. }
  25293. }
  25294. static void SerializeGltfBufferData(const std::vector<unsigned char> &data,
  25295. json &o)
  25296. {
  25297. std::string header = "data:application/octet-stream;base64,";
  25298. if (data.size() > 0)
  25299. {
  25300. std::string encodedData =
  25301. base64_encode(&data[0], static_cast<unsigned int>(data.size()));
  25302. SerializeStringProperty("uri", header + encodedData, o);
  25303. }
  25304. else
  25305. {
  25306. // Issue #229
  25307. // size 0 is allowd. Just emit mime header.
  25308. SerializeStringProperty("uri", header, o);
  25309. }
  25310. }
  25311. //removed writing data
  25312. static bool SerializeGltfBufferData(const std::vector<unsigned char> &data,
  25313. const std::string &binFilename)
  25314. {
  25315. assert(0);
  25316. /*
  25317. #ifdef _WIN32
  25318. #if defined(__GLIBCXX__) // mingw
  25319. int file_descriptor = _wopen(UTF8ToWchar(binFilename).c_str(),
  25320. _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
  25321. __gnu_cxx::stdio_filebuf<char> wfile_buf(
  25322. file_descriptor, std::ios_base::out | std::ios_base::binary);
  25323. std::ostream output(&wfile_buf);
  25324. if (!wfile_buf.is_open()) return false;
  25325. #elif defined(_MSC_VER)
  25326. std::ofstream output(UTF8ToWchar(binFilename).c_str(), std::ofstream::binary);
  25327. if (!output.is_open()) return false;
  25328. #else
  25329. std::ofstream output(binFilename.c_str(), std::ofstream::binary);
  25330. if (!output.is_open()) return false;
  25331. #endif
  25332. #else
  25333. std::ofstream output(binFilename.c_str(), std::ofstream::binary);
  25334. if (!output.is_open()) return false;
  25335. #endif
  25336. if (data.size() > 0)
  25337. {
  25338. output.write(reinterpret_cast<const char *>(&data[0]),
  25339. std::streamsize(data.size()));
  25340. }
  25341. else
  25342. {
  25343. // Issue #229
  25344. // size 0 will be still valid buffer data.
  25345. // write empty file.
  25346. }
  25347. */
  25348. return true;
  25349. }
  25350. #if 0 // FIXME(syoyo): not used. will be removed in the future release.
  25351. static void SerializeParameterMap(ParameterMap &param, json &o)
  25352. {
  25353. for (ParameterMap::iterator paramIt = param.begin(); paramIt != param.end();
  25354. ++paramIt)
  25355. {
  25356. if (paramIt->second.number_array.size())
  25357. {
  25358. SerializeNumberArrayProperty<double>(paramIt->first,
  25359. paramIt->second.number_array, o);
  25360. }
  25361. else if (paramIt->second.json_double_value.size())
  25362. {
  25363. json json_double_value;
  25364. for (std::map<std::string, double>::iterator it =
  25365. paramIt->second.json_double_value.begin();
  25366. it != paramIt->second.json_double_value.end(); ++it)
  25367. {
  25368. if (it->first == "index")
  25369. {
  25370. json_double_value[it->first] = paramIt->second.TextureIndex();
  25371. }
  25372. else
  25373. {
  25374. json_double_value[it->first] = it->second;
  25375. }
  25376. }
  25377. o[paramIt->first] = json_double_value;
  25378. }
  25379. else if (!paramIt->second.string_value.empty())
  25380. {
  25381. SerializeStringProperty(paramIt->first, paramIt->second.string_value, o);
  25382. }
  25383. else if (paramIt->second.has_number_value)
  25384. {
  25385. o[paramIt->first] = paramIt->second.number_value;
  25386. }
  25387. else
  25388. {
  25389. o[paramIt->first] = paramIt->second.bool_value;
  25390. }
  25391. }
  25392. }
  25393. #endif
  25394. static void SerializeExtensionMap(const ExtensionMap &extensions, json &o)
  25395. {
  25396. if (!extensions.size()) return;
  25397. json extMap;
  25398. for (ExtensionMap::const_iterator extIt = extensions.begin();
  25399. extIt != extensions.end(); ++extIt)
  25400. {
  25401. // Allow an empty object for extension(#97)
  25402. json ret;
  25403. bool isNull = true;
  25404. if (ValueToJson(extIt->second, &ret))
  25405. {
  25406. isNull = JsonIsNull(ret);
  25407. JsonAddMember(extMap, extIt->first.c_str(), std::move(ret));
  25408. }
  25409. if (isNull)
  25410. {
  25411. if (!(extIt->first.empty()))
  25412. { // name should not be empty, but for sure
  25413. // create empty object so that an extension name is still included in
  25414. // json.
  25415. json empty;
  25416. JsonSetObject(empty);
  25417. JsonAddMember(extMap, extIt->first.c_str(), std::move(empty));
  25418. }
  25419. }
  25420. }
  25421. JsonAddMember(o, "extensions", std::move(extMap));
  25422. }
  25423. static void SerializeGltfAccessor(Accessor &accessor, json &o)
  25424. {
  25425. if (accessor.bufferView >= 0)
  25426. SerializeNumberProperty<int>("bufferView", accessor.bufferView, o);
  25427. if (accessor.byteOffset != 0)
  25428. SerializeNumberProperty<int>("byteOffset", int(accessor.byteOffset), o);
  25429. SerializeNumberProperty<int>("componentType", accessor.componentType, o);
  25430. SerializeNumberProperty<size_t>("count", accessor.count, o);
  25431. SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
  25432. SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
  25433. if (accessor.normalized)
  25434. SerializeValue("normalized", Value(accessor.normalized), o);
  25435. std::string type;
  25436. switch (accessor.type)
  25437. {
  25438. case TINYGLTF_TYPE_SCALAR:
  25439. type = "SCALAR";
  25440. break;
  25441. case TINYGLTF_TYPE_VEC2:
  25442. type = "VEC2";
  25443. break;
  25444. case TINYGLTF_TYPE_VEC3:
  25445. type = "VEC3";
  25446. break;
  25447. case TINYGLTF_TYPE_VEC4:
  25448. type = "VEC4";
  25449. break;
  25450. case TINYGLTF_TYPE_MAT2:
  25451. type = "MAT2";
  25452. break;
  25453. case TINYGLTF_TYPE_MAT3:
  25454. type = "MAT3";
  25455. break;
  25456. case TINYGLTF_TYPE_MAT4:
  25457. type = "MAT4";
  25458. break;
  25459. }
  25460. SerializeStringProperty("type", type, o);
  25461. if (!accessor.name.empty()) SerializeStringProperty("name", accessor.name, o);
  25462. if (accessor.extras.Type() != NULL_TYPE)
  25463. {
  25464. SerializeValue("extras", accessor.extras, o);
  25465. }
  25466. }
  25467. static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o)
  25468. {
  25469. SerializeNumberProperty("sampler", channel.sampler, o);
  25470. {
  25471. json target;
  25472. SerializeNumberProperty("node", channel.target_node, target);
  25473. SerializeStringProperty("path", channel.target_path, target);
  25474. SerializeExtensionMap(channel.target_extensions, target);
  25475. JsonAddMember(o, "target", std::move(target));
  25476. }
  25477. if (channel.extras.Type() != NULL_TYPE)
  25478. {
  25479. SerializeValue("extras", channel.extras, o);
  25480. }
  25481. SerializeExtensionMap(channel.extensions, o);
  25482. }
  25483. static void SerializeGltfAnimationSampler(AnimationSampler &sampler, json &o)
  25484. {
  25485. SerializeNumberProperty("input", sampler.input, o);
  25486. SerializeNumberProperty("output", sampler.output, o);
  25487. SerializeStringProperty("interpolation", sampler.interpolation, o);
  25488. if (sampler.extras.Type() != NULL_TYPE)
  25489. {
  25490. SerializeValue("extras", sampler.extras, o);
  25491. }
  25492. }
  25493. static void SerializeGltfAnimation(Animation &animation, json &o)
  25494. {
  25495. if (!animation.name.empty())
  25496. SerializeStringProperty("name", animation.name, o);
  25497. {
  25498. json channels;
  25499. JsonReserveArray(channels, animation.channels.size());
  25500. for (unsigned int i = 0; i < animation.channels.size(); ++i)
  25501. {
  25502. json channel;
  25503. AnimationChannel gltfChannel = animation.channels[i];
  25504. SerializeGltfAnimationChannel(gltfChannel, channel);
  25505. JsonPushBack(channels, std::move(channel));
  25506. }
  25507. JsonAddMember(o, "channels", std::move(channels));
  25508. }
  25509. {
  25510. json samplers;
  25511. JsonReserveArray(samplers, animation.samplers.size());
  25512. for (unsigned int i = 0; i < animation.samplers.size(); ++i)
  25513. {
  25514. json sampler;
  25515. AnimationSampler gltfSampler = animation.samplers[i];
  25516. SerializeGltfAnimationSampler(gltfSampler, sampler);
  25517. JsonPushBack(samplers, std::move(sampler));
  25518. }
  25519. JsonAddMember(o, "samplers", std::move(samplers));
  25520. }
  25521. if (animation.extras.Type() != NULL_TYPE)
  25522. {
  25523. SerializeValue("extras", animation.extras, o);
  25524. }
  25525. SerializeExtensionMap(animation.extensions, o);
  25526. }
  25527. static void SerializeGltfAsset(Asset &asset, json &o)
  25528. {
  25529. if (!asset.generator.empty())
  25530. {
  25531. SerializeStringProperty("generator", asset.generator, o);
  25532. }
  25533. if (!asset.copyright.empty())
  25534. {
  25535. SerializeStringProperty("copyright", asset.copyright, o);
  25536. }
  25537. if (!asset.version.empty())
  25538. {
  25539. SerializeStringProperty("version", asset.version, o);
  25540. }
  25541. if (asset.extras.Keys().size())
  25542. {
  25543. SerializeValue("extras", asset.extras, o);
  25544. }
  25545. SerializeExtensionMap(asset.extensions, o);
  25546. }
  25547. static void SerializeGltfBufferBin(Buffer &buffer, json &o,
  25548. std::vector<unsigned char> &binBuffer)
  25549. {
  25550. SerializeNumberProperty("byteLength", buffer.data.size(), o);
  25551. binBuffer = buffer.data;
  25552. if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o);
  25553. if (buffer.extras.Type() != NULL_TYPE)
  25554. {
  25555. SerializeValue("extras", buffer.extras, o);
  25556. }
  25557. }
  25558. static void SerializeGltfBuffer(Buffer &buffer, json &o)
  25559. {
  25560. SerializeNumberProperty("byteLength", buffer.data.size(), o);
  25561. SerializeGltfBufferData(buffer.data, o);
  25562. if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o);
  25563. if (buffer.extras.Type() != NULL_TYPE)
  25564. {
  25565. SerializeValue("extras", buffer.extras, o);
  25566. }
  25567. }
  25568. static bool SerializeGltfBuffer(Buffer &buffer, json &o,
  25569. const std::string &binFilename,
  25570. const std::string &binBaseFilename)
  25571. {
  25572. if (!SerializeGltfBufferData(buffer.data, binFilename)) return false;
  25573. SerializeNumberProperty("byteLength", buffer.data.size(), o);
  25574. SerializeStringProperty("uri", binBaseFilename, o);
  25575. if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o);
  25576. if (buffer.extras.Type() != NULL_TYPE)
  25577. {
  25578. SerializeValue("extras", buffer.extras, o);
  25579. }
  25580. return true;
  25581. }
  25582. static void SerializeGltfBufferView(BufferView &bufferView, json &o)
  25583. {
  25584. SerializeNumberProperty("buffer", bufferView.buffer, o);
  25585. SerializeNumberProperty<size_t>("byteLength", bufferView.byteLength, o);
  25586. // byteStride is optional, minimum allowed is 4
  25587. if (bufferView.byteStride >= 4)
  25588. {
  25589. SerializeNumberProperty<size_t>("byteStride", bufferView.byteStride, o);
  25590. }
  25591. // byteOffset is optional, default is 0
  25592. if (bufferView.byteOffset > 0)
  25593. {
  25594. SerializeNumberProperty<size_t>("byteOffset", bufferView.byteOffset, o);
  25595. }
  25596. // Target is optional, check if it contains a valid value
  25597. if (bufferView.target == TINYGLTF_TARGET_ARRAY_BUFFER ||
  25598. bufferView.target == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER)
  25599. {
  25600. SerializeNumberProperty("target", bufferView.target, o);
  25601. }
  25602. if (bufferView.name.size())
  25603. {
  25604. SerializeStringProperty("name", bufferView.name, o);
  25605. }
  25606. if (bufferView.extras.Type() != NULL_TYPE)
  25607. {
  25608. SerializeValue("extras", bufferView.extras, o);
  25609. }
  25610. }
  25611. static void SerializeGltfImage(Image &image, json &o)
  25612. {
  25613. // if uri empty, the mimeType and bufferview should be set
  25614. if (image.uri.empty())
  25615. {
  25616. SerializeStringProperty("mimeType", image.mimeType, o);
  25617. SerializeNumberProperty<int>("bufferView", image.bufferView, o);
  25618. }
  25619. else
  25620. {
  25621. // TODO(syoyo): dlib::urilencode?
  25622. SerializeStringProperty("uri", image.uri, o);
  25623. }
  25624. if (image.name.size())
  25625. {
  25626. SerializeStringProperty("name", image.name, o);
  25627. }
  25628. if (image.extras.Type() != NULL_TYPE)
  25629. {
  25630. SerializeValue("extras", image.extras, o);
  25631. }
  25632. SerializeExtensionMap(image.extensions, o);
  25633. }
  25634. static void SerializeGltfTextureInfo(TextureInfo &texinfo, json &o)
  25635. {
  25636. SerializeNumberProperty("index", texinfo.index, o);
  25637. if (texinfo.texCoord != 0)
  25638. {
  25639. SerializeNumberProperty("texCoord", texinfo.texCoord, o);
  25640. }
  25641. if (texinfo.extras.Type() != NULL_TYPE)
  25642. {
  25643. SerializeValue("extras", texinfo.extras, o);
  25644. }
  25645. SerializeExtensionMap(texinfo.extensions, o);
  25646. }
  25647. static void SerializeGltfNormalTextureInfo(NormalTextureInfo &texinfo,
  25648. json &o)
  25649. {
  25650. SerializeNumberProperty("index", texinfo.index, o);
  25651. if (texinfo.texCoord != 0)
  25652. {
  25653. SerializeNumberProperty("texCoord", texinfo.texCoord, o);
  25654. }
  25655. if (!TINYGLTF_DOUBLE_EQUAL(texinfo.scale, 1.0))
  25656. {
  25657. SerializeNumberProperty("scale", texinfo.scale, o);
  25658. }
  25659. if (texinfo.extras.Type() != NULL_TYPE)
  25660. {
  25661. SerializeValue("extras", texinfo.extras, o);
  25662. }
  25663. SerializeExtensionMap(texinfo.extensions, o);
  25664. }
  25665. static void SerializeGltfOcclusionTextureInfo(OcclusionTextureInfo &texinfo,
  25666. json &o)
  25667. {
  25668. SerializeNumberProperty("index", texinfo.index, o);
  25669. if (texinfo.texCoord != 0)
  25670. {
  25671. SerializeNumberProperty("texCoord", texinfo.texCoord, o);
  25672. }
  25673. if (!TINYGLTF_DOUBLE_EQUAL(texinfo.strength, 1.0))
  25674. {
  25675. SerializeNumberProperty("strength", texinfo.strength, o);
  25676. }
  25677. if (texinfo.extras.Type() != NULL_TYPE)
  25678. {
  25679. SerializeValue("extras", texinfo.extras, o);
  25680. }
  25681. SerializeExtensionMap(texinfo.extensions, o);
  25682. }
  25683. static void SerializeGltfPbrMetallicRoughness(PbrMetallicRoughness &pbr,
  25684. json &o)
  25685. {
  25686. std::vector<double> default_baseColorFactor = { 1.0, 1.0, 1.0, 1.0 };
  25687. if (!Equals(pbr.baseColorFactor, default_baseColorFactor))
  25688. {
  25689. SerializeNumberArrayProperty<double>("baseColorFactor", pbr.baseColorFactor,
  25690. o);
  25691. }
  25692. if (!TINYGLTF_DOUBLE_EQUAL(pbr.metallicFactor, 1.0))
  25693. {
  25694. SerializeNumberProperty("metallicFactor", pbr.metallicFactor, o);
  25695. }
  25696. if (!TINYGLTF_DOUBLE_EQUAL(pbr.roughnessFactor, 1.0))
  25697. {
  25698. SerializeNumberProperty("roughnessFactor", pbr.roughnessFactor, o);
  25699. }
  25700. if (pbr.baseColorTexture.index > -1)
  25701. {
  25702. json texinfo;
  25703. SerializeGltfTextureInfo(pbr.baseColorTexture, texinfo);
  25704. JsonAddMember(o, "baseColorTexture", std::move(texinfo));
  25705. }
  25706. if (pbr.metallicRoughnessTexture.index > -1)
  25707. {
  25708. json texinfo;
  25709. SerializeGltfTextureInfo(pbr.metallicRoughnessTexture, texinfo);
  25710. JsonAddMember(o, "metallicRoughnessTexture", std::move(texinfo));
  25711. }
  25712. SerializeExtensionMap(pbr.extensions, o);
  25713. if (pbr.extras.Type() != NULL_TYPE)
  25714. {
  25715. SerializeValue("extras", pbr.extras, o);
  25716. }
  25717. }
  25718. static void SerializeGltfMaterial(Material &material, json &o)
  25719. {
  25720. if (material.name.size())
  25721. {
  25722. SerializeStringProperty("name", material.name, o);
  25723. }
  25724. // QUESTION(syoyo): Write material parameters regardless of its default value?
  25725. if (!TINYGLTF_DOUBLE_EQUAL(material.alphaCutoff, 0.5))
  25726. {
  25727. SerializeNumberProperty("alphaCutoff", material.alphaCutoff, o);
  25728. }
  25729. if (material.alphaMode.compare("OPAQUE") != 0)
  25730. {
  25731. SerializeStringProperty("alphaMode", material.alphaMode, o);
  25732. }
  25733. if (material.doubleSided != false)
  25734. JsonAddMember(o, "doubleSided", json(material.doubleSided));
  25735. if (material.normalTexture.index > -1)
  25736. {
  25737. json texinfo;
  25738. SerializeGltfNormalTextureInfo(material.normalTexture, texinfo);
  25739. JsonAddMember(o, "normalTexture", std::move(texinfo));
  25740. }
  25741. if (material.occlusionTexture.index > -1)
  25742. {
  25743. json texinfo;
  25744. SerializeGltfOcclusionTextureInfo(material.occlusionTexture, texinfo);
  25745. JsonAddMember(o, "occlusionTexture", std::move(texinfo));
  25746. }
  25747. if (material.emissiveTexture.index > -1)
  25748. {
  25749. json texinfo;
  25750. SerializeGltfTextureInfo(material.emissiveTexture, texinfo);
  25751. JsonAddMember(o, "emissiveTexture", std::move(texinfo));
  25752. }
  25753. std::vector<double> default_emissiveFactor = { 0.0, 0.0, 0.0 };
  25754. if (!Equals(material.emissiveFactor, default_emissiveFactor))
  25755. {
  25756. SerializeNumberArrayProperty<double>("emissiveFactor",
  25757. material.emissiveFactor, o);
  25758. }
  25759. {
  25760. json pbrMetallicRoughness;
  25761. SerializeGltfPbrMetallicRoughness(material.pbrMetallicRoughness,
  25762. pbrMetallicRoughness);
  25763. // Issue 204
  25764. // Do not serialize `pbrMetallicRoughness` if pbrMetallicRoughness has all
  25765. // default values(json is null). Otherwise it will serialize to
  25766. // `pbrMetallicRoughness : null`, which cannot be read by other glTF
  25767. // importers(and validators).
  25768. //
  25769. if (!JsonIsNull(pbrMetallicRoughness))
  25770. {
  25771. JsonAddMember(o, "pbrMetallicRoughness", std::move(pbrMetallicRoughness));
  25772. }
  25773. }
  25774. #if 0 // legacy way. just for the record.
  25775. if (material.values.size())
  25776. {
  25777. json pbrMetallicRoughness;
  25778. SerializeParameterMap(material.values, pbrMetallicRoughness);
  25779. JsonAddMember(o, "pbrMetallicRoughness", std::move(pbrMetallicRoughness));
  25780. }
  25781. SerializeParameterMap(material.additionalValues, o);
  25782. #else
  25783. #endif
  25784. SerializeExtensionMap(material.extensions, o);
  25785. if (material.extras.Type() != NULL_TYPE)
  25786. {
  25787. SerializeValue("extras", material.extras, o);
  25788. }
  25789. }
  25790. static void SerializeGltfMesh(Mesh &mesh, json &o)
  25791. {
  25792. json primitives;
  25793. JsonReserveArray(primitives, mesh.primitives.size());
  25794. for (unsigned int i = 0; i < mesh.primitives.size(); ++i)
  25795. {
  25796. json primitive;
  25797. const Primitive &gltfPrimitive = mesh.primitives[i]; // don't make a copy
  25798. {
  25799. json attributes;
  25800. for (auto attrIt = gltfPrimitive.attributes.begin();
  25801. attrIt != gltfPrimitive.attributes.end(); ++attrIt)
  25802. {
  25803. SerializeNumberProperty<int>(attrIt->first, attrIt->second, attributes);
  25804. }
  25805. JsonAddMember(primitive, "attributes", std::move(attributes));
  25806. }
  25807. // Indicies is optional
  25808. if (gltfPrimitive.indices > -1)
  25809. {
  25810. SerializeNumberProperty<int>("indices", gltfPrimitive.indices, primitive);
  25811. }
  25812. // Material is optional
  25813. if (gltfPrimitive.material > -1)
  25814. {
  25815. SerializeNumberProperty<int>("material", gltfPrimitive.material,
  25816. primitive);
  25817. }
  25818. SerializeNumberProperty<int>("mode", gltfPrimitive.mode, primitive);
  25819. // Morph targets
  25820. if (gltfPrimitive.targets.size())
  25821. {
  25822. json targets;
  25823. JsonReserveArray(targets, gltfPrimitive.targets.size());
  25824. for (unsigned int k = 0; k < gltfPrimitive.targets.size(); ++k)
  25825. {
  25826. json targetAttributes;
  25827. std::map<std::string, int> targetData = gltfPrimitive.targets[k];
  25828. for (std::map<std::string, int>::iterator attrIt = targetData.begin();
  25829. attrIt != targetData.end(); ++attrIt)
  25830. {
  25831. SerializeNumberProperty<int>(attrIt->first, attrIt->second,
  25832. targetAttributes);
  25833. }
  25834. JsonPushBack(targets, std::move(targetAttributes));
  25835. }
  25836. JsonAddMember(primitive, "targets", std::move(targets));
  25837. }
  25838. SerializeExtensionMap(gltfPrimitive.extensions, primitive);
  25839. if (gltfPrimitive.extras.Type() != NULL_TYPE)
  25840. {
  25841. SerializeValue("extras", gltfPrimitive.extras, primitive);
  25842. }
  25843. JsonPushBack(primitives, std::move(primitive));
  25844. }
  25845. JsonAddMember(o, "primitives", std::move(primitives));
  25846. if (mesh.weights.size())
  25847. {
  25848. SerializeNumberArrayProperty<double>("weights", mesh.weights, o);
  25849. }
  25850. if (mesh.name.size())
  25851. {
  25852. SerializeStringProperty("name", mesh.name, o);
  25853. }
  25854. SerializeExtensionMap(mesh.extensions, o);
  25855. if (mesh.extras.Type() != NULL_TYPE)
  25856. {
  25857. SerializeValue("extras", mesh.extras, o);
  25858. }
  25859. }
  25860. static void SerializeSpotLight(SpotLight &spot, json &o)
  25861. {
  25862. SerializeNumberProperty("innerConeAngle", spot.innerConeAngle, o);
  25863. SerializeNumberProperty("outerConeAngle", spot.outerConeAngle, o);
  25864. SerializeExtensionMap(spot.extensions, o);
  25865. if (spot.extras.Type() != NULL_TYPE)
  25866. {
  25867. SerializeValue("extras", spot.extras, o);
  25868. }
  25869. }
  25870. static void SerializeGltfLight(Light &light, json &o)
  25871. {
  25872. if (!light.name.empty()) SerializeStringProperty("name", light.name, o);
  25873. SerializeNumberProperty("intensity", light.intensity, o);
  25874. if (light.range > 0.0)
  25875. {
  25876. SerializeNumberProperty("range", light.range, o);
  25877. }
  25878. SerializeNumberArrayProperty("color", light.color, o);
  25879. SerializeStringProperty("type", light.type, o);
  25880. if (light.type == "spot")
  25881. {
  25882. json spot;
  25883. SerializeSpotLight(light.spot, spot);
  25884. JsonAddMember(o, "spot", std::move(spot));
  25885. }
  25886. SerializeExtensionMap(light.extensions, o);
  25887. if (light.extras.Type() != NULL_TYPE)
  25888. {
  25889. SerializeValue("extras", light.extras, o);
  25890. }
  25891. }
  25892. static void SerializeGltfNode(Node &node, json &o)
  25893. {
  25894. if (node.translation.size() > 0)
  25895. {
  25896. SerializeNumberArrayProperty<double>("translation", node.translation, o);
  25897. }
  25898. if (node.rotation.size() > 0)
  25899. {
  25900. SerializeNumberArrayProperty<double>("rotation", node.rotation, o);
  25901. }
  25902. if (node.scale.size() > 0)
  25903. {
  25904. SerializeNumberArrayProperty<double>("scale", node.scale, o);
  25905. }
  25906. if (node.matrix.size() > 0)
  25907. {
  25908. SerializeNumberArrayProperty<double>("matrix", node.matrix, o);
  25909. }
  25910. if (node.mesh != -1)
  25911. {
  25912. SerializeNumberProperty<int>("mesh", node.mesh, o);
  25913. }
  25914. if (node.skin != -1)
  25915. {
  25916. SerializeNumberProperty<int>("skin", node.skin, o);
  25917. }
  25918. if (node.camera != -1)
  25919. {
  25920. SerializeNumberProperty<int>("camera", node.camera, o);
  25921. }
  25922. if (node.weights.size() > 0)
  25923. {
  25924. SerializeNumberArrayProperty<double>("weights", node.weights, o);
  25925. }
  25926. if (node.extras.Type() != NULL_TYPE)
  25927. {
  25928. SerializeValue("extras", node.extras, o);
  25929. }
  25930. SerializeExtensionMap(node.extensions, o);
  25931. if (!node.name.empty()) SerializeStringProperty("name", node.name, o);
  25932. SerializeNumberArrayProperty<int>("children", node.children, o);
  25933. }
  25934. static void SerializeGltfSampler(Sampler &sampler, json &o)
  25935. {
  25936. if (sampler.magFilter != -1)
  25937. {
  25938. SerializeNumberProperty("magFilter", sampler.magFilter, o);
  25939. }
  25940. if (sampler.minFilter != -1)
  25941. {
  25942. SerializeNumberProperty("minFilter", sampler.minFilter, o);
  25943. }
  25944. SerializeNumberProperty("wrapR", sampler.wrapR, o);
  25945. SerializeNumberProperty("wrapS", sampler.wrapS, o);
  25946. SerializeNumberProperty("wrapT", sampler.wrapT, o);
  25947. if (sampler.extras.Type() != NULL_TYPE)
  25948. {
  25949. SerializeValue("extras", sampler.extras, o);
  25950. }
  25951. }
  25952. static void SerializeGltfOrthographicCamera(const OrthographicCamera &camera,
  25953. json &o)
  25954. {
  25955. SerializeNumberProperty("zfar", camera.zfar, o);
  25956. SerializeNumberProperty("znear", camera.znear, o);
  25957. SerializeNumberProperty("xmag", camera.xmag, o);
  25958. SerializeNumberProperty("ymag", camera.ymag, o);
  25959. if (camera.extras.Type() != NULL_TYPE)
  25960. {
  25961. SerializeValue("extras", camera.extras, o);
  25962. }
  25963. }
  25964. static void SerializeGltfPerspectiveCamera(const PerspectiveCamera &camera,
  25965. json &o)
  25966. {
  25967. SerializeNumberProperty("zfar", camera.zfar, o);
  25968. SerializeNumberProperty("znear", camera.znear, o);
  25969. if (camera.aspectRatio > 0)
  25970. {
  25971. SerializeNumberProperty("aspectRatio", camera.aspectRatio, o);
  25972. }
  25973. if (camera.yfov > 0)
  25974. {
  25975. SerializeNumberProperty("yfov", camera.yfov, o);
  25976. }
  25977. if (camera.extras.Type() != NULL_TYPE)
  25978. {
  25979. SerializeValue("extras", camera.extras, o);
  25980. }
  25981. }
  25982. static void SerializeGltfCamera(const Camera &camera, json &o)
  25983. {
  25984. SerializeStringProperty("type", camera.type, o);
  25985. if (!camera.name.empty())
  25986. {
  25987. SerializeStringProperty("name", camera.name, o);
  25988. }
  25989. if (camera.type.compare("orthographic") == 0)
  25990. {
  25991. json orthographic;
  25992. SerializeGltfOrthographicCamera(camera.orthographic, orthographic);
  25993. JsonAddMember(o, "orthographic", std::move(orthographic));
  25994. }
  25995. else if (camera.type.compare("perspective") == 0)
  25996. {
  25997. json perspective;
  25998. SerializeGltfPerspectiveCamera(camera.perspective, perspective);
  25999. JsonAddMember(o, "perspective", std::move(perspective));
  26000. }
  26001. else
  26002. {
  26003. // ???
  26004. }
  26005. if (camera.extras.Type() != NULL_TYPE)
  26006. {
  26007. SerializeValue("extras", camera.extras, o);
  26008. }
  26009. SerializeExtensionMap(camera.extensions, o);
  26010. }
  26011. static void SerializeGltfScene(Scene &scene, json &o)
  26012. {
  26013. SerializeNumberArrayProperty<int>("nodes", scene.nodes, o);
  26014. if (scene.name.size())
  26015. {
  26016. SerializeStringProperty("name", scene.name, o);
  26017. }
  26018. if (scene.extras.Type() != NULL_TYPE)
  26019. {
  26020. SerializeValue("extras", scene.extras, o);
  26021. }
  26022. SerializeExtensionMap(scene.extensions, o);
  26023. }
  26024. static void SerializeGltfSkin(Skin &skin, json &o)
  26025. {
  26026. if (skin.inverseBindMatrices != -1)
  26027. SerializeNumberProperty("inverseBindMatrices", skin.inverseBindMatrices, o);
  26028. SerializeNumberArrayProperty<int>("joints", skin.joints, o);
  26029. SerializeNumberProperty("skeleton", skin.skeleton, o);
  26030. if (skin.name.size())
  26031. {
  26032. SerializeStringProperty("name", skin.name, o);
  26033. }
  26034. }
  26035. static void SerializeGltfTexture(Texture &texture, json &o)
  26036. {
  26037. if (texture.sampler > -1)
  26038. {
  26039. SerializeNumberProperty("sampler", texture.sampler, o);
  26040. }
  26041. if (texture.source > -1)
  26042. {
  26043. SerializeNumberProperty("source", texture.source, o);
  26044. }
  26045. if (texture.name.size())
  26046. {
  26047. SerializeStringProperty("name", texture.name, o);
  26048. }
  26049. if (texture.extras.Type() != NULL_TYPE)
  26050. {
  26051. SerializeValue("extras", texture.extras, o);
  26052. }
  26053. SerializeExtensionMap(texture.extensions, o);
  26054. }
  26055. ///
  26056. /// Serialize all properties except buffers and images.
  26057. ///
  26058. static void SerializeGltfModel(Model *model, json &o)
  26059. {
  26060. // ACCESSORS
  26061. if (model->accessors.size())
  26062. {
  26063. json accessors;
  26064. JsonReserveArray(accessors, model->accessors.size());
  26065. for (unsigned int i = 0; i < model->accessors.size(); ++i)
  26066. {
  26067. json accessor;
  26068. SerializeGltfAccessor(model->accessors[i], accessor);
  26069. JsonPushBack(accessors, std::move(accessor));
  26070. }
  26071. JsonAddMember(o, "accessors", std::move(accessors));
  26072. }
  26073. // ANIMATIONS
  26074. if (model->animations.size())
  26075. {
  26076. json animations;
  26077. JsonReserveArray(animations, model->animations.size());
  26078. for (unsigned int i = 0; i < model->animations.size(); ++i)
  26079. {
  26080. if (model->animations[i].channels.size())
  26081. {
  26082. json animation;
  26083. SerializeGltfAnimation(model->animations[i], animation);
  26084. JsonPushBack(animations, std::move(animation));
  26085. }
  26086. }
  26087. JsonAddMember(o, "animations", std::move(animations));
  26088. }
  26089. // ASSET
  26090. json asset;
  26091. SerializeGltfAsset(model->asset, asset);
  26092. JsonAddMember(o, "asset", std::move(asset));
  26093. // BUFFERVIEWS
  26094. if (model->bufferViews.size())
  26095. {
  26096. json bufferViews;
  26097. JsonReserveArray(bufferViews, model->bufferViews.size());
  26098. for (unsigned int i = 0; i < model->bufferViews.size(); ++i)
  26099. {
  26100. json bufferView;
  26101. SerializeGltfBufferView(model->bufferViews[i], bufferView);
  26102. JsonPushBack(bufferViews, std::move(bufferView));
  26103. }
  26104. JsonAddMember(o, "bufferViews", std::move(bufferViews));
  26105. }
  26106. // Extensions required
  26107. if (model->extensionsRequired.size())
  26108. {
  26109. SerializeStringArrayProperty("extensionsRequired",
  26110. model->extensionsRequired, o);
  26111. }
  26112. // MATERIALS
  26113. if (model->materials.size())
  26114. {
  26115. json materials;
  26116. JsonReserveArray(materials, model->materials.size());
  26117. for (unsigned int i = 0; i < model->materials.size(); ++i)
  26118. {
  26119. json material;
  26120. SerializeGltfMaterial(model->materials[i], material);
  26121. if (JsonIsNull(material))
  26122. {
  26123. // Issue 294.
  26124. // `material` does not have any required parameters
  26125. // so the result may be null(unmodified) when all material parameters have default value.
  26126. //
  26127. // null is not allowed thus we create an empty JSON object.
  26128. JsonSetObject(material);
  26129. }
  26130. JsonPushBack(materials, std::move(material));
  26131. }
  26132. JsonAddMember(o, "materials", std::move(materials));
  26133. }
  26134. // MESHES
  26135. if (model->meshes.size())
  26136. {
  26137. json meshes;
  26138. JsonReserveArray(meshes, model->meshes.size());
  26139. for (unsigned int i = 0; i < model->meshes.size(); ++i)
  26140. {
  26141. json mesh;
  26142. SerializeGltfMesh(model->meshes[i], mesh);
  26143. JsonPushBack(meshes, std::move(mesh));
  26144. }
  26145. JsonAddMember(o, "meshes", std::move(meshes));
  26146. }
  26147. // NODES
  26148. if (model->nodes.size())
  26149. {
  26150. json nodes;
  26151. JsonReserveArray(nodes, model->nodes.size());
  26152. for (unsigned int i = 0; i < model->nodes.size(); ++i)
  26153. {
  26154. json node;
  26155. SerializeGltfNode(model->nodes[i], node);
  26156. JsonPushBack(nodes, std::move(node));
  26157. }
  26158. JsonAddMember(o, "nodes", std::move(nodes));
  26159. }
  26160. // SCENE
  26161. if (model->defaultScene > -1)
  26162. {
  26163. SerializeNumberProperty<int>("scene", model->defaultScene, o);
  26164. }
  26165. // SCENES
  26166. if (model->scenes.size())
  26167. {
  26168. json scenes;
  26169. JsonReserveArray(scenes, model->scenes.size());
  26170. for (unsigned int i = 0; i < model->scenes.size(); ++i)
  26171. {
  26172. json currentScene;
  26173. SerializeGltfScene(model->scenes[i], currentScene);
  26174. JsonPushBack(scenes, std::move(currentScene));
  26175. }
  26176. JsonAddMember(o, "scenes", std::move(scenes));
  26177. }
  26178. // SKINS
  26179. if (model->skins.size())
  26180. {
  26181. json skins;
  26182. JsonReserveArray(skins, model->skins.size());
  26183. for (unsigned int i = 0; i < model->skins.size(); ++i)
  26184. {
  26185. json skin;
  26186. SerializeGltfSkin(model->skins[i], skin);
  26187. JsonPushBack(skins, std::move(skin));
  26188. }
  26189. JsonAddMember(o, "skins", std::move(skins));
  26190. }
  26191. // TEXTURES
  26192. if (model->textures.size())
  26193. {
  26194. json textures;
  26195. JsonReserveArray(textures, model->textures.size());
  26196. for (unsigned int i = 0; i < model->textures.size(); ++i)
  26197. {
  26198. json texture;
  26199. SerializeGltfTexture(model->textures[i], texture);
  26200. JsonPushBack(textures, std::move(texture));
  26201. }
  26202. JsonAddMember(o, "textures", std::move(textures));
  26203. }
  26204. // SAMPLERS
  26205. if (model->samplers.size())
  26206. {
  26207. json samplers;
  26208. JsonReserveArray(samplers, model->samplers.size());
  26209. for (unsigned int i = 0; i < model->samplers.size(); ++i)
  26210. {
  26211. json sampler;
  26212. SerializeGltfSampler(model->samplers[i], sampler);
  26213. JsonPushBack(samplers, std::move(sampler));
  26214. }
  26215. JsonAddMember(o, "samplers", std::move(samplers));
  26216. }
  26217. // CAMERAS
  26218. if (model->cameras.size())
  26219. {
  26220. json cameras;
  26221. JsonReserveArray(cameras, model->cameras.size());
  26222. for (unsigned int i = 0; i < model->cameras.size(); ++i)
  26223. {
  26224. json camera;
  26225. SerializeGltfCamera(model->cameras[i], camera);
  26226. JsonPushBack(cameras, std::move(camera));
  26227. }
  26228. JsonAddMember(o, "cameras", std::move(cameras));
  26229. }
  26230. // EXTENSIONS
  26231. SerializeExtensionMap(model->extensions, o);
  26232. auto extensionsUsed = model->extensionsUsed;
  26233. // LIGHTS as KHR_lights_punctual
  26234. if (model->lights.size())
  26235. {
  26236. json lights;
  26237. JsonReserveArray(lights, model->lights.size());
  26238. for (unsigned int i = 0; i < model->lights.size(); ++i)
  26239. {
  26240. json light;
  26241. SerializeGltfLight(model->lights[i], light);
  26242. JsonPushBack(lights, std::move(light));
  26243. }
  26244. json khr_lights_cmn;
  26245. JsonAddMember(khr_lights_cmn, "lights", std::move(lights));
  26246. json ext_j;
  26247. {
  26248. json_const_iterator it;
  26249. if (FindMember(o, "extensions", it))
  26250. {
  26251. JsonAssign(ext_j, GetValue(it));
  26252. }
  26253. }
  26254. JsonAddMember(ext_j, "KHR_lights_punctual", std::move(khr_lights_cmn));
  26255. JsonAddMember(o, "extensions", std::move(ext_j));
  26256. // Also add "KHR_lights_punctual" to `extensionsUsed`
  26257. {
  26258. auto has_khr_lights_punctual =
  26259. std::find_if(extensionsUsed.begin(), extensionsUsed.end(),
  26260. [](const std::string &s)
  26261. {
  26262. return (s.compare("KHR_lights_punctual") == 0);
  26263. });
  26264. if (has_khr_lights_punctual == extensionsUsed.end())
  26265. {
  26266. extensionsUsed.push_back("KHR_lights_punctual");
  26267. }
  26268. }
  26269. }
  26270. // Extensions used
  26271. if (model->extensionsUsed.size())
  26272. {
  26273. SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o);
  26274. }
  26275. // EXTRAS
  26276. if (model->extras.Type() != NULL_TYPE)
  26277. {
  26278. SerializeValue("extras", model->extras, o);
  26279. }
  26280. }
  26281. static bool WriteGltfStream(std::ostream &stream, const std::string &content)
  26282. {
  26283. stream << content << std::endl;
  26284. return true;
  26285. }
  26286. //removed writing data
  26287. static bool WriteGltfFile(const std::string &output,
  26288. const std::string &content)
  26289. {
  26290. assert(0);
  26291. /*
  26292. #ifdef _WIN32
  26293. #if defined(_MSC_VER)
  26294. std::ofstream gltfFile(UTF8ToWchar(output).c_str());
  26295. #elif defined(__GLIBCXX__)
  26296. int file_descriptor = _wopen(UTF8ToWchar(output).c_str(),
  26297. _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
  26298. __gnu_cxx::stdio_filebuf<char> wfile_buf(
  26299. file_descriptor, std::ios_base::out | std::ios_base::binary);
  26300. std::ostream gltfFile(&wfile_buf);
  26301. if (!wfile_buf.is_open()) return false;
  26302. #else
  26303. std::ofstream gltfFile(output.c_str());
  26304. if (!gltfFile.is_open()) return false;
  26305. #endif
  26306. #else
  26307. std::ofstream gltfFile(output.c_str());
  26308. if (!gltfFile.is_open()) return false;
  26309. #endif
  26310. return WriteGltfStream(gltfFile, content);
  26311. */
  26312. return 0;
  26313. }
  26314. static void WriteBinaryGltfStream(std::ostream &stream,
  26315. const std::string &content,
  26316. const std::vector<unsigned char> &binBuffer)
  26317. {
  26318. const std::string header = "glTF";
  26319. const int version = 2;
  26320. // https://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number
  26321. auto roundUp = [](uint32_t numToRound, uint32_t multiple)
  26322. {
  26323. if (multiple == 0) return numToRound;
  26324. uint32_t remainder = numToRound % multiple;
  26325. if (remainder == 0) return numToRound;
  26326. return numToRound + multiple - remainder;
  26327. };
  26328. const uint32_t padding_size =
  26329. roundUp(uint32_t(content.size()), 4) - uint32_t(content.size());
  26330. // 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
  26331. // Chunk data must be located at 4-byte boundary.
  26332. const uint32_t length =
  26333. 12 + 8 + roundUp(uint32_t(content.size()), 4) +
  26334. (binBuffer.size() ? (8 + roundUp(uint32_t(binBuffer.size()), 4)) : 0);
  26335. stream.write(header.c_str(), std::streamsize(header.size()));
  26336. stream.write(reinterpret_cast<const char *>(&version), sizeof(version));
  26337. stream.write(reinterpret_cast<const char *>(&length), sizeof(length));
  26338. // JSON chunk info, then JSON data
  26339. const uint32_t model_length = uint32_t(content.size()) + padding_size;
  26340. const uint32_t model_format = 0x4E4F534A;
  26341. stream.write(reinterpret_cast<const char *>(&model_length),
  26342. sizeof(model_length));
  26343. stream.write(reinterpret_cast<const char *>(&model_format),
  26344. sizeof(model_format));
  26345. stream.write(content.c_str(), std::streamsize(content.size()));
  26346. // Chunk must be multiplies of 4, so pad with spaces
  26347. if (padding_size > 0)
  26348. {
  26349. const std::string padding = std::string(size_t(padding_size), ' ');
  26350. stream.write(padding.c_str(), std::streamsize(padding.size()));
  26351. }
  26352. if (binBuffer.size() > 0)
  26353. {
  26354. const uint32_t bin_padding_size =
  26355. roundUp(uint32_t(binBuffer.size()), 4) - uint32_t(binBuffer.size());
  26356. // BIN chunk info, then BIN data
  26357. const uint32_t bin_length = uint32_t(binBuffer.size()) + bin_padding_size;
  26358. const uint32_t bin_format = 0x004e4942;
  26359. stream.write(reinterpret_cast<const char *>(&bin_length),
  26360. sizeof(bin_length));
  26361. stream.write(reinterpret_cast<const char *>(&bin_format),
  26362. sizeof(bin_format));
  26363. stream.write(reinterpret_cast<const char *>(binBuffer.data()),
  26364. std::streamsize(binBuffer.size()));
  26365. // Chunksize must be multiplies of 4, so pad with zeroes
  26366. if (bin_padding_size > 0)
  26367. {
  26368. const std::vector<unsigned char> padding =
  26369. std::vector<unsigned char>(size_t(bin_padding_size), 0);
  26370. stream.write(reinterpret_cast<const char *>(padding.data()),
  26371. std::streamsize(padding.size()));
  26372. }
  26373. }
  26374. }
  26375. //removed writing data
  26376. static void WriteBinaryGltfFile(const std::string &output,
  26377. const std::string &content,
  26378. const std::vector<unsigned char> &binBuffer)
  26379. {
  26380. assert(0);
  26381. /*
  26382. #ifdef _WIN32
  26383. #if defined(_MSC_VER)
  26384. std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary);
  26385. #elif defined(__GLIBCXX__)
  26386. int file_descriptor = _wopen(UTF8ToWchar(output).c_str(),
  26387. _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
  26388. __gnu_cxx::stdio_filebuf<char> wfile_buf(
  26389. file_descriptor, std::ios_base::out | std::ios_base::binary);
  26390. std::ostream gltfFile(&wfile_buf);
  26391. #else
  26392. std::ofstream gltfFile(output.c_str(), std::ios::binary);
  26393. #endif
  26394. #else
  26395. std::ofstream gltfFile(output.c_str(), std::ios::binary);
  26396. #endif
  26397. WriteBinaryGltfStream(gltfFile, content, binBuffer);
  26398. */
  26399. }
  26400. bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
  26401. bool prettyPrint = true,
  26402. bool writeBinary = false)
  26403. {
  26404. JsonDocument output;
  26405. /// Serialize all properties except buffers and images.
  26406. SerializeGltfModel(model, output);
  26407. // BUFFERS
  26408. std::vector<unsigned char> binBuffer;
  26409. if (model->buffers.size())
  26410. {
  26411. json buffers;
  26412. JsonReserveArray(buffers, model->buffers.size());
  26413. for (unsigned int i = 0; i < model->buffers.size(); ++i)
  26414. {
  26415. json buffer;
  26416. if (writeBinary && i == 0 && model->buffers[i].uri.empty())
  26417. {
  26418. SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer);
  26419. }
  26420. else
  26421. {
  26422. SerializeGltfBuffer(model->buffers[i], buffer);
  26423. }
  26424. JsonPushBack(buffers, std::move(buffer));
  26425. }
  26426. JsonAddMember(output, "buffers", std::move(buffers));
  26427. }
  26428. // IMAGES
  26429. if (model->images.size())
  26430. {
  26431. json images;
  26432. JsonReserveArray(images, model->images.size());
  26433. for (unsigned int i = 0; i < model->images.size(); ++i)
  26434. {
  26435. json image;
  26436. std::string dummystring = "";
  26437. // UpdateImageObject need baseDir but only uses it if embeddedImages is
  26438. // enabled, since we won't write separate images when writing to a stream
  26439. // we
  26440. UpdateImageObject(model->images[i], dummystring, int(i), false,
  26441. &this->WriteImageData, this->write_image_user_data_);
  26442. SerializeGltfImage(model->images[i], image);
  26443. JsonPushBack(images, std::move(image));
  26444. }
  26445. JsonAddMember(output, "images", std::move(images));
  26446. }
  26447. if (writeBinary)
  26448. {
  26449. WriteBinaryGltfStream(stream, JsonToString(output), binBuffer);
  26450. }
  26451. else
  26452. {
  26453. WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
  26454. }
  26455. return true;
  26456. }
  26457. bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
  26458. bool embedImages = false,
  26459. bool embedBuffers = false,
  26460. bool prettyPrint = true,
  26461. bool writeBinary = false)
  26462. {
  26463. JsonDocument output;
  26464. std::string defaultBinFilename = GetBaseFilename(filename);
  26465. std::string defaultBinFileExt = ".bin";
  26466. std::string::size_type pos =
  26467. defaultBinFilename.rfind('.', defaultBinFilename.length());
  26468. if (pos != std::string::npos)
  26469. {
  26470. defaultBinFilename = defaultBinFilename.substr(0, pos);
  26471. }
  26472. std::string baseDir = GetBaseDir(filename);
  26473. if (baseDir.empty())
  26474. {
  26475. baseDir = "./";
  26476. }
  26477. /// Serialize all properties except buffers and images.
  26478. SerializeGltfModel(model, output);
  26479. // BUFFERS
  26480. std::vector<std::string> usedUris;
  26481. std::vector<unsigned char> binBuffer;
  26482. if (model->buffers.size())
  26483. {
  26484. json buffers;
  26485. JsonReserveArray(buffers, model->buffers.size());
  26486. for (unsigned int i = 0; i < model->buffers.size(); ++i)
  26487. {
  26488. json buffer;
  26489. if (writeBinary && i == 0 && model->buffers[i].uri.empty())
  26490. {
  26491. SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer);
  26492. }
  26493. else if (embedBuffers)
  26494. {
  26495. SerializeGltfBuffer(model->buffers[i], buffer);
  26496. }
  26497. else
  26498. {
  26499. std::string binSavePath;
  26500. std::string binUri;
  26501. if (!model->buffers[i].uri.empty() &&
  26502. !IsDataURI(model->buffers[i].uri))
  26503. {
  26504. binUri = model->buffers[i].uri;
  26505. }
  26506. else
  26507. {
  26508. binUri = defaultBinFilename + defaultBinFileExt;
  26509. bool inUse = true;
  26510. int numUsed = 0;
  26511. while (inUse)
  26512. {
  26513. inUse = false;
  26514. for (const std::string &usedName : usedUris)
  26515. {
  26516. if (binUri.compare(usedName) != 0) continue;
  26517. inUse = true;
  26518. binUri = defaultBinFilename + std::to_string(numUsed++) +
  26519. defaultBinFileExt;
  26520. break;
  26521. }
  26522. }
  26523. }
  26524. usedUris.push_back(binUri);
  26525. binSavePath = JoinPath(baseDir, binUri);
  26526. if (!SerializeGltfBuffer(model->buffers[i], buffer, binSavePath,
  26527. binUri))
  26528. {
  26529. return false;
  26530. }
  26531. }
  26532. JsonPushBack(buffers, std::move(buffer));
  26533. }
  26534. JsonAddMember(output, "buffers", std::move(buffers));
  26535. }
  26536. // IMAGES
  26537. if (model->images.size())
  26538. {
  26539. json images;
  26540. JsonReserveArray(images, model->images.size());
  26541. for (unsigned int i = 0; i < model->images.size(); ++i)
  26542. {
  26543. json image;
  26544. UpdateImageObject(model->images[i], baseDir, int(i), embedImages,
  26545. &this->WriteImageData, this->write_image_user_data_);
  26546. SerializeGltfImage(model->images[i], image);
  26547. JsonPushBack(images, std::move(image));
  26548. }
  26549. JsonAddMember(output, "images", std::move(images));
  26550. }
  26551. if (writeBinary)
  26552. {
  26553. WriteBinaryGltfFile(filename, JsonToString(output), binBuffer);
  26554. }
  26555. else
  26556. {
  26557. WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
  26558. }
  26559. return true;
  26560. }
  26561. } // namespace tinygltf
  26562. #ifdef __clang__
  26563. #pragma clang diagnostic pop
  26564. #endif
  26565. #endif // TINYGLTF_IMPLEMENTATION
  26566. ////////////////////////////////////////////////
  26567. //Core.cpp
  26568. ////////////////////////////////////////////////
  26569. #pragma region Core
  26570. #include <stdio.h>
  26571. #include <Windows.h>
  26572. #include <signal.h>
  26573. #include <sstream>
  26574. #undef min
  26575. #undef max
  26576. namespace gl3d
  26577. {
  26578. void assertFunc(const char *expression,
  26579. const char *file_name,
  26580. unsigned const line_number,
  26581. const char *comment)
  26582. {
  26583. char c[1024] = {};
  26584. sprintf(c,
  26585. "Assertion failed\n\n"
  26586. "File:\n"
  26587. "%s\n\n"
  26588. "Line:\n"
  26589. "%u\n\n"
  26590. "Expresion:\n"
  26591. "%s\n\n"
  26592. "Comment:\n"
  26593. "%s",
  26594. file_name,
  26595. line_number,
  26596. expression,
  26597. comment
  26598. );
  26599. int const action = MessageBox(0, c, "Platform Layer", MB_TASKMODAL
  26600. | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND);
  26601. switch (action)
  26602. {
  26603. case IDABORT: // Abort the program:
  26604. {
  26605. raise(SIGABRT);
  26606. // We won't usually get here, but it's possible that a user-registered
  26607. // abort handler returns, so exit the program immediately. Note that
  26608. // even though we are "aborting," we do not call abort() because we do
  26609. // not want to invoke Watson (the user has already had an opportunity
  26610. // to debug the error and chose not to).
  26611. _exit(3);
  26612. }
  26613. case IDRETRY: // Break into the debugger then return control to caller
  26614. {
  26615. __debugbreak();
  26616. return;
  26617. }
  26618. case IDIGNORE: // Return control to caller
  26619. {
  26620. return;
  26621. }
  26622. default: // This should not happen; treat as fatal error:
  26623. {
  26624. abort();
  26625. }
  26626. }
  26627. }
  26628. //https://learnopengl.com/In-Practice/Debugging
  26629. void GLAPIENTRY glDebugOutput(GLenum source,
  26630. GLenum type,
  26631. unsigned int id,
  26632. GLenum severity,
  26633. GLsizei length,
  26634. const char *message,
  26635. const void *userParam)
  26636. {
  26637. ErrorReporter *errorReporter = (ErrorReporter*)userParam;
  26638. // ignore non-significant error/warning codes
  26639. if (id == 131169 || id == 131185 || id == 131218 || id == 131204
  26640. || id == 131222
  26641. || id == 131140 //that dittering thing
  26642. ) return;
  26643. if (type == GL_DEBUG_TYPE_PERFORMANCE) return;
  26644. std::stringstream error;
  26645. error << "---------------" << std::endl;
  26646. error << "Debug message (" << id << "): " << message << std::endl;
  26647. switch (source)
  26648. {
  26649. case GL_DEBUG_SOURCE_API: error << "Source: API"; break;
  26650. case GL_DEBUG_SOURCE_WINDOW_SYSTEM: error << "Source: Window System"; break;
  26651. case GL_DEBUG_SOURCE_SHADER_COMPILER: error << "Source: Shader Compiler"; break;
  26652. case GL_DEBUG_SOURCE_THIRD_PARTY: error << "Source: Third Party"; break;
  26653. case GL_DEBUG_SOURCE_APPLICATION: error << "Source: Application"; break;
  26654. case GL_DEBUG_SOURCE_OTHER: error << "Source: Other"; break;
  26655. } error << std::endl;
  26656. switch (type)
  26657. {
  26658. case GL_DEBUG_TYPE_ERROR: error << "Type: Error"; break;
  26659. case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: error << "Type: Deprecated Behaviour"; break;
  26660. case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: error << "Type: Undefined Behaviour"; break;
  26661. case GL_DEBUG_TYPE_PORTABILITY: error << "Type: Portability"; break;
  26662. case GL_DEBUG_TYPE_PERFORMANCE: error << "Type: Performance"; break;
  26663. case GL_DEBUG_TYPE_MARKER: error << "Type: Marker"; break;
  26664. case GL_DEBUG_TYPE_PUSH_GROUP: error << "Type: Push Group"; break;
  26665. case GL_DEBUG_TYPE_POP_GROUP: error << "Type: Pop Group"; break;
  26666. case GL_DEBUG_TYPE_OTHER: error << "Type: Other"; break;
  26667. } error << std::endl;
  26668. switch (severity)
  26669. {
  26670. case GL_DEBUG_SEVERITY_HIGH: error << "Severity: high"; break;
  26671. case GL_DEBUG_SEVERITY_MEDIUM: error << "Severity: medium"; break;
  26672. case GL_DEBUG_SEVERITY_LOW: error << "Severity: low"; break;
  26673. case GL_DEBUG_SEVERITY_NOTIFICATION: error << "Severity: notification"; break;
  26674. };
  26675. errorReporter->callErrorCallback(error.str());
  26676. }
  26677. };
  26678. #define TINYGLTF_IMPLEMENTATION
  26679. #define STB_IMAGE_WRITE_IMPLEMENTATION
  26680. #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
  26681. #define TINYGLTF_NO_INCLUDE_JSON
  26682. #define TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE
  26683. #define JSON_NOEXCEPTION
  26684. #pragma endregion
  26685. ////////////////////////////////////////////////
  26686. //ErrorReporting.cpp
  26687. ////////////////////////////////////////////////
  26688. #pragma region ErrorReporting
  26689. void gl3d::ErrorReporter::callErrorCallback(std::string s)
  26690. {
  26691. if (!s.empty() && currentErrorCallback != nullptr)
  26692. {
  26693. currentErrorCallback(s, userData);
  26694. }
  26695. }
  26696. void gl3d::defaultErrorCallback(std::string err, void *userData)
  26697. {
  26698. #if GL3D_REMOVE_IOSTREAM == 0
  26699. std::cout << err << "\n";
  26700. #endif
  26701. }
  26702. std::string gl3d::defaultReadEntireFile(const char* fileName, bool &couldNotOpen, void *userData)
  26703. {
  26704. #if GL3D_REMOVE_FSTREAM == 0
  26705. std::ifstream file;
  26706. file.open(fileName);
  26707. if (!file.is_open())
  26708. {
  26709. couldNotOpen = true;
  26710. return "";
  26711. }
  26712. couldNotOpen = false;
  26713. size_t size = 0;
  26714. file.seekg(0, file.end);
  26715. size = file.tellg();
  26716. file.seekg(0, file.beg);
  26717. std::string ret;
  26718. ret.reserve(size + 1);
  26719. ret.assign((std::istreambuf_iterator<char>(file)),
  26720. std::istreambuf_iterator<char>());
  26721. file.close();
  26722. return ret;
  26723. #else
  26724. return "";
  26725. #endif
  26726. }
  26727. std::vector<char> gl3d::defaultReadEntireFileBinary(const char *fileName, bool &couldNotOpen, void *userData)
  26728. {
  26729. #if GL3D_REMOVE_FSTREAM == 0
  26730. std::ifstream file;
  26731. file.open(fileName, std::ios::binary);
  26732. if (!file.is_open())
  26733. {
  26734. couldNotOpen = true;
  26735. return {};
  26736. }
  26737. couldNotOpen = false;
  26738. size_t size = 0;
  26739. file.seekg(0, file.end);
  26740. size = file.tellg();
  26741. file.seekg(0, file.beg);
  26742. std::vector<char> ret;
  26743. ret.reserve(size + 1);
  26744. ret.assign((std::istreambuf_iterator<char>(file)),
  26745. std::istreambuf_iterator<char>());
  26746. file.close();
  26747. return ret;
  26748. #else
  26749. return {};
  26750. #endif
  26751. }
  26752. bool gl3d::defaultFileExists(const char *fileName, void *userData)
  26753. {
  26754. #if GL3D_REMOVE_FSTREAM == 0
  26755. std::ifstream file;
  26756. file.open(fileName);
  26757. if (!file.is_open())
  26758. {
  26759. return false;
  26760. }
  26761. else
  26762. {
  26763. return true;
  26764. }
  26765. #else
  26766. return false;
  26767. #endif
  26768. }
  26769. #pragma endregion
  26770. ////////////////////////////////////////////////
  26771. //Animations.cpp
  26772. ////////////////////////////////////////////////
  26773. #pragma region Animations
  26774. #pragma endregion
  26775. ////////////////////////////////////////////////
  26776. //Texture.cpp
  26777. ////////////////////////////////////////////////
  26778. #pragma region Texture
  26779. #include <glm\vec2.hpp>
  26780. #include <glm\vec3.hpp>
  26781. #include <algorithm>
  26782. namespace gl3d
  26783. {
  26784. std::string GpuTexture::loadTextureFromFile(const char *file, FileOpener &fileOpener, int quality, int channels)
  26785. {
  26786. bool couldNotOpen = 0;
  26787. auto content = fileOpener.binary(file, couldNotOpen);
  26788. if (couldNotOpen)
  26789. {
  26790. return std::string("Could not open file: ") + file;
  26791. }
  26792. int w=0, h=0, nrChannels=0;
  26793. stbi_set_flip_vertically_on_load(true);
  26794. unsigned char *data = stbi_load_from_memory((unsigned char*)content.data(), content.size(), &w, &h, &nrChannels, channels);
  26795. if (!data)
  26796. {
  26797. id = 0;
  26798. return std::string("err: ") + file;
  26799. }
  26800. else
  26801. {
  26802. loadTextureFromMemory(data, w, h, channels, quality);
  26803. stbi_image_free(data);
  26804. }
  26805. return "";
  26806. }
  26807. void GpuTexture::loadTextureFromMemory(void *data, int w, int h, int chanels,
  26808. int quality)
  26809. {
  26810. gl3dAssertComment(chanels == 1 || chanels == 3 || chanels == 4, "invalid chanel number");
  26811. GLenum format = GL_RGBA;
  26812. GLenum internalFormat = GL_RGBA8;
  26813. if(chanels == 3)
  26814. {
  26815. format = GL_RGB;
  26816. internalFormat = GL_RGB8;
  26817. }else if(chanels == 1)
  26818. {
  26819. format = GL_RED;
  26820. internalFormat = GL_R8;
  26821. }
  26822. glGenTextures(1, &id);
  26823. glBindTexture(GL_TEXTURE_2D, id);
  26824. glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_BYTE, data);
  26825. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  26826. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  26827. if (quality < 0)
  26828. return;
  26829. setTextureQuality(quality);
  26830. if(quality > linearNoMipmap)
  26831. glGenerateMipmap(GL_TEXTURE_2D);
  26832. }
  26833. void GpuTexture::loadTextureFromMemoryAndCheckAlpha(void* data, int w, int h, int& alpha, int& alphaWithData,
  26834. int chanels, int quality)
  26835. {
  26836. alpha = 0;
  26837. alphaWithData = 0;
  26838. if (chanels == 4)
  26839. {
  26840. for (int i = 0; i < w * h; i++)
  26841. {
  26842. if (((char*)data)[4 * i + 3] != UCHAR_MAX)
  26843. {
  26844. alpha = 1;
  26845. }
  26846. if (((char*)data)[4 * i + 3] != 0 && ((char*)data)[4 * i + 3] != UCHAR_MAX)
  26847. {
  26848. alphaWithData = 1;
  26849. }
  26850. if (alpha && alphaWithData)
  26851. {
  26852. break;
  26853. }
  26854. }
  26855. if (!alpha)
  26856. {
  26857. //cut the last channel
  26858. int writePos = 0;
  26859. int readPos = 0;
  26860. for (int i = 0; i < w * h; i++)
  26861. {
  26862. ((char*)data)[writePos++] = ((char*)data)[readPos++];
  26863. ((char*)data)[writePos++] = ((char*)data)[readPos++];
  26864. ((char*)data)[writePos++] = ((char*)data)[readPos++];
  26865. readPos++;//skip alpha
  26866. }
  26867. chanels = 3;
  26868. }
  26869. }
  26870. loadTextureFromMemory(data, w, h, chanels, quality);
  26871. }
  26872. std::string GpuTexture::loadTextureFromFileAndCheckAlpha(const char* file, int& alpha, int& alphaData, int quality, int channels)
  26873. {
  26874. int w, h, nrChannels;
  26875. stbi_set_flip_vertically_on_load(true);
  26876. unsigned char* data = stbi_load(file, &w, &h, &nrChannels, channels);
  26877. alpha = 0;
  26878. alphaData = 0;
  26879. if (!data)
  26880. {
  26881. //todo err messages
  26882. return std::string("err: ") + file;
  26883. id = 0;
  26884. }
  26885. else
  26886. {
  26887. //first look if there is alpha data in the file or if it is wanted at all
  26888. if(nrChannels != 4 || channels != 4)
  26889. {
  26890. alpha = 0;
  26891. }
  26892. else
  26893. {
  26894. for (int i = 0; i < w * h; i++)
  26895. {
  26896. if (((char*)data)[4 * i + 3] != UCHAR_MAX)
  26897. {
  26898. alpha = 1;
  26899. }
  26900. if (((char*)data)[4 * i + 3] != 0 && ((char*)data)[4 * i + 3] != UCHAR_MAX)
  26901. {
  26902. alphaData = 1;
  26903. }
  26904. if (alpha && alphaData)
  26905. {
  26906. break;
  26907. }
  26908. }
  26909. }
  26910. // if there is no alpha channel in file clamp channels to max 3
  26911. if (!alpha && channels == 4)
  26912. {
  26913. int writePos = 0;
  26914. int readPos = 0;
  26915. for (int i = 0; i < w * h; i++)
  26916. {
  26917. data[writePos++] = data[readPos++];
  26918. data[writePos++] = data[readPos++];
  26919. data[writePos++] = data[readPos++];
  26920. readPos++;//skip alpha
  26921. }
  26922. channels = 3;
  26923. }
  26924. loadTextureFromMemory(data, w, h, channels, quality);
  26925. stbi_image_free(data);
  26926. }
  26927. return "";
  26928. }
  26929. void GpuTexture::clear()
  26930. {
  26931. glDeleteTextures(1, &id);
  26932. id = 0;
  26933. }
  26934. void GpuTexture::setTextureQuality(int quality)
  26935. {
  26936. if (!id)
  26937. return;
  26938. if (quality < 0)
  26939. return;
  26940. glBindTexture(GL_TEXTURE_2D, id);
  26941. switch (quality)
  26942. {
  26943. case leastPossible:
  26944. {
  26945. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  26946. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  26947. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1.f);
  26948. }
  26949. break;
  26950. case linearNoMipmap:
  26951. {
  26952. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  26953. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  26954. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1.f);
  26955. }
  26956. break;
  26957. case nearestMipmap:
  26958. {
  26959. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  26960. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  26961. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1.f);
  26962. }
  26963. break;
  26964. case linearMipmap:
  26965. {
  26966. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  26967. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  26968. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 4.f);
  26969. }
  26970. break;
  26971. case maxQuality:
  26972. {
  26973. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  26974. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  26975. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.f);
  26976. }
  26977. break;
  26978. default:
  26979. gl3dAssertComment(0, "invalid quality");
  26980. break;
  26981. }
  26982. }
  26983. int GpuTexture::getTextureQuality()
  26984. {
  26985. if(id == leastPossible)
  26986. {
  26987. return 0;
  26988. }
  26989. glBindTexture(GL_TEXTURE_2D, id);
  26990. int param = 0;
  26991. glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &param);
  26992. switch (param)
  26993. {
  26994. case GL_NEAREST:
  26995. {
  26996. return leastPossible;
  26997. }
  26998. break;
  26999. case GL_NEAREST_MIPMAP_NEAREST:
  27000. {
  27001. return nearestMipmap;
  27002. }
  27003. break;
  27004. case GL_LINEAR_MIPMAP_NEAREST:
  27005. {
  27006. return linearMipmap;
  27007. }
  27008. break;
  27009. case GL_LINEAR_MIPMAP_LINEAR:
  27010. {
  27011. return maxQuality;
  27012. }
  27013. break;
  27014. }
  27015. return leastPossible;
  27016. }
  27017. glm::ivec2 GpuTexture::getTextureSize()
  27018. {
  27019. if (!id)
  27020. {
  27021. return glm::ivec2();
  27022. }
  27023. else
  27024. {
  27025. glBindTexture(GL_TEXTURE_2D, id);
  27026. int w=0, h=0;
  27027. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
  27028. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
  27029. return { w, h };
  27030. }
  27031. }
  27032. void gausianBlurRGB(unsigned char *data, int w, int h, int kernel)
  27033. {
  27034. unsigned char *newImage = new unsigned char[w * h * 3];
  27035. //actually compute this on the gpu if really needed
  27036. auto horiz = [&](int kernel)
  27037. {
  27038. //horizontal blur
  27039. for (int y = 0; y < h; y++)
  27040. {
  27041. for (int x = 0; x < w; x++)
  27042. {
  27043. glm::tvec3<int> colors = {};
  27044. int beg = std::max(0, x - kernel);
  27045. int end = std::min(x + kernel + 1, w);
  27046. for (int i = beg; i < end; i++)
  27047. {
  27048. colors.r += data[(i + y * w) * 3 + 0];
  27049. colors.g += data[(i + y * w) * 3 + 1];
  27050. colors.b += data[(i + y * w) * 3 + 2];
  27051. }
  27052. if (x - kernel < 0)
  27053. for (int i = kernel - x - 1; i >= 0; i--)
  27054. {
  27055. colors.r += data[(i + y * w) * 3 + 0];
  27056. colors.g += data[(i + y * w) * 3 + 1];
  27057. colors.b += data[(i + y * w) * 3 + 2];
  27058. }
  27059. if (x + kernel >= w)
  27060. for (int i = w - 1; i >= w - (x + kernel - w + 1); i--)
  27061. {
  27062. colors.r += data[(i + y * w) * 3 + 0];
  27063. colors.g += data[(i + y * w) * 3 + 1];
  27064. colors.b += data[(i + y * w) * 3 + 2];
  27065. }
  27066. colors /= kernel * 2 + 1;
  27067. //colors /= end - beg;
  27068. newImage[(x + y * w) * 3 + 0] = colors.r;
  27069. newImage[(x + y * w) * 3 + 1] = colors.g;
  27070. newImage[(x + y * w) * 3 + 2] = colors.b;
  27071. }
  27072. }
  27073. };
  27074. auto vert = [&](int kernel)
  27075. {
  27076. //vertical blur
  27077. for (int x = 0; x < w; x++)
  27078. {
  27079. for (int y = 0; y < h; y++)
  27080. {
  27081. glm::tvec3<int> colors = {};
  27082. int beg = std::max(0, y - kernel);
  27083. int end = std::min(y + kernel + 1, h);
  27084. for (int j = beg; j < end; j++)
  27085. {
  27086. colors.r += data[(x + j * w) * 3 + 0];
  27087. colors.g += data[(x + j * w) * 3 + 1];
  27088. colors.b += data[(x + j * w) * 3 + 2];
  27089. }
  27090. if (y - kernel < 0)
  27091. for (int j = kernel - y - 1; j >= 0; j--)
  27092. {
  27093. colors.r += data[(x + j * w) * 3 + 0];
  27094. colors.g += data[(x + j * w) * 3 + 1];
  27095. colors.b += data[(x + j * w) * 3 + 2];
  27096. }
  27097. if (y + kernel >= h)
  27098. for (int j = h - 1; j >= h - (y + kernel - h + 1); j--)
  27099. {
  27100. colors.r += data[(x + j * w) * 3 + 0];
  27101. colors.g += data[(x + j * w) * 3 + 1];
  27102. colors.b += data[(x + j * w) * 3 + 2];
  27103. }
  27104. colors /= kernel * 2 + 1;
  27105. //colors /= end - beg;
  27106. newImage[(x + y * w) * 3 + 0] = colors.r;
  27107. newImage[(x + y * w) * 3 + 1] = colors.g;
  27108. newImage[(x + y * w) * 3 + 2] = colors.b;
  27109. }
  27110. }
  27111. };
  27112. int iterations = 2;
  27113. for(int i=0;i<iterations;i++)
  27114. {
  27115. horiz(kernel);
  27116. vert(kernel);
  27117. }
  27118. for (int i = 0; i < w * h * 3; i++)
  27119. {
  27120. data[i] = newImage[i];
  27121. }
  27122. delete newImage;
  27123. }
  27124. };
  27125. #pragma endregion
  27126. ////////////////////////////////////////////////
  27127. //Shader.cpp
  27128. ////////////////////////////////////////////////
  27129. #pragma region Shader
  27130. #define GL3D_LOAD_SHADERS_FROM_HEADER_ONLY
  27131. #include <unordered_map>
  27132. namespace gl3d
  27133. {
  27134. GLint createShaderFromData(const char* data, GLenum shaderType, ErrorReporter &errorReporter)
  27135. {
  27136. GLuint shaderId = glCreateShader(shaderType);
  27137. glShaderSource(shaderId, 1, &data, nullptr);
  27138. glCompileShader(shaderId);
  27139. GLint rezult = 0;
  27140. glGetShaderiv(shaderId, GL_COMPILE_STATUS, &rezult);
  27141. if (!rezult)
  27142. {
  27143. char* message = 0;
  27144. int l = 0;
  27145. glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &l);
  27146. if (l)
  27147. {
  27148. message = new char[l];
  27149. glGetShaderInfoLog(shaderId, l, &l, message);
  27150. message[l - 1] = 0;
  27151. errorReporter.callErrorCallback(data);
  27152. errorReporter.callErrorCallback("----");
  27153. errorReporter.callErrorCallback(message);
  27154. delete[] message;
  27155. }
  27156. else
  27157. {
  27158. errorReporter.callErrorCallback(data);
  27159. errorReporter.callErrorCallback("----");
  27160. errorReporter.callErrorCallback("unknown error :(");
  27161. }
  27162. glDeleteShader(shaderId);
  27163. shaderId = 0;
  27164. return shaderId;
  27165. }
  27166. return shaderId;
  27167. }
  27168. #ifdef GL3D_LOAD_SHADERS_FROM_HEADER_ONLY
  27169. std::unordered_map<std::string, const char*> headerOnlyShaders =
  27170. {
  27171. //std::pair< std::string, const char*>{"name", "value"}
  27172. //#pragma shaderSources
  27173. std::pair<std::string, const char*>{"ssao.frag", "#version 330 core\n"
  27174. "out float fragColor;\n"
  27175. "noperspective in highp vec2 v_texCoords;\n"
  27176. "uniform sampler2D u_gPosition; \n"
  27177. "uniform isampler2D u_gNormal;\n"
  27178. "uniform sampler2D u_texNoise;\n"
  27179. "uniform vec3 samples[64];\n"
  27180. "uniform mat4 u_projection; \n"
  27181. "uniform mat4 u_view; \n"
  27182. "const int kernelSize = 64;\n"
  27183. "layout(std140) uniform u_SSAODATA\n"
  27184. "{\n"
  27185. "float radius;\n"
  27186. "float bias;\n"
  27187. "int samplesTestSize; \n"
  27188. "}ssaoDATA;\n"
  27189. "vec3 fromuShortToFloat(ivec3 a)\n"
  27190. "{\n"
  27191. "vec3 ret = a;\n"
  27192. "ret /= 65536;\n"
  27193. "ret *= 2.f;\n"
  27194. "ret -= 1.f;\n"
  27195. "return normalize(ret);\n"
  27196. "}\n"
  27197. "void main()\n"
  27198. "{\n"
  27199. "vec2 screenSize = textureSize(u_gPosition, 0).xy/2.f; \n"
  27200. "vec2 noiseScale = vec2(screenSize.x/4.0, screenSize.y/4.0);\n"
  27201. "vec2 noisePos = v_texCoords * noiseScale;\n"
  27202. "vec3 fragPos = texture(u_gPosition, v_texCoords).xyz;\n"
  27203. "vec3 normal = normalize( vec3(transpose(inverse(mat3(u_view))) * \n"
  27204. "fromuShortToFloat(texture(u_gNormal, v_texCoords).xyz)) );\n"
  27205. "vec3 randomVec = texture2D(u_texNoise, noisePos).xyz; \n"
  27206. "vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));\n"
  27207. "vec3 bitangent = cross(normal, tangent);\n"
  27208. "mat3 TBN = mat3(tangent, bitangent, normal); \n"
  27209. "float occlusion = 0.0;\n"
  27210. "int begin = int((kernelSize - ssaoDATA.samplesTestSize) * abs(randomVec.x));\n"
  27211. "for(int i = begin; i < begin + ssaoDATA.samplesTestSize; ++i)\n"
  27212. "{\n"
  27213. "vec3 samplePos = TBN * samples[i]; \n"
  27214. "samplePos = fragPos + samplePos * ssaoDATA.radius; \n"
  27215. "vec4 offset = vec4(samplePos, 1.0);\n"
  27216. "offset = u_projection * offset; \n"
  27217. "offset.xyz /= offset.w; \n"
  27218. "offset.xyz = offset.xyz * 0.5 + 0.5; \n"
  27219. "{\n"
  27220. "float sampleDepth = texture(u_gPosition, offset.xy).z; \n"
  27221. "float rangeCheck = smoothstep(0.0, 1.0, ssaoDATA.radius / abs(fragPos.z - sampleDepth));\n"
  27222. "occlusion += (sampleDepth >= samplePos.z + ssaoDATA.bias ? 1.0 : 0.0) * rangeCheck;\n"
  27223. "}\n"
  27224. "} \n"
  27225. "occlusion = 1.0 - (occlusion / kernelSize);\n"
  27226. "fragColor = occlusion;\n"
  27227. "}\n"},
  27228. std::pair<std::string, const char*>{"blur.frag", "#version 150\n"
  27229. "noperspective in vec2 v_texCoords;\n"
  27230. "uniform sampler2D u_ssaoInput;\n"
  27231. "out float fragColor;\n"
  27232. "void main ()\n"
  27233. "{\n"
  27234. "float result_1;\n"
  27235. "vec2 texelSize_2;\n"
  27236. "texelSize_2 = (1.0/(vec2(textureSize (u_ssaoInput, 0))));\n"
  27237. "vec2 tmpvar_3;\n"
  27238. "tmpvar_3 = (vec2(-2.0, -2.0) * texelSize_2);\n"
  27239. "vec2 P_4;\n"
  27240. "P_4 = (v_texCoords + tmpvar_3);\n"
  27241. "result_1 = textureLod (u_ssaoInput, P_4, 0.0).x;\n"
  27242. "vec2 tmpvar_5;\n"
  27243. "tmpvar_5 = (vec2(-1.0, -2.0) * texelSize_2);\n"
  27244. "vec2 P_6;\n"
  27245. "P_6 = (v_texCoords + tmpvar_5);\n"
  27246. "result_1 = (result_1 + textureLod (u_ssaoInput, P_6, 0.0).x);\n"
  27247. "vec2 tmpvar_7;\n"
  27248. "tmpvar_7 = (vec2(0.0, -2.0) * texelSize_2);\n"
  27249. "vec2 P_8;\n"
  27250. "P_8 = (v_texCoords + tmpvar_7);\n"
  27251. "result_1 = (result_1 + textureLod (u_ssaoInput, P_8, 0.0).x);\n"
  27252. "vec2 tmpvar_9;\n"
  27253. "tmpvar_9 = (vec2(1.0, -2.0) * texelSize_2);\n"
  27254. "vec2 P_10;\n"
  27255. "P_10 = (v_texCoords + tmpvar_9);\n"
  27256. "result_1 = (result_1 + textureLod (u_ssaoInput, P_10, 0.0).x);\n"
  27257. "vec2 tmpvar_11;\n"
  27258. "tmpvar_11 = (vec2(-2.0, -1.0) * texelSize_2);\n"
  27259. "vec2 P_12;\n"
  27260. "P_12 = (v_texCoords + tmpvar_11);\n"
  27261. "result_1 = (result_1 + textureLod (u_ssaoInput, P_12, 0.0).x);\n"
  27262. "vec2 tmpvar_13;\n"
  27263. "tmpvar_13 = -(texelSize_2);\n"
  27264. "vec2 P_14;\n"
  27265. "P_14 = (v_texCoords + tmpvar_13);\n"
  27266. "result_1 = (result_1 + textureLod (u_ssaoInput, P_14, 0.0).x);\n"
  27267. "vec2 tmpvar_15;\n"
  27268. "tmpvar_15 = (vec2(0.0, -1.0) * texelSize_2);\n"
  27269. "vec2 P_16;\n"
  27270. "P_16 = (v_texCoords + tmpvar_15);\n"
  27271. "result_1 = (result_1 + textureLod (u_ssaoInput, P_16, 0.0).x);\n"
  27272. "vec2 tmpvar_17;\n"
  27273. "tmpvar_17 = (vec2(1.0, -1.0) * texelSize_2);\n"
  27274. "vec2 P_18;\n"
  27275. "P_18 = (v_texCoords + tmpvar_17);\n"
  27276. "result_1 = (result_1 + textureLod (u_ssaoInput, P_18, 0.0).x);\n"
  27277. "vec2 tmpvar_19;\n"
  27278. "tmpvar_19 = (vec2(-2.0, 0.0) * texelSize_2);\n"
  27279. "vec2 P_20;\n"
  27280. "P_20 = (v_texCoords + tmpvar_19);\n"
  27281. "result_1 = (result_1 + textureLod (u_ssaoInput, P_20, 0.0).x);\n"
  27282. "vec2 tmpvar_21;\n"
  27283. "tmpvar_21 = (vec2(-1.0, 0.0) * texelSize_2);\n"
  27284. "vec2 P_22;\n"
  27285. "P_22 = (v_texCoords + tmpvar_21);\n"
  27286. "result_1 = (result_1 + textureLod (u_ssaoInput, P_22, 0.0).x);\n"
  27287. "result_1 = (result_1 + textureLod (u_ssaoInput, v_texCoords, 0.0).x);\n"
  27288. "vec2 tmpvar_23;\n"
  27289. "tmpvar_23 = (vec2(1.0, 0.0) * texelSize_2);\n"
  27290. "vec2 P_24;\n"
  27291. "P_24 = (v_texCoords + tmpvar_23);\n"
  27292. "result_1 = (result_1 + textureLod (u_ssaoInput, P_24, 0.0).x);\n"
  27293. "vec2 tmpvar_25;\n"
  27294. "tmpvar_25 = (vec2(-2.0, 1.0) * texelSize_2);\n"
  27295. "vec2 P_26;\n"
  27296. "P_26 = (v_texCoords + tmpvar_25);\n"
  27297. "result_1 = (result_1 + textureLod (u_ssaoInput, P_26, 0.0).x);\n"
  27298. "vec2 tmpvar_27;\n"
  27299. "tmpvar_27 = (vec2(-1.0, 1.0) * texelSize_2);\n"
  27300. "vec2 P_28;\n"
  27301. "P_28 = (v_texCoords + tmpvar_27);\n"
  27302. "result_1 = (result_1 + textureLod (u_ssaoInput, P_28, 0.0).x);\n"
  27303. "vec2 tmpvar_29;\n"
  27304. "tmpvar_29 = (vec2(0.0, 1.0) * texelSize_2);\n"
  27305. "vec2 P_30;\n"
  27306. "P_30 = (v_texCoords + tmpvar_29);\n"
  27307. "result_1 = (result_1 + textureLod (u_ssaoInput, P_30, 0.0).x);\n"
  27308. "vec2 P_31;\n"
  27309. "P_31 = (v_texCoords + texelSize_2);\n"
  27310. "result_1 = (result_1 + textureLod (u_ssaoInput, P_31, 0.0).x);\n"
  27311. "fragColor = (result_1 / 16.0);\n"
  27312. "}\n"},
  27313. std::pair<std::string, const char*>{"skyBox.vert", "#version 330\n"
  27314. "layout (location = 0) in vec3 aPos;\n"
  27315. "out vec3 v_texCoords;\n"
  27316. "uniform mat4 u_viewProjection;\n"
  27317. "void main()\n"
  27318. "{\n"
  27319. "v_texCoords = aPos;\n"
  27320. "vec4 pos = u_viewProjection * vec4(aPos, 1.0);\n"
  27321. "gl_Position = pos.xyww;\n"
  27322. "} \n"},
  27323. std::pair<std::string, const char*>{"skyBox.frag", "#version 150\n"
  27324. "out vec4 a_outColor;\n"
  27325. "in vec3 v_texCoords;\n"
  27326. "uniform samplerCube u_skybox;\n"
  27327. "uniform vec3 u_ambient;\n"
  27328. "uniform int u_skyBoxPresent;\n"
  27329. "void main ()\n"
  27330. "{\n"
  27331. "vec3 tmpvar_1;\n"
  27332. "tmpvar_1 = pow (u_ambient, vec3(2.2, 2.2, 2.2));\n"
  27333. "if ((u_skyBoxPresent != 0)) {\n"
  27334. "vec4 tmpvar_2;\n"
  27335. "tmpvar_2 = textureLod (u_skybox, v_texCoords, 2.0);\n"
  27336. "a_outColor.w = tmpvar_2.w;\n"
  27337. "a_outColor.xyz = (tmpvar_2.xyz * tmpvar_1);\n"
  27338. "} else {\n"
  27339. "a_outColor.xyz = tmpvar_1;\n"
  27340. "};\n"
  27341. "}\n"},
  27342. std::pair<std::string, const char*>{"preFilterSpecular.frag", "#version 150\n"
  27343. "out vec4 FragColor;\n"
  27344. "in vec3 v_localPos;\n"
  27345. "uniform samplerCube u_environmentMap;\n"
  27346. "uniform float u_roughness;\n"
  27347. "uniform uint u_sampleCount;\n"
  27348. "void main ()\n"
  27349. "{\n"
  27350. "float resolution_2;\n"
  27351. "float totalWeight_3;\n"
  27352. "vec3 prefilteredColor_4;\n"
  27353. "vec3 V_5;\n"
  27354. "vec3 N_6;\n"
  27355. "vec3 tmpvar_7;\n"
  27356. "tmpvar_7 = normalize(v_localPos);\n"
  27357. "N_6 = tmpvar_7;\n"
  27358. "V_5 = tmpvar_7;\n"
  27359. "prefilteredColor_4 = vec3(0.0, 0.0, 0.0);\n"
  27360. "totalWeight_3 = 0.0;\n"
  27361. "resolution_2 = float(textureSize (u_environmentMap, 0).x);\n"
  27362. "for (uint i_1 = uint(0); i_1 < u_sampleCount; i_1++) {\n"
  27363. "float tmpvar_8;\n"
  27364. "uint bits_9;\n"
  27365. "bits_9 = ((i_1 << 16u) | (i_1 >> 16u));\n"
  27366. "bits_9 = (((bits_9 & 1431655765u) << 1u) | ((bits_9 & 2863311530u) >> 1u));\n"
  27367. "bits_9 = (((bits_9 & 858993459u) << 2u) | ((bits_9 & 3435973836u) >> 2u));\n"
  27368. "bits_9 = (((bits_9 & 252645135u) << 4u) | ((bits_9 & 4042322160u) >> 4u));\n"
  27369. "bits_9 = (((bits_9 & 16711935u) << 8u) | ((bits_9 & 4278255360u) >> 8u));\n"
  27370. "tmpvar_8 = (float(bits_9) * 2.328306e-10);\n"
  27371. "vec2 tmpvar_10;\n"
  27372. "tmpvar_10.x = (float(i_1) / float(u_sampleCount));\n"
  27373. "tmpvar_10.y = tmpvar_8;\n"
  27374. "vec3 H_11;\n"
  27375. "float tmpvar_12;\n"
  27376. "tmpvar_12 = (u_roughness * u_roughness);\n"
  27377. "float tmpvar_13;\n"
  27378. "tmpvar_13 = (6.283185 * tmpvar_10.x);\n"
  27379. "float tmpvar_14;\n"
  27380. "tmpvar_14 = sqrt(((1.0 - tmpvar_8) / (1.0 + \n"
  27381. "(((tmpvar_12 * tmpvar_12) - 1.0) * tmpvar_8)\n"
  27382. ")));\n"
  27383. "float tmpvar_15;\n"
  27384. "tmpvar_15 = sqrt((1.0 - (tmpvar_14 * tmpvar_14)));\n"
  27385. "H_11.x = (cos(tmpvar_13) * tmpvar_15);\n"
  27386. "H_11.y = (sin(tmpvar_13) * tmpvar_15);\n"
  27387. "H_11.z = tmpvar_14;\n"
  27388. "float tmpvar_16;\n"
  27389. "tmpvar_16 = abs(N_6.z);\n"
  27390. "vec3 tmpvar_17;\n"
  27391. "if ((tmpvar_16 < 0.999)) {\n"
  27392. "tmpvar_17 = vec3(0.0, 0.0, 1.0);\n"
  27393. "} else {\n"
  27394. "tmpvar_17 = vec3(1.0, 0.0, 0.0);\n"
  27395. "};\n"
  27396. "vec3 tmpvar_18;\n"
  27397. "tmpvar_18 = normalize(((tmpvar_17.yzx * N_6.zxy) - (tmpvar_17.zxy * N_6.yzx)));\n"
  27398. "vec3 tmpvar_19;\n"
  27399. "tmpvar_19 = normalize(((\n"
  27400. "(tmpvar_18 * H_11.x)\n"
  27401. "+ \n"
  27402. "(((N_6.yzx * tmpvar_18.zxy) - (N_6.zxy * tmpvar_18.yzx)) * H_11.y)\n"
  27403. ") + (N_6 * tmpvar_14)));\n"
  27404. "vec3 tmpvar_20;\n"
  27405. "tmpvar_20 = normalize(((\n"
  27406. "(2.0 * dot (V_5, tmpvar_19))\n"
  27407. "* tmpvar_19) - V_5));\n"
  27408. "float tmpvar_21;\n"
  27409. "tmpvar_21 = max (dot (N_6, tmpvar_20), 0.0);\n"
  27410. "if ((tmpvar_21 > 0.0)) {\n"
  27411. "float tmpvar_22;\n"
  27412. "tmpvar_22 = (u_roughness * u_roughness);\n"
  27413. "float tmpvar_23;\n"
  27414. "tmpvar_23 = (tmpvar_22 * tmpvar_22);\n"
  27415. "float tmpvar_24;\n"
  27416. "tmpvar_24 = max (dot (N_6, tmpvar_19), 0.0);\n"
  27417. "float tmpvar_25;\n"
  27418. "tmpvar_25 = (((tmpvar_24 * tmpvar_24) * (tmpvar_23 - 1.0)) + 1.0);\n"
  27419. "float tmpvar_26;\n"
  27420. "tmpvar_26 = (12.56637 / ((6.0 * resolution_2) * resolution_2));\n"
  27421. "float tmpvar_27;\n"
  27422. "tmpvar_27 = (1.0/(((\n"
  27423. "float(u_sampleCount)\n"
  27424. "* \n"
  27425. "((((tmpvar_23 / \n"
  27426. "((3.141593 * tmpvar_25) * tmpvar_25)\n"
  27427. ") * max (\n"
  27428. "dot (N_6, tmpvar_19)\n"
  27429. ", 0.0)) / (4.0 * max (\n"
  27430. "dot (tmpvar_19, V_5)\n"
  27431. ", 0.0))) + 0.0001)\n"
  27432. ") + 0.0001)));\n"
  27433. "float tmpvar_28;\n"
  27434. "if ((u_roughness == 0.0)) {\n"
  27435. "tmpvar_28 = 0.0;\n"
  27436. "} else {\n"
  27437. "tmpvar_28 = (0.5 * log2((tmpvar_27 / tmpvar_26)));\n"
  27438. "};\n"
  27439. "prefilteredColor_4 = (prefilteredColor_4 + (textureLod (u_environmentMap, tmpvar_20, tmpvar_28).xyz * tmpvar_21));\n"
  27440. "totalWeight_3 = (totalWeight_3 + tmpvar_21);\n"
  27441. "};\n"
  27442. "};\n"
  27443. "prefilteredColor_4 = (prefilteredColor_4 / totalWeight_3);\n"
  27444. "vec4 tmpvar_29;\n"
  27445. "tmpvar_29.w = 1.0;\n"
  27446. "tmpvar_29.xyz = prefilteredColor_4;\n"
  27447. "FragColor = tmpvar_29;\n"
  27448. "}\n"},
  27449. std::pair<std::string, const char*>{"hdrToCubeMap.vert", "#version 330\n"
  27450. "layout (location = 0) in vec3 aPos;\n"
  27451. "out vec3 v_localPos;\n"
  27452. "uniform mat4 u_viewProjection;\n"
  27453. "void main()\n"
  27454. "{\n"
  27455. "v_localPos = aPos;\n"
  27456. "gl_Position = u_viewProjection * vec4(aPos, 1.0);\n"
  27457. "} \n"},
  27458. std::pair<std::string, const char*>{"hdrToCubeMap.frag", "#version 150\n"
  27459. "out vec4 FragColor;\n"
  27460. "in vec3 v_localPos;\n"
  27461. "uniform sampler2D u_equirectangularMap;\n"
  27462. "void main ()\n"
  27463. "{\n"
  27464. "vec3 tmpvar_1;\n"
  27465. "tmpvar_1 = normalize(v_localPos);\n"
  27466. "vec2 uv_2;\n"
  27467. "float tmpvar_3;\n"
  27468. "float tmpvar_4;\n"
  27469. "tmpvar_4 = (min (abs(\n"
  27470. "(tmpvar_1.z / tmpvar_1.x)\n"
  27471. "), 1.0) / max (abs(\n"
  27472. "(tmpvar_1.z / tmpvar_1.x)\n"
  27473. "), 1.0));\n"
  27474. "float tmpvar_5;\n"
  27475. "tmpvar_5 = (tmpvar_4 * tmpvar_4);\n"
  27476. "tmpvar_5 = (((\n"
  27477. "((((\n"
  27478. "((((-0.01213232 * tmpvar_5) + 0.05368138) * tmpvar_5) - 0.1173503)\n"
  27479. "* tmpvar_5) + 0.1938925) * tmpvar_5) - 0.3326756)\n"
  27480. "* tmpvar_5) + 0.9999793) * tmpvar_4);\n"
  27481. "tmpvar_5 = (tmpvar_5 + (float(\n"
  27482. "(abs((tmpvar_1.z / tmpvar_1.x)) > 1.0)\n"
  27483. ") * (\n"
  27484. "(tmpvar_5 * -2.0)\n"
  27485. "+ 1.570796)));\n"
  27486. "tmpvar_3 = (tmpvar_5 * sign((tmpvar_1.z / tmpvar_1.x)));\n"
  27487. "if ((abs(tmpvar_1.x) > (1e-8 * abs(tmpvar_1.z)))) {\n"
  27488. "if ((tmpvar_1.x < 0.0)) {\n"
  27489. "if ((tmpvar_1.z >= 0.0)) {\n"
  27490. "tmpvar_3 += 3.141593;\n"
  27491. "} else {\n"
  27492. "tmpvar_3 = (tmpvar_3 - 3.141593);\n"
  27493. "};\n"
  27494. "};\n"
  27495. "} else {\n"
  27496. "tmpvar_3 = (sign(tmpvar_1.z) * 1.570796);\n"
  27497. "};\n"
  27498. "vec2 tmpvar_6;\n"
  27499. "tmpvar_6.x = tmpvar_3;\n"
  27500. "tmpvar_6.y = (sign(tmpvar_1.y) * (1.570796 - (\n"
  27501. "sqrt((1.0 - abs(tmpvar_1.y)))\n"
  27502. "* \n"
  27503. "(1.570796 + (abs(tmpvar_1.y) * (-0.2146018 + (\n"
  27504. "abs(tmpvar_1.y)\n"
  27505. "* \n"
  27506. "(0.08656672 + (abs(tmpvar_1.y) * -0.03102955))\n"
  27507. "))))\n"
  27508. ")));\n"
  27509. "uv_2 = (tmpvar_6 * vec2(0.1591, 0.3183));\n"
  27510. "uv_2 = (uv_2 + 0.5);\n"
  27511. "vec4 tmpvar_7;\n"
  27512. "tmpvar_7.w = 1.0;\n"
  27513. "tmpvar_7.xyz = texture (u_equirectangularMap, uv_2).xyz;\n"
  27514. "FragColor = tmpvar_7;\n"
  27515. "}\n"},
  27516. std::pair<std::string, const char*>{"convolute.frag", "#version 150\n"
  27517. "out vec4 fragColor;\n"
  27518. "in vec3 v_localPos;\n"
  27519. "uniform samplerCube u_environmentMap;\n"
  27520. "uniform float u_sampleQuality;\n"
  27521. "void main ()\n"
  27522. "{\n"
  27523. "float nrSamples_2;\n"
  27524. "float sampleDelta_3;\n"
  27525. "vec3 right_4;\n"
  27526. "vec3 up_5;\n"
  27527. "vec3 irradiance_6;\n"
  27528. "vec3 normal_7;\n"
  27529. "vec3 tmpvar_8;\n"
  27530. "tmpvar_8 = normalize(v_localPos);\n"
  27531. "normal_7 = tmpvar_8;\n"
  27532. "irradiance_6 = vec3(0.0, 0.0, 0.0);\n"
  27533. "vec3 tmpvar_9;\n"
  27534. "tmpvar_9 = normalize(((vec3(1.0, 0.0, 0.0) * tmpvar_8.zxy) - (vec3(0.0, 0.0, 1.0) * tmpvar_8.yzx)));\n"
  27535. "right_4 = tmpvar_9;\n"
  27536. "up_5 = normalize(((tmpvar_8.yzx * tmpvar_9.zxy) - (tmpvar_8.zxy * tmpvar_9.yzx)));\n"
  27537. "sampleDelta_3 = u_sampleQuality;\n"
  27538. "nrSamples_2 = 0.0;\n"
  27539. "for (float phi_1 = 0.0; phi_1 < 6.283185; phi_1 = (phi_1 + sampleDelta_3)) {\n"
  27540. "for (float theta_10 = 0.0; theta_10 < 1.570796; theta_10 = (theta_10 + sampleDelta_3)) {\n"
  27541. "float tmpvar_11;\n"
  27542. "tmpvar_11 = cos(theta_10);\n"
  27543. "vec3 tmpvar_12;\n"
  27544. "tmpvar_12.x = (sin(theta_10) * cos(phi_1));\n"
  27545. "tmpvar_12.y = (sin(theta_10) * sin(phi_1));\n"
  27546. "tmpvar_12.z = tmpvar_11;\n"
  27547. "irradiance_6 = (irradiance_6 + ((texture (u_environmentMap, \n"
  27548. "(((tmpvar_12.x * right_4) + (tmpvar_12.y * up_5)) + (tmpvar_11 * normal_7))\n"
  27549. ").xyz * \n"
  27550. "cos(theta_10)\n"
  27551. ") * sin(theta_10)));\n"
  27552. "nrSamples_2 += 1.0;\n"
  27553. "};\n"
  27554. "};\n"
  27555. "irradiance_6 = (irradiance_6 * (3.141593 / nrSamples_2));\n"
  27556. "vec4 tmpvar_13;\n"
  27557. "tmpvar_13.w = 1.0;\n"
  27558. "tmpvar_13.xyz = irradiance_6;\n"
  27559. "fragColor = tmpvar_13;\n"
  27560. "}\n"},
  27561. std::pair<std::string, const char*>{"atmosphericScattering.frag", "#version 150\n"
  27562. "uniform vec3 u_lightPos;\n"
  27563. "uniform vec3 u_color1;\n"
  27564. "uniform vec3 u_color2;\n"
  27565. "uniform vec3 u_groundColor;\n"
  27566. "uniform float u_g;\n"
  27567. "uniform int u_useGround;\n"
  27568. "in vec3 v_localPos;\n"
  27569. "out vec3 fragColor;\n"
  27570. "void main ()\n"
  27571. "{\n"
  27572. "vec3 tmpvar_1;\n"
  27573. "tmpvar_1 = normalize(v_localPos);\n"
  27574. "vec3 tmpvar_2;\n"
  27575. "tmpvar_2 = normalize(u_lightPos);\n"
  27576. "float tmpvar_3;\n"
  27577. "tmpvar_3 = max (tmpvar_1.y, 0.0);\n"
  27578. "float tmpvar_4;\n"
  27579. "tmpvar_4 = (1.0 - tmpvar_3);\n"
  27580. "float tmpvar_5;\n"
  27581. "tmpvar_5 = (u_g * u_g);\n"
  27582. "float tmpvar_6;\n"
  27583. "tmpvar_6 = dot (tmpvar_2, tmpvar_1);\n"
  27584. "vec3 tmpvar_7;\n"
  27585. "tmpvar_7 = (((u_color1 + \n"
  27586. "((((1.5 * \n"
  27587. "((1.0 - tmpvar_5) / (2.0 + tmpvar_5))\n"
  27588. ") * (1.0 + \n"
  27589. "(tmpvar_6 * tmpvar_6)\n"
  27590. ")) / pow ((\n"
  27591. "(1.0 + tmpvar_5)\n"
  27592. "- \n"
  27593. "((2.0 * u_g) * tmpvar_6)\n"
  27594. "), 1.5)) * u_color2)\n"
  27595. ") + (\n"
  27596. "((1.0 - abs(tmpvar_2.y)) * u_color2)\n"
  27597. "* \n"
  27598. "pow (tmpvar_4, 16.0)\n"
  27599. ")) + (pow (tmpvar_4, 16.0) * u_color2));\n"
  27600. "if (((tmpvar_3 < 0.02) && (u_useGround != 0))) {\n"
  27601. "float tmpvar_8;\n"
  27602. "tmpvar_8 = min (max ((tmpvar_3 / 0.02), 0.0), 1.0);\n"
  27603. "fragColor = mix (u_groundColor, tmpvar_7, vec3((tmpvar_8 * (tmpvar_8 * tmpvar_8))));\n"
  27604. "} else {\n"
  27605. "fragColor = tmpvar_7;\n"
  27606. "};\n"
  27607. "}\n"},
  27608. std::pair<std::string, const char*>{"varienceShadowMap.frag", "#version 150\n"
  27609. "uniform sampler2D u_albedoSampler;\n"
  27610. "uniform int u_hasTexture;\n"
  27611. "in vec2 v_texCoord;\n"
  27612. "out vec2 outColor;\n"
  27613. "void main ()\n"
  27614. "{\n"
  27615. "if ((u_hasTexture != 0)) {\n"
  27616. "vec4 tmpvar_1;\n"
  27617. "tmpvar_1 = texture (u_albedoSampler, v_texCoord);\n"
  27618. "if ((tmpvar_1.w <= 0.1)) {\n"
  27619. "discard;\n"
  27620. "};\n"
  27621. "};\n"
  27622. "vec2 tmpvar_2;\n"
  27623. "tmpvar_2.x = gl_FragCoord.z;\n"
  27624. "tmpvar_2.y = (gl_FragCoord.z * gl_FragCoord.z);\n"
  27625. "outColor = tmpvar_2;\n"
  27626. "}\n"},
  27627. std::pair<std::string, const char*>{"pointShadow.vert", "#version 430\n"
  27628. "layout(location = 0) in vec3 a_positions;\n"
  27629. "layout(location = 1) in vec3 a_normals; \n"
  27630. "layout(location = 2) in vec2 a_texCoord;\n"
  27631. "layout(location = 3) in ivec4 a_jointsId;\n"
  27632. "layout(location = 4) in vec4 a_weights;\n"
  27633. "uniform mat4 u_transform; \n"
  27634. "readonly restrict layout(std140) buffer u_jointTransforms\n"
  27635. "{\n"
  27636. "mat4 jointTransforms[];\n"
  27637. "};\n"
  27638. "uniform int u_hasAnimations;\n"
  27639. "out vec2 v_texCoord;\n"
  27640. "void main()\n"
  27641. "{\n"
  27642. "vec4 totalLocalPos = vec4(0.f);\n"
  27643. "if(u_hasAnimations != 0)\n"
  27644. "{\n"
  27645. "for(int i=0; i<4; i++)\n"
  27646. "{\n"
  27647. "if(a_jointsId[i] < 0){break;}\n"
  27648. "mat4 jointTransform = jointTransforms[a_jointsId[i]];\n"
  27649. "vec4 posePosition = jointTransform * vec4(a_positions, 1);\n"
  27650. "totalLocalPos += posePosition * a_weights[i];\n"
  27651. "}\n"
  27652. "}else\n"
  27653. "{\n"
  27654. "totalLocalPos = vec4(a_positions, 1.f);\n"
  27655. "}\n"
  27656. "gl_Position = u_transform * totalLocalPos;\n"
  27657. "v_texCoord = a_texCoord;\n"
  27658. "} \n"},
  27659. std::pair<std::string, const char*>{"pointShadow.geom", "#version 330 core\n"
  27660. "layout (triangles) in;\n"
  27661. "layout (triangle_strip, max_vertices=18) out;\n"
  27662. "uniform mat4 u_shadowMatrices[6];\n"
  27663. "uniform int u_lightIndex;\n"
  27664. "out vec4 v_fragPos; \n"
  27665. "out vec2 v_finalTexCoord;\n"
  27666. "in vec2 v_texCoord[3];\n"
  27667. "void main()\n"
  27668. "{\n"
  27669. "for(int face = 0; face < 6; ++face)\n"
  27670. "{\n"
  27671. "gl_Layer = face + u_lightIndex * 6; \n"
  27672. "for(int i = 0; i < 3; ++i) \n"
  27673. "{\n"
  27674. "v_fragPos = gl_in[i].gl_Position;\n"
  27675. "v_finalTexCoord = v_texCoord[i];\n"
  27676. "gl_Position = u_shadowMatrices[face] * v_fragPos;\n"
  27677. "EmitVertex();\n"
  27678. "} \n"
  27679. "EndPrimitive();\n"
  27680. "}\n"
  27681. "} \n"},
  27682. std::pair<std::string, const char*>{"pointShadow.frag", "#version 150\n"
  27683. "uniform sampler2D u_albedoSampler;\n"
  27684. "uniform int u_hasTexture;\n"
  27685. "uniform vec3 u_lightPos;\n"
  27686. "uniform float u_farPlane;\n"
  27687. "in vec4 v_fragPos;\n"
  27688. "in vec2 v_finalTexCoord;\n"
  27689. "void main ()\n"
  27690. "{\n"
  27691. "if ((u_hasTexture != 0)) {\n"
  27692. "vec4 tmpvar_1;\n"
  27693. "tmpvar_1 = texture (u_albedoSampler, v_finalTexCoord);\n"
  27694. "if (((tmpvar_1.w * 255.0) < 1.0)) {\n"
  27695. "discard;\n"
  27696. "};\n"
  27697. "};\n"
  27698. "vec3 x_2;\n"
  27699. "x_2 = (v_fragPos.xyz - u_lightPos);\n"
  27700. "gl_FragDepth = (sqrt(dot (x_2, x_2)) / u_farPlane);\n"
  27701. "}\n"},
  27702. std::pair<std::string, const char*>{"postProcess.frag", "#version 150\n"
  27703. "out vec4 a_color;\n"
  27704. "noperspective in vec2 v_texCoords;\n"
  27705. "uniform sampler2D u_colorTexture;\n"
  27706. "uniform sampler2D u_bloomTexture;\n"
  27707. "uniform float u_bloomIntensity;\n"
  27708. "uniform float u_exposure;\n"
  27709. "uniform int u_useSSAO;\n"
  27710. "uniform float u_ssaoExponent;\n"
  27711. "uniform sampler2D u_ssao;\n"
  27712. "void main ()\n"
  27713. "{\n"
  27714. "float ssaof_1;\n"
  27715. "vec4 tmpvar_2;\n"
  27716. "tmpvar_2 = texture (u_colorTexture, v_texCoords);\n"
  27717. "ssaof_1 = 1.0;\n"
  27718. "if ((u_useSSAO != 0)) {\n"
  27719. "ssaof_1 = pow (texture (u_ssao, v_texCoords).x, u_ssaoExponent);\n"
  27720. "} else {\n"
  27721. "ssaof_1 = 1.0;\n"
  27722. "};\n"
  27723. "a_color.xyz = ((texture (u_bloomTexture, v_texCoords).xyz * u_bloomIntensity) + (tmpvar_2.xyz * ssaof_1));\n"
  27724. "vec3 color_3;\n"
  27725. "color_3 = (a_color.xyz * u_exposure);\n"
  27726. "mat3 tmpvar_4;\n"
  27727. "tmpvar_4[0].x = 0.59719;\n"
  27728. "tmpvar_4[1].x = 0.35458;\n"
  27729. "tmpvar_4[2].x = 0.04823;\n"
  27730. "tmpvar_4[0].y = 0.076;\n"
  27731. "tmpvar_4[1].y = 0.90834;\n"
  27732. "tmpvar_4[2].y = 0.01566;\n"
  27733. "tmpvar_4[0].z = 0.0284;\n"
  27734. "tmpvar_4[1].z = 0.13383;\n"
  27735. "tmpvar_4[2].z = 0.83777;\n"
  27736. "color_3 = (tmpvar_4 * color_3);\n"
  27737. "mat3 tmpvar_5;\n"
  27738. "tmpvar_5[0].x = 1.60475;\n"
  27739. "tmpvar_5[1].x = -0.53108;\n"
  27740. "tmpvar_5[2].x = -0.07367;\n"
  27741. "tmpvar_5[0].y = -0.10208;\n"
  27742. "tmpvar_5[1].y = 1.10813;\n"
  27743. "tmpvar_5[2].y = -0.00605;\n"
  27744. "tmpvar_5[0].z = -0.00327;\n"
  27745. "tmpvar_5[1].z = -0.07276;\n"
  27746. "tmpvar_5[2].z = 1.07602;\n"
  27747. "color_3 = (tmpvar_5 * ((\n"
  27748. "(color_3 * (color_3 + 0.0245786))\n"
  27749. "- 9.0537e-5) / (\n"
  27750. "(color_3 * ((0.983729 * color_3) + 0.432951))\n"
  27751. "+ 0.238081)));\n"
  27752. "vec3 tmpvar_6;\n"
  27753. "tmpvar_6 = clamp (color_3, 0.0, 1.0);\n"
  27754. "color_3 = tmpvar_6;\n"
  27755. "a_color.xyz = pow (tmpvar_6, vec3(0.4545454, 0.4545454, 0.4545454));\n"
  27756. "a_color.w = tmpvar_2.w;\n"
  27757. "}\n"},
  27758. std::pair<std::string, const char*>{"gausianBlur.frag", "#version 150\n"
  27759. "noperspective in vec2 v_texCoords;\n"
  27760. "uniform sampler2D u_toBlurcolorInput;\n"
  27761. "out vec3 fragColor;\n"
  27762. "uniform bool u_horizontal;\n"
  27763. "uniform int u_mip;\n"
  27764. "uniform vec2 u_texel;\n"
  27765. "void main ()\n"
  27766. "{\n"
  27767. "vec3 result_1;\n"
  27768. "result_1 = (textureLod (u_toBlurcolorInput, v_texCoords, float(u_mip)).xyz * 0.227027);\n"
  27769. "if (u_horizontal) {\n"
  27770. "vec2 tmpvar_2;\n"
  27771. "tmpvar_2.y = 0.0;\n"
  27772. "float tmpvar_3;\n"
  27773. "tmpvar_3 = u_texel.x;\n"
  27774. "tmpvar_2.x = tmpvar_3;\n"
  27775. "float tmpvar_4;\n"
  27776. "tmpvar_4 = float(u_mip);\n"
  27777. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_2), tmpvar_4).xyz * 0.1945946));\n"
  27778. "vec2 tmpvar_5;\n"
  27779. "tmpvar_5.y = 0.0;\n"
  27780. "tmpvar_5.x = tmpvar_3;\n"
  27781. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_5), tmpvar_4).xyz * 0.1945946));\n"
  27782. "vec2 tmpvar_6;\n"
  27783. "tmpvar_6.y = 0.0;\n"
  27784. "float tmpvar_7;\n"
  27785. "tmpvar_7 = (u_texel.x * 2.0);\n"
  27786. "tmpvar_6.x = tmpvar_7;\n"
  27787. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_6), tmpvar_4).xyz * 0.1216216));\n"
  27788. "vec2 tmpvar_8;\n"
  27789. "tmpvar_8.y = 0.0;\n"
  27790. "tmpvar_8.x = tmpvar_7;\n"
  27791. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_8), tmpvar_4).xyz * 0.1216216));\n"
  27792. "vec2 tmpvar_9;\n"
  27793. "tmpvar_9.y = 0.0;\n"
  27794. "float tmpvar_10;\n"
  27795. "tmpvar_10 = (u_texel.x * 3.0);\n"
  27796. "tmpvar_9.x = tmpvar_10;\n"
  27797. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_9), tmpvar_4).xyz * 0.054054));\n"
  27798. "vec2 tmpvar_11;\n"
  27799. "tmpvar_11.y = 0.0;\n"
  27800. "tmpvar_11.x = tmpvar_10;\n"
  27801. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_11), tmpvar_4).xyz * 0.054054));\n"
  27802. "vec2 tmpvar_12;\n"
  27803. "tmpvar_12.y = 0.0;\n"
  27804. "float tmpvar_13;\n"
  27805. "tmpvar_13 = (u_texel.x * 4.0);\n"
  27806. "tmpvar_12.x = tmpvar_13;\n"
  27807. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_12), tmpvar_4).xyz * 0.016216));\n"
  27808. "vec2 tmpvar_14;\n"
  27809. "tmpvar_14.y = 0.0;\n"
  27810. "tmpvar_14.x = tmpvar_13;\n"
  27811. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_14), tmpvar_4).xyz * 0.016216));\n"
  27812. "} else {\n"
  27813. "vec2 tmpvar_15;\n"
  27814. "tmpvar_15.x = 0.0;\n"
  27815. "float tmpvar_16;\n"
  27816. "tmpvar_16 = u_texel.y;\n"
  27817. "tmpvar_15.y = tmpvar_16;\n"
  27818. "float tmpvar_17;\n"
  27819. "tmpvar_17 = float(u_mip);\n"
  27820. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_15), tmpvar_17).xyz * 0.1945946));\n"
  27821. "vec2 tmpvar_18;\n"
  27822. "tmpvar_18.x = 0.0;\n"
  27823. "tmpvar_18.y = tmpvar_16;\n"
  27824. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_18), tmpvar_17).xyz * 0.1945946));\n"
  27825. "vec2 tmpvar_19;\n"
  27826. "tmpvar_19.x = 0.0;\n"
  27827. "float tmpvar_20;\n"
  27828. "tmpvar_20 = (u_texel.y * 2.0);\n"
  27829. "tmpvar_19.y = tmpvar_20;\n"
  27830. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_19), tmpvar_17).xyz * 0.1216216));\n"
  27831. "vec2 tmpvar_21;\n"
  27832. "tmpvar_21.x = 0.0;\n"
  27833. "tmpvar_21.y = tmpvar_20;\n"
  27834. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_21), tmpvar_17).xyz * 0.1216216));\n"
  27835. "vec2 tmpvar_22;\n"
  27836. "tmpvar_22.x = 0.0;\n"
  27837. "float tmpvar_23;\n"
  27838. "tmpvar_23 = (u_texel.y * 3.0);\n"
  27839. "tmpvar_22.y = tmpvar_23;\n"
  27840. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_22), tmpvar_17).xyz * 0.054054));\n"
  27841. "vec2 tmpvar_24;\n"
  27842. "tmpvar_24.x = 0.0;\n"
  27843. "tmpvar_24.y = tmpvar_23;\n"
  27844. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_24), tmpvar_17).xyz * 0.054054));\n"
  27845. "vec2 tmpvar_25;\n"
  27846. "tmpvar_25.x = 0.0;\n"
  27847. "float tmpvar_26;\n"
  27848. "tmpvar_26 = (u_texel.y * 4.0);\n"
  27849. "tmpvar_25.y = tmpvar_26;\n"
  27850. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords + tmpvar_25), tmpvar_17).xyz * 0.016216));\n"
  27851. "vec2 tmpvar_27;\n"
  27852. "tmpvar_27.x = 0.0;\n"
  27853. "tmpvar_27.y = tmpvar_26;\n"
  27854. "result_1 = (result_1 + (textureLod (u_toBlurcolorInput, (v_texCoords - tmpvar_27), tmpvar_17).xyz * 0.016216));\n"
  27855. "};\n"
  27856. "fragColor = result_1;\n"
  27857. "}\n"},
  27858. std::pair<std::string, const char*>{"filterDown.frag", "#version 150\n"
  27859. "out vec3 a_color;\n"
  27860. "noperspective in vec2 v_texCoords;\n"
  27861. "uniform sampler2D u_texture;\n"
  27862. "uniform int u_mip;\n"
  27863. "void main ()\n"
  27864. "{\n"
  27865. "vec2 tmpvar_1;\n"
  27866. "tmpvar_1 = (1.0/(vec2(textureSize (u_texture, u_mip))));\n"
  27867. "vec2 tmpvar_2;\n"
  27868. "tmpvar_2 = (tmpvar_1 * 2.0);\n"
  27869. "float tmpvar_3;\n"
  27870. "tmpvar_3 = float(u_mip);\n"
  27871. "vec4 tmpvar_4;\n"
  27872. "tmpvar_4 = textureLod (u_texture, (v_texCoords + (tmpvar_2 * vec2(0.0, 1.0))), tmpvar_3);\n"
  27873. "vec4 tmpvar_5;\n"
  27874. "tmpvar_5 = textureLod (u_texture, (v_texCoords + (tmpvar_2 * vec2(-1.0, 0.0))), tmpvar_3);\n"
  27875. "vec4 tmpvar_6;\n"
  27876. "tmpvar_6 = textureLod (u_texture, v_texCoords, tmpvar_3);\n"
  27877. "vec4 tmpvar_7;\n"
  27878. "tmpvar_7 = textureLod (u_texture, (v_texCoords + (tmpvar_2 * vec2(1.0, 0.0))), tmpvar_3);\n"
  27879. "vec4 tmpvar_8;\n"
  27880. "tmpvar_8 = textureLod (u_texture, (v_texCoords + (tmpvar_2 * vec2(0.0, -1.0))), tmpvar_3);\n"
  27881. "a_color = (((\n"
  27882. "((0.125 * ((textureLod (u_texture, \n"
  27883. "(v_texCoords + (tmpvar_1 * vec2(-1.0, 1.0)))\n"
  27884. ", tmpvar_3).xyz + textureLod (u_texture, \n"
  27885. "(v_texCoords + tmpvar_1)\n"
  27886. ", tmpvar_3).xyz) + (textureLod (u_texture, \n"
  27887. "(v_texCoords + (tmpvar_1 * vec2(1.0, -1.0)))\n"
  27888. ", tmpvar_3).xyz + textureLod (u_texture, \n"
  27889. "(v_texCoords - tmpvar_1)\n"
  27890. ", tmpvar_3).xyz))) + (0.03125 * ((textureLod (u_texture, \n"
  27891. "(v_texCoords + (tmpvar_2 * vec2(-1.0, 1.0)))\n"
  27892. ", tmpvar_3).xyz + tmpvar_4.xyz) + (tmpvar_5.xyz + tmpvar_6.xyz))))\n"
  27893. "+ \n"
  27894. "(0.03125 * ((textureLod (u_texture, (v_texCoords + tmpvar_2), tmpvar_3).xyz + tmpvar_4.xyz) + (tmpvar_7.xyz + tmpvar_6.xyz)))\n"
  27895. ") + (0.03125 * \n"
  27896. "((textureLod (u_texture, (v_texCoords - tmpvar_2), tmpvar_3).xyz + tmpvar_8.xyz) + (tmpvar_5.xyz + tmpvar_6.xyz))\n"
  27897. ")) + (0.03125 * (\n"
  27898. "(textureLod (u_texture, (v_texCoords + (tmpvar_2 * vec2(1.0, -1.0))), tmpvar_3).xyz + tmpvar_8.xyz)\n"
  27899. "+ \n"
  27900. "(tmpvar_7.xyz + tmpvar_6.xyz)\n"
  27901. ")));\n"
  27902. "}\n"},
  27903. std::pair<std::string, const char*>{"filter.frag", "#version 150\n"
  27904. "out vec4 a_outBloom;\n"
  27905. "noperspective in vec2 v_texCoords;\n"
  27906. "uniform sampler2D u_texture;\n"
  27907. "uniform float u_exposure;\n"
  27908. "uniform float u_tresshold;\n"
  27909. "void main ()\n"
  27910. "{\n"
  27911. "vec3 color_1;\n"
  27912. "color_1 = (texture (u_texture, v_texCoords).xyz * u_exposure);\n"
  27913. "mat3 tmpvar_2;\n"
  27914. "tmpvar_2[0].x = 0.59719;\n"
  27915. "tmpvar_2[1].x = 0.35458;\n"
  27916. "tmpvar_2[2].x = 0.04823;\n"
  27917. "tmpvar_2[0].y = 0.076;\n"
  27918. "tmpvar_2[1].y = 0.90834;\n"
  27919. "tmpvar_2[2].y = 0.01566;\n"
  27920. "tmpvar_2[0].z = 0.0284;\n"
  27921. "tmpvar_2[1].z = 0.13383;\n"
  27922. "tmpvar_2[2].z = 0.83777;\n"
  27923. "color_1 = (tmpvar_2 * color_1);\n"
  27924. "mat3 tmpvar_3;\n"
  27925. "tmpvar_3[0].x = 1.60475;\n"
  27926. "tmpvar_3[1].x = -0.53108;\n"
  27927. "tmpvar_3[2].x = -0.07367;\n"
  27928. "tmpvar_3[0].y = -0.10208;\n"
  27929. "tmpvar_3[1].y = 1.10813;\n"
  27930. "tmpvar_3[2].y = -0.00605;\n"
  27931. "tmpvar_3[0].z = -0.00327;\n"
  27932. "tmpvar_3[1].z = -0.07276;\n"
  27933. "tmpvar_3[2].z = 1.07602;\n"
  27934. "color_1 = (tmpvar_3 * ((\n"
  27935. "(color_1 * (color_1 + 0.0245786))\n"
  27936. "- 9.0537e-5) / (\n"
  27937. "(color_1 * ((0.983729 * color_1) + 0.432951))\n"
  27938. "+ 0.238081)));\n"
  27939. "vec3 tmpvar_4;\n"
  27940. "tmpvar_4 = clamp (color_1, 0.0, 1.0);\n"
  27941. "color_1 = tmpvar_4;\n"
  27942. "float tmpvar_5;\n"
  27943. "tmpvar_5 = dot (tmpvar_4, vec3(0.2126, 0.7152, 0.0722));\n"
  27944. "if ((tmpvar_5 > u_tresshold)) {\n"
  27945. "vec4 tmpvar_6;\n"
  27946. "tmpvar_6.w = 1.0;\n"
  27947. "tmpvar_6.xyz = tmpvar_4;\n"
  27948. "a_outBloom = tmpvar_6;\n"
  27949. "} else {\n"
  27950. "a_outBloom = vec4(0.0, 0.0, 0.0, 1.0);\n"
  27951. "};\n"
  27952. "a_outBloom = clamp (a_outBloom, 0.0, 1000.0);\n"
  27953. "}\n"},
  27954. std::pair<std::string, const char*>{"colorCorrection.frag", "#version 150\n"
  27955. "out vec4 a_color;\n"
  27956. "noperspective in vec2 v_texCoords;\n"
  27957. "uniform sampler2D u_texture;\n"
  27958. "uniform sampler2D u_lookup;\n"
  27959. "void main ()\n"
  27960. "{\n"
  27961. "vec4 tmpvar_1;\n"
  27962. "tmpvar_1 = texture (u_texture, v_texCoords);\n"
  27963. "int tmpvar_2;\n"
  27964. "tmpvar_2 = int(floor((64.0 * tmpvar_1.z)));\n"
  27965. "int tmpvar_3;\n"
  27966. "tmpvar_3 = min (int(ceil(\n"
  27967. "(64.0 * tmpvar_1.z)\n"
  27968. ")), 63);\n"
  27969. "vec2 finalCellPos_4;\n"
  27970. "ivec2 index2_5;\n"
  27971. "index2_5.x = (int(mod (tmpvar_2, 8)));\n"
  27972. "index2_5.y = (tmpvar_2 / 8);\n"
  27973. "vec2 tmpvar_6;\n"
  27974. "tmpvar_6 = (((vec2(0.125, 0.125) * tmpvar_1.xy) + (vec2(0.125, 0.125) * \n"
  27975. "vec2(index2_5)\n"
  27976. ")) + vec2(0.001, 0.001));\n"
  27977. "finalCellPos_4.x = tmpvar_6.x;\n"
  27978. "finalCellPos_4.y = (1.0 - tmpvar_6.y);\n"
  27979. "vec2 finalCellPos_7;\n"
  27980. "ivec2 index2_8;\n"
  27981. "index2_8.x = (int(mod (tmpvar_3, 8)));\n"
  27982. "index2_8.y = (tmpvar_3 / 8);\n"
  27983. "vec2 tmpvar_9;\n"
  27984. "tmpvar_9 = (((vec2(0.125, 0.125) * tmpvar_1.xy) + (vec2(0.125, 0.125) * \n"
  27985. "vec2(index2_8)\n"
  27986. ")) + vec2(0.001, 0.001));\n"
  27987. "finalCellPos_7.x = tmpvar_9.x;\n"
  27988. "finalCellPos_7.y = (1.0 - tmpvar_9.y);\n"
  27989. "a_color.xyz = mix (texture (u_lookup, finalCellPos_4).xyz, texture (u_lookup, finalCellPos_7).xyz, vec3(((64.0 * tmpvar_1.z) - float(tmpvar_2))));\n"
  27990. "a_color.w = 1.0;\n"
  27991. "}\n"},
  27992. std::pair<std::string, const char*>{"chromaticAberation.frag", "#version 150\n"
  27993. "out vec4 a_color;\n"
  27994. "noperspective in vec2 v_texCoords;\n"
  27995. "uniform sampler2D u_finalColorTexture;\n"
  27996. "uniform sampler2D u_DepthTexture;\n"
  27997. "uniform ivec2 u_windowSize;\n"
  27998. "uniform float u_strength;\n"
  27999. "uniform float u_near;\n"
  28000. "uniform float u_far;\n"
  28001. "uniform float u_unfocusDistance;\n"
  28002. "void main ()\n"
  28003. "{\n"
  28004. "vec3 finalColor_1;\n"
  28005. "vec2 fragC_2;\n"
  28006. "vec2 tmpvar_3;\n"
  28007. "vec2 tmpvar_4;\n"
  28008. "tmpvar_4 = vec2(u_windowSize);\n"
  28009. "tmpvar_3 = (u_strength / tmpvar_4);\n"
  28010. "fragC_2 = (gl_FragCoord.xy / tmpvar_4);\n"
  28011. "fragC_2 = (fragC_2 * 2.0);\n"
  28012. "fragC_2 = (fragC_2 - 1.0);\n"
  28013. "vec2 tmpvar_5;\n"
  28014. "tmpvar_5 = -(fragC_2);\n"
  28015. "vec2 tmpvar_6;\n"
  28016. "tmpvar_6 = (tmpvar_5 * tmpvar_3);\n"
  28017. "vec2 tmpvar_7;\n"
  28018. "tmpvar_7 = ((tmpvar_5 * tmpvar_3) * 0.5);\n"
  28019. "vec4 tmpvar_8;\n"
  28020. "tmpvar_8 = texture (u_DepthTexture, v_texCoords);\n"
  28021. "float tmpvar_9;\n"
  28022. "float tmpvar_10;\n"
  28023. "tmpvar_10 = (2.0 * u_near);\n"
  28024. "float tmpvar_11;\n"
  28025. "tmpvar_11 = (u_far - u_near);\n"
  28026. "float tmpvar_12;\n"
  28027. "tmpvar_12 = (u_far + u_near);\n"
  28028. "tmpvar_9 = ((tmpvar_10 * u_far) / (tmpvar_12 - (\n"
  28029. "((tmpvar_8.x * 2.0) - 1.0)\n"
  28030. "* tmpvar_11)));\n"
  28031. "float tmpvar_13;\n"
  28032. "tmpvar_13 = ((tmpvar_10 * u_far) / (tmpvar_12 - (\n"
  28033. "((tmpvar_8.x * 2.0) - 1.0)\n"
  28034. "* tmpvar_11)));\n"
  28035. "float tmpvar_14;\n"
  28036. "tmpvar_14 = ((tmpvar_10 * u_far) / (tmpvar_12 - (\n"
  28037. "((tmpvar_8.x * 2.0) - 1.0)\n"
  28038. "* tmpvar_11)));\n"
  28039. "if (((tmpvar_9 < u_unfocusDistance) && (tmpvar_14 < tmpvar_9))) {\n"
  28040. "finalColor_1.x = texture (u_finalColorTexture, v_texCoords).x;\n"
  28041. "} else {\n"
  28042. "finalColor_1.x = texture (u_finalColorTexture, (v_texCoords + tmpvar_6)).x;\n"
  28043. "};\n"
  28044. "if (((tmpvar_13 < u_unfocusDistance) && (tmpvar_14 < tmpvar_13))) {\n"
  28045. "finalColor_1.y = texture (u_finalColorTexture, v_texCoords).y;\n"
  28046. "} else {\n"
  28047. "finalColor_1.y = texture (u_finalColorTexture, (v_texCoords + tmpvar_7)).y;\n"
  28048. "};\n"
  28049. "finalColor_1.z = texture (u_finalColorTexture, v_texCoords).z;\n"
  28050. "vec4 tmpvar_15;\n"
  28051. "tmpvar_15.w = 1.0;\n"
  28052. "tmpvar_15.xyz = finalColor_1;\n"
  28053. "a_color = tmpvar_15;\n"
  28054. "}\n"},
  28055. std::pair<std::string, const char*>{"addMipsBlur.frag", "#version 150\n"
  28056. "out vec3 a_color;\n"
  28057. "noperspective in vec2 v_texCoords;\n"
  28058. "uniform sampler2D u_texture;\n"
  28059. "uniform int u_mip;\n"
  28060. "void main ()\n"
  28061. "{\n"
  28062. "vec2 tmpvar_1;\n"
  28063. "tmpvar_1 = (1.0/(vec2(textureSize (u_texture, u_mip))));\n"
  28064. "float tmpvar_2;\n"
  28065. "tmpvar_2 = float(u_mip);\n"
  28066. "a_color = textureLod (u_texture, (v_texCoords + (tmpvar_1 * vec2(-1.0, 1.0))), tmpvar_2).xyz;\n"
  28067. "a_color = (a_color + (textureLod (u_texture, (v_texCoords + \n"
  28068. "(tmpvar_1 * vec2(0.0, 1.0))\n"
  28069. "), tmpvar_2).xyz * 2.0));\n"
  28070. "a_color = (a_color + textureLod (u_texture, (v_texCoords + tmpvar_1), tmpvar_2).xyz);\n"
  28071. "a_color = (a_color + (textureLod (u_texture, (v_texCoords + \n"
  28072. "(tmpvar_1 * vec2(-1.0, 0.0))\n"
  28073. "), tmpvar_2).xyz * 2.0));\n"
  28074. "a_color = (a_color + (textureLod (u_texture, v_texCoords, tmpvar_2).xyz * 4.0));\n"
  28075. "a_color = (a_color + (textureLod (u_texture, (v_texCoords + \n"
  28076. "(tmpvar_1 * vec2(1.0, 0.0))\n"
  28077. "), tmpvar_2).xyz * 2.0));\n"
  28078. "a_color = (a_color + textureLod (u_texture, (v_texCoords - tmpvar_1), tmpvar_2).xyz);\n"
  28079. "a_color = (a_color + (textureLod (u_texture, (v_texCoords + \n"
  28080. "(tmpvar_1 * vec2(0.0, -1.0))\n"
  28081. "), tmpvar_2).xyz * 2.0));\n"
  28082. "a_color = (a_color + textureLod (u_texture, (v_texCoords + (tmpvar_1 * vec2(1.0, -1.0))), tmpvar_2).xyz);\n"
  28083. "a_color = (a_color / 16.0);\n"
  28084. "}\n"},
  28085. std::pair<std::string, const char*>{"addMips.frag", "#version 150\n"
  28086. "out vec3 a_color;\n"
  28087. "noperspective in vec2 v_texCoords;\n"
  28088. "uniform sampler2D u_texture;\n"
  28089. "uniform int u_mip;\n"
  28090. "void main ()\n"
  28091. "{\n"
  28092. "a_color = textureLod (u_texture, v_texCoords, float(u_mip)).xyz;\n"
  28093. "}\n"},
  28094. std::pair<std::string, const char*>{"mergePBRmat.frag", "#version 430 core\n"
  28095. "noperspective in vec2 v_texCoords;\n"
  28096. "out vec4 fragColor;\n"
  28097. "layout(binding = 0) uniform sampler2D u_roughness;\n"
  28098. "layout(binding = 1) uniform sampler2D u_metallic;\n"
  28099. "layout(binding = 2) uniform sampler2D u_ambient;\n"
  28100. "void main()\n"
  28101. "{\n"
  28102. "float metallic = texture(u_metallic, v_texCoords).r;\n"
  28103. "float roughness = texture(u_roughness, v_texCoords).r;\n"
  28104. "float ambient = texture(u_ambient, v_texCoords).r;\n"
  28105. "fragColor = vec4(roughness, metallic, ambient, 1);\n"
  28106. "}\n"},
  28107. std::pair<std::string, const char*>{"hbao.frag", "#version 330 core\n"
  28108. "out float fragColor;\n"
  28109. "noperspective in highp vec2 v_texCoords;\n"
  28110. "uniform sampler2D u_gPosition;\n"
  28111. "uniform isampler2D u_gNormal;\n"
  28112. "uniform sampler2D u_texNoise;\n"
  28113. "uniform mat4 u_projection; \n"
  28114. "uniform mat4 u_view; \n"
  28115. "const float INFINITY = 1.f/0.f;\n"
  28116. "vec3 fromuShortToFloat(ivec3 a)\n"
  28117. "{\n"
  28118. "vec3 ret = a;\n"
  28119. "ret /= 65536;\n"
  28120. "ret *= 2.f;\n"
  28121. "ret -= 1.f;\n"
  28122. "return normalize(ret);\n"
  28123. "}\n"
  28124. "float saturate(float a)\n"
  28125. "{\n"
  28126. "return min(max(a,0),1);\n"
  28127. "}\n"
  28128. "vec2 computeAO(vec3 normal, vec2 direction, vec2 screenSize, vec3 fragPos)\n"
  28129. "{\n"
  28130. "float RAD = 0.05;\n"
  28131. "float RAD_FOR_DIRECTION = length( direction*vec2(10.0) / (vec2(abs(fragPos.z))*screenSize));\n"
  28132. "vec3 viewVector = normalize(fragPos);\n"
  28133. "vec3 leftDirection = cross(viewVector, vec3(direction,0));\n"
  28134. "vec3 projectedNormal = normal - dot(leftDirection, normal) * leftDirection;\n"
  28135. "float projectedLen = length(projectedNormal);\n"
  28136. "projectedNormal /= projectedLen;\n"
  28137. "vec3 tangent = cross(projectedNormal, leftDirection);\n"
  28138. "const float bias = (3.141592/360)*20.f;\n"
  28139. "float tangentAngle = atan(tangent.z / length(tangent.xy));\n"
  28140. "float sinTangentAngle = sin(tangentAngle + bias);\n"
  28141. "vec2 texelSize = vec2(1.f,1.f) / screenSize;\n"
  28142. "float highestZ = -INFINITY;\n"
  28143. "vec3 foundPos = vec3(0,0,-INFINITY);\n"
  28144. "for(int i=2; i<=10; i++)\n"
  28145. "{\n"
  28146. "vec2 marchPosition = v_texCoords + i*texelSize*direction;\n"
  28147. "vec3 fragPosMarch = texture(u_gPosition, marchPosition).xyz;\n"
  28148. "vec3 hVector = normalize(fragPosMarch-fragPos); \n"
  28149. "float rangeCheck = 1 - saturate(length(fragPosMarch-fragPos) / RAD-1);\n"
  28150. "if(hVector.z > highestZ && length(fragPosMarch-fragPos) < RAD)\n"
  28151. "{\n"
  28152. "highestZ = hVector.z;\n"
  28153. "foundPos = fragPosMarch;\n"
  28154. "}\n"
  28155. "}\n"
  28156. "vec3 horizonVector = (foundPos - fragPos);\n"
  28157. "float horizonAngle = atan(horizonVector.z/length(horizonVector.xy));\n"
  28158. "float sinHorizonAngle = sin(horizonAngle); \n"
  28159. "vec2 rez = vec2(saturate((sinHorizonAngle - sinTangentAngle))/2, projectedLen);\n"
  28160. "return rez;\n"
  28161. "}\n"
  28162. "void main()\n"
  28163. "{\n"
  28164. "vec2 screenSize = textureSize(u_gPosition, 0).xy/2.f; \n"
  28165. "vec2 noiseScale = vec2(screenSize.x/4.0, screenSize.y/4.0);\n"
  28166. "vec2 noisePos = v_texCoords * noiseScale;\n"
  28167. "vec3 fragPos = texture(u_gPosition, v_texCoords).xyz; \n"
  28168. "if(fragPos.z == -INFINITY){fragColor = 1; return;}\n"
  28169. "vec3 normal = normalize( vec3( \n"
  28170. "transpose(inverse(mat3(u_view))) * \n"
  28171. "fromuShortToFloat(texture(u_gNormal, v_texCoords).xyz)\n"
  28172. "));\n"
  28173. "vec2 randomVec = vec2(0,1);\n"
  28174. "vec2 rez = vec2(0,0);\n"
  28175. "vec3 viewVector = normalize(fragPos);\n"
  28176. "rez += computeAO(normal, vec2(randomVec), screenSize, fragPos);\n"
  28177. "rez += computeAO(normal, -vec2(randomVec), screenSize, fragPos);\n"
  28178. "rez += computeAO(normal, vec2(-randomVec.y,randomVec.x), screenSize, fragPos);\n"
  28179. "rez += computeAO(normal, vec2(randomVec.y, -randomVec.x), screenSize, fragPos);\n"
  28180. "rez.x /= rez.y;\n"
  28181. "fragColor = 1.f - rez.x;\n"
  28182. "}\n"},
  28183. std::pair<std::string, const char*>{"zPrePass.vert", "#version 430\n"
  28184. "layout(location = 0) in vec3 a_positions;\n"
  28185. "layout(location = 2) in vec2 a_texCoord;\n"
  28186. "layout(location = 3) in ivec4 a_jointsId;\n"
  28187. "layout(location = 4) in vec4 a_weights;\n"
  28188. "uniform mat4 u_transform; \n"
  28189. "readonly restrict layout(std140) buffer u_jointTransforms\n"
  28190. "{\n"
  28191. "mat4 jointTransforms[];\n"
  28192. "};\n"
  28193. "uniform int u_hasAnimations;\n"
  28194. "out vec2 v_texCoord;\n"
  28195. "void main()\n"
  28196. "{\n"
  28197. "vec4 totalLocalPos = vec4(0.f);\n"
  28198. "if(u_hasAnimations != 0)\n"
  28199. "{\n"
  28200. "for(int i=0; i<4; i++)\n"
  28201. "{\n"
  28202. "if(a_jointsId[i] < 0){break;}\n"
  28203. "mat4 jointTransform = jointTransforms[a_jointsId[i]];\n"
  28204. "vec4 posePosition = jointTransform * vec4(a_positions, 1);\n"
  28205. "totalLocalPos += posePosition * a_weights[i];\n"
  28206. "}\n"
  28207. "}else\n"
  28208. "{\n"
  28209. "totalLocalPos = vec4(a_positions, 1.f);\n"
  28210. "}\n"
  28211. "gl_Position = u_transform * totalLocalPos;\n"
  28212. "v_texCoord = a_texCoord;\n"
  28213. "}\n"},
  28214. std::pair<std::string, const char*>{"zPrePass.frag", "#version 150\n"
  28215. "uniform sampler2D u_albedoSampler;\n"
  28216. "uniform int u_hasTexture;\n"
  28217. "in vec2 v_texCoord;\n"
  28218. "void main ()\n"
  28219. "{\n"
  28220. "if ((u_hasTexture != 0)) {\n"
  28221. "vec4 tmpvar_1;\n"
  28222. "tmpvar_1 = texture (u_albedoSampler, v_texCoord);\n"
  28223. "if (((tmpvar_1.w * 255.0) < 1.0)) {\n"
  28224. "discard;\n"
  28225. "};\n"
  28226. "};\n"
  28227. "}\n"},
  28228. std::pair<std::string, const char*>{"lightingPass.frag", "#version 430 core\n"
  28229. "#extension GL_ARB_bindless_texture: require\n"
  28230. "layout(location = 0) out vec4 a_outColor;\n"
  28231. "layout(location = 1) out vec4 a_outBloom;\n"
  28232. "noperspective in vec2 v_texCoords;\n"
  28233. "uniform isampler2D u_normals;\n"
  28234. "uniform samplerCube u_skyboxFiltered;\n"
  28235. "uniform samplerCube u_skyboxIradiance;\n"
  28236. "uniform sampler2D u_brdfTexture;\n"
  28237. "uniform sampler2DArrayShadow u_cascades;\n"
  28238. "uniform sampler2DArrayShadow u_spotShadows;\n"
  28239. "uniform samplerCubeArrayShadow u_pointShadows;\n"
  28240. "uniform isampler2D u_materialIndex;\n"
  28241. "uniform sampler2D u_textureUV;\n"
  28242. "uniform sampler2D u_lastFrameTexture;\n"
  28243. "uniform sampler2D u_positionViewSpace;\n"
  28244. "uniform isampler2D u_textureDerivates;\n"
  28245. "uniform int u_hasLastFrameTexture;\n"
  28246. "uniform mat4 u_cameraProjection;\n"
  28247. "uniform mat4 u_view;\n"
  28248. "uniform mat4 u_inverseView;\n"
  28249. "uniform vec3 u_eyePosition;\n"
  28250. "uniform int u_transparentPass;\n"
  28251. "struct MaterialStruct\n"
  28252. "{\n"
  28253. "vec4 kd;\n"
  28254. "vec4 rma; \n"
  28255. "uvec4 firstBIndlessSamplers; \n"
  28256. "uvec2 secondBIndlessSamplers; \n"
  28257. "int rmaLoaded;\n"
  28258. "int notUsed;\n"
  28259. "};\n"
  28260. "readonly layout(std140) buffer u_material\n"
  28261. "{\n"
  28262. "MaterialStruct mat[];\n"
  28263. "};\n"
  28264. "layout (std140) uniform u_lightPassData\n"
  28265. "{\n"
  28266. "vec4 ambientColor;\n"
  28267. "float bloomTresshold;\n"
  28268. "int lightSubScater;\n"
  28269. "float exposure;\n"
  28270. "int skyBoxPresent;\n"
  28271. "float SSR_minRayStep;\n"
  28272. "int SSR_maxSteps;\n"
  28273. "int SSR_numBinarySearchSteps;\n"
  28274. "float SSR_maxRayStep;\n"
  28275. "float SSR_maxRayDelta;\n"
  28276. "}lightPassData;\n"
  28277. "struct PointLight\n"
  28278. "{\n"
  28279. "vec3 positions; \n"
  28280. "float dist;\n"
  28281. "vec3 color;\n"
  28282. "float attenuation;\n"
  28283. "int castShadowsIndex;\n"
  28284. "float hardness;\n"
  28285. "int castShadows;\n"
  28286. "int changedThisFrame;\n"
  28287. "};\n"
  28288. "readonly restrict layout(std140) buffer u_pointLights\n"
  28289. "{\n"
  28290. "PointLight light[];\n"
  28291. "};\n"
  28292. "uniform int u_pointLightCount;\n"
  28293. "struct DirectionalLight\n"
  28294. "{\n"
  28295. "vec3 direction; \n"
  28296. "int castShadowsIndex;\n"
  28297. "int changedThisFrame; \n"
  28298. "int castShadows;\n"
  28299. "int notUsed1;\n"
  28300. "int notUsed2;\n"
  28301. "vec4 color; \n"
  28302. "mat4 firstLightSpaceMatrix;\n"
  28303. "mat4 secondLightSpaceMatrix;\n"
  28304. "mat4 thirdLightSpaceMatrix;\n"
  28305. "};\n"
  28306. "readonly restrict layout(std140) buffer u_directionalLights\n"
  28307. "{\n"
  28308. "DirectionalLight dLight[];\n"
  28309. "};\n"
  28310. "uniform int u_directionalLightCount;\n"
  28311. "struct SpotLight\n"
  28312. "{\n"
  28313. "vec4 position; \n"
  28314. "vec4 direction; \n"
  28315. "vec4 color; \n"
  28316. "float hardness;\n"
  28317. "int shadowIndex;\n"
  28318. "int castShadows; \n"
  28319. "int changedThisFrame; \n"
  28320. "float near;\n"
  28321. "float far;\n"
  28322. "float notUsed1;\n"
  28323. "float notUsed2;\n"
  28324. "mat4 lightSpaceMatrix;\n"
  28325. "};\n"
  28326. "readonly restrict layout(std140) buffer u_spotLights\n"
  28327. "{\n"
  28328. "SpotLight spotLights[];\n"
  28329. "};\n"
  28330. "uniform int u_spotLightCount;\n"
  28331. "const float PI = 3.14159265359;\n"
  28332. "const float randomNumbers[100] = float[100](\n"
  28333. "0.05535, 0.22262, 0.93768, 0.80063, 0.40089, 0.49459, 0.44997, 0.27060, 0.58789, 0.61765,\n"
  28334. "0.87949, 0.38913, 0.23154, 0.27249, 0.93448, 0.71567, 0.26940, 0.32226, 0.73918, 0.30905,\n"
  28335. "0.98754, 0.82585, 0.84031, 0.60059, 0.56027, 0.10819, 0.55848, 0.95612, 0.88034, 0.94950,\n"
  28336. "0.53892, 0.86421, 0.84131, 0.39158, 0.25861, 0.10192, 0.19673, 0.25165, 0.68675, 0.79157,\n"
  28337. "0.94730, 0.36948, 0.27978, 0.66377, 0.38935, 0.93795, 0.83168, 0.01452, 0.51242, 0.12272,\n"
  28338. "0.61045, 0.34752, 0.13781, 0.92361, 0.73422, 0.31213, 0.55513, 0.81074, 0.56166, 0.31797,\n"
  28339. "0.09507, 0.50049, 0.44248, 0.38244, 0.58468, 0.32327, 0.61830, 0.67908, 0.16011, 0.82861,\n"
  28340. "0.36502, 0.12052, 0.28872, 0.73448, 0.51443, 0.99355, 0.75244, 0.22432, 0.95501, 0.90914,\n"
  28341. "0.37992, 0.61330, 0.49202, 0.69464, 0.14831, 0.51697, 0.34620, 0.55315, 0.41602, 0.49807,\n"
  28342. "0.15133, 0.07372, 0.75259, 0.59642, 0.35652, 0.60051, 0.08879, 0.59271, 0.29388, 0.69505\n"
  28343. ");\n"
  28344. "const float INFINITY = 1.f/0.f;\n"
  28345. "float attenuationFunctionNotClamped(float x, float r, float p)\n"
  28346. "{\n"
  28347. "float p4 = p*p*p*p;\n"
  28348. "float power = pow(x/r, p4);\n"
  28349. "float rez = (1-power);\n"
  28350. "rez = rez * rez;\n"
  28351. "return rez;\n"
  28352. "}\n"
  28353. "float DistributionGGX(vec3 N, vec3 H, float roughness)\n"
  28354. "{\n"
  28355. "float a = roughness*roughness;\n"
  28356. "float a2 = a*a;\n"
  28357. "float NdotH = max(dot(N, H), 0.0);\n"
  28358. "float NdotH2 = NdotH*NdotH;\n"
  28359. "float denom = (NdotH2 * (a2 - 1.0) + 1.0);\n"
  28360. "denom = PI * denom * denom;\n"
  28361. "return a2 / max(denom, 0.0000001);\n"
  28362. "}\n"
  28363. "float GeometrySchlickGGX(float NdotV, float roughness)\n"
  28364. "{\n"
  28365. "float k = roughness*roughness / 2;\n"
  28366. "float num = NdotV;\n"
  28367. "float denom = NdotV * (1.0 - k) + k;\n"
  28368. "return num / max(denom, 0.0000001);\n"
  28369. "}\n"
  28370. "float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)\n"
  28371. "{\n"
  28372. "float NdotV = max(dot(N, V), 0.0);\n"
  28373. "float NdotL = max(dot(N, L), 0.0);\n"
  28374. "float ggx2 = GeometrySchlickGGX(NdotV, roughness);\n"
  28375. "float ggx1 = GeometrySchlickGGX(NdotL, roughness);\n"
  28376. "return ggx1 * ggx2;\n"
  28377. "}\n"
  28378. "vec3 fresnelSchlick(float cosTheta, vec3 F0)\n"
  28379. "{\n"
  28380. "return F0 + (1.0 - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);\n"
  28381. "}\n"
  28382. "vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)\n"
  28383. "{\n"
  28384. "return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);\n"
  28385. "} \n"
  28386. "vec3 fSpecular(vec3 normal, vec3 halfwayVec, vec3 viewDir, \n"
  28387. "vec3 lightDirection, float dotNVclamped, float roughness, vec3 F)\n"
  28388. "{\n"
  28389. "float NDF = DistributionGGX(normal, halfwayVec, roughness); \n"
  28390. "float G = GeometrySmith(normal, viewDir, lightDirection, roughness); \n"
  28391. "float denominator = 4.0 * dotNVclamped \n"
  28392. "* max(dot(normal, lightDirection), 0.0);\n"
  28393. "vec3 specular = (NDF * G * F) / max(denominator, 0.001);\n"
  28394. "return specular;\n"
  28395. "}\n"
  28396. "vec3 fDiffuse(vec3 color)\n"
  28397. "{\n"
  28398. "return color.rgb / PI;\n"
  28399. "}\n"
  28400. "vec3 fDiffuseOrenNayar(vec3 color, float roughness, vec3 L, vec3 V, vec3 N)\n"
  28401. "{\n"
  28402. "float a = roughness;\n"
  28403. "float a2 = a*a;\n"
  28404. "float cosi = max(dot(L, N), 0);\n"
  28405. "float cosr = max(dot(V, N), 0);\n"
  28406. "float sini = sqrt(1-cosi*cosi);\n"
  28407. "float sinr = sqrt(1-cosr*cosr);\n"
  28408. "float tani = sini/cosi;\n"
  28409. "float tanr = sinr/cosr;\n"
  28410. "float A = 1 - 0.5 * a2/(a2 + 0.33);\n"
  28411. "float B = 0.45*a2/(a2+0.09);\n"
  28412. "float sinAlpha = max(sini, sinr);\n"
  28413. "float tanBeta = min(tani, tanr);\n"
  28414. "return color.rgb * (A + (B* max(0, dot(L,reflect(V,N))) * sinAlpha * tanBeta )) / PI;\n"
  28415. "}\n"
  28416. "vec3 fDiffuseOrenNayar2(vec3 color, float roughness, vec3 L, vec3 V, vec3 N)\n"
  28417. "{\n"
  28418. "float a = roughness;\n"
  28419. "float a2 = a*a;\n"
  28420. "float A = 1.0/(PI+(PI/2.0-2/3.0)*a);\n"
  28421. "float B = PI/(PI+(PI/2.0-2/3.0)*a);\n"
  28422. "float s = dot(L,N) - dot(N,L)*dot(N,V);\n"
  28423. "float t;\n"
  28424. "if(s <= 0)\n"
  28425. "t = 1;\n"
  28426. "else\n"
  28427. "t = max(dot(N,L), dot(N,V));\n"
  28428. "return color * (A + B * s/t);\n"
  28429. "}\n"
  28430. "vec3 computePointLightSource(vec3 lightDirection, float metallic, float roughness, in vec3 lightColor, in vec3 worldPosition,\n"
  28431. "in vec3 viewDir, in vec3 color, in vec3 normal, in vec3 F0)\n"
  28432. "{\n"
  28433. "float dotNVclamped = clamp(dot(normal, viewDir), 0.0, 0.99);\n"
  28434. "vec3 halfwayVec = normalize(lightDirection + viewDir);\n"
  28435. "vec3 radiance = lightColor; \n"
  28436. "vec3 F = fresnelSchlick(max(dot(halfwayVec, viewDir), 0.0), F0);\n"
  28437. "vec3 specular = fSpecular(normal, halfwayVec, viewDir, lightDirection, dotNVclamped, roughness, F);\n"
  28438. "vec3 kS = F; \n"
  28439. "vec3 kD = vec3(1.0) - kS; \n"
  28440. "kD *= 1.0 - metallic; \n"
  28441. "vec3 diffuse = fDiffuseOrenNayar2(color.rgb, roughness, lightDirection, viewDir, normal);\n"
  28442. "float NdotL = max(dot(normal, lightDirection), 0.0); \n"
  28443. "return (kD * diffuse + specular) * radiance * NdotL;\n"
  28444. "}\n"
  28445. "float testShadowValue(sampler2DArrayShadow map, vec2 coords, float currentDepth, float bias, int index)\n"
  28446. "{\n"
  28447. "return texture(map, vec4(coords, index, currentDepth-bias)).r;\n"
  28448. "}\n"
  28449. "void sincos(float a, out float s, out float c)\n"
  28450. "{\n"
  28451. "s = sin(a);\n"
  28452. "c = cos(a);\n"
  28453. "}\n"
  28454. "vec2 vogelDiskSample(int sampleIndex, int samplesCount, float phi)\n"
  28455. "{\n"
  28456. "float GoldenAngle = 2.4f;\n"
  28457. "float r = sqrt(sampleIndex + 0.5f) / sqrt(samplesCount);\n"
  28458. "float theta = sampleIndex * GoldenAngle + phi;\n"
  28459. "float sine, cosine;\n"
  28460. "sincos(theta, sine, cosine);\n"
  28461. "return vec2(r * cosine, r * sine);\n"
  28462. "}\n"
  28463. "float InterleavedGradientNoise(vec2 position_screen)\n"
  28464. "{\n"
  28465. "vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);\n"
  28466. "return fract(magic.z * fract(dot(position_screen, magic.xy)));\n"
  28467. "}\n"
  28468. "float shadowCalculation(vec3 projCoords, float bias, sampler2DArrayShadow shadowMap, int index)\n"
  28469. "{\n"
  28470. "if(projCoords.z > 0.99995)\n"
  28471. "return 1.f;\n"
  28472. "float currentDepth = projCoords.z;\n"
  28473. "vec2 texelSize = 1.0 / textureSize(shadowMap, 0).xy;\n"
  28474. "float shadow = 0.0;\n"
  28475. "bool fewSamples = false;\n"
  28476. "int kernelHalf = 1;\n"
  28477. "int kernelSize = kernelHalf*2 + 1;\n"
  28478. "int kernelSize2 = kernelSize*kernelSize;\n"
  28479. "float penumbraSize = 1.f;\n"
  28480. "if(false)\n"
  28481. "{\n"
  28482. "float shadowValueAtCentre = 0;\n"
  28483. "if(false)\n"
  28484. "{\n"
  28485. "float offsetSize = kernelSize/2;\n"
  28486. "const int OFFSETS = 4;\n"
  28487. "vec2 offsets[OFFSETS] = \n"
  28488. "{\n"
  28489. "vec2(offsetSize,offsetSize),\n"
  28490. "vec2(-offsetSize,offsetSize),\n"
  28491. "vec2(offsetSize,-offsetSize),\n"
  28492. "vec2(-offsetSize,-offsetSize),\n"
  28493. "};\n"
  28494. "fewSamples = true;\n"
  28495. "float s1 = testShadowValue(shadowMap, projCoords.xy, \n"
  28496. "currentDepth, bias, index); \n"
  28497. "shadowValueAtCentre = s1;\n"
  28498. "for(int i=0;i<OFFSETS; i++)\n"
  28499. "{\n"
  28500. "float s2 = testShadowValue(shadowMap, projCoords.xy + offsets[i] * texelSize * 2, \n"
  28501. "currentDepth, bias, index); \n"
  28502. "if(s1 != s2)\n"
  28503. "{\n"
  28504. "fewSamples = false;\n"
  28505. "break;\n"
  28506. "} \n"
  28507. "s1 = s2;\n"
  28508. "}\n"
  28509. "}\n"
  28510. "if(fewSamples)\n"
  28511. "{\n"
  28512. "shadow = shadowValueAtCentre;\n"
  28513. "}else\n"
  28514. "{\n"
  28515. "for(int y = -kernelHalf; y <= kernelHalf; ++y)\n"
  28516. "{\n"
  28517. "for(int x = -kernelHalf; x <= kernelHalf; ++x)\n"
  28518. "{\n"
  28519. "vec2 offset = vec2(x, y);\n"
  28520. "if(false)\n"
  28521. "{\n"
  28522. "int randomOffset1 = (x*kernelSize) + y;\n"
  28523. "int randomOffset2 = randomOffset1 + kernelSize2;\n"
  28524. "offset += vec2(randomNumbers[randomOffset1, randomOffset2]);\n"
  28525. "}\n"
  28526. "if(false)\n"
  28527. "{\n"
  28528. "float u = (offset.x + kernelHalf)/float(kernelSize-1);\n"
  28529. "float v = (offset.y + kernelHalf)/float(kernelSize-1);\n"
  28530. "offset.x = sqrt(v) * cos(2*PI * u)* kernelHalf;\n"
  28531. "offset.y = sqrt(v) * sin(2*PI * u)* kernelHalf;\n"
  28532. "}\n"
  28533. "vec2 finalOffset = offset * texelSize * penumbraSize;\n"
  28534. "float s = testShadowValue(shadowMap, projCoords.xy + finalOffset, \n"
  28535. "currentDepth, bias, index); \n"
  28536. "shadow += s;\n"
  28537. "} \n"
  28538. "}\n"
  28539. "shadow /= kernelSize2;\n"
  28540. "}\n"
  28541. "}else\n"
  28542. "{\n"
  28543. "int sampleSize = 9;\n"
  28544. "int checkSampleSize = 5;\n"
  28545. "float size = 1.5;\n"
  28546. "float noise = InterleavedGradientNoise(v_texCoords) * 2 * PI;\n"
  28547. "for(int i=sampleSize-1; i>=sampleSize-checkSampleSize; i--)\n"
  28548. "{\n"
  28549. "vec2 offset = vogelDiskSample(i, sampleSize, noise);\n"
  28550. "vec2 finalOffset = offset * texelSize * size;\n"
  28551. "float s = testShadowValue(shadowMap, projCoords.xy + finalOffset, \n"
  28552. "currentDepth, bias, index);\n"
  28553. "shadow += s;\n"
  28554. "}\n"
  28555. "if(true && (shadow == 0 || shadow == checkSampleSize))\n"
  28556. "{\n"
  28557. "shadow /= checkSampleSize;\n"
  28558. "}else\n"
  28559. "{\n"
  28560. "for(int i=sampleSize-checkSampleSize-1; i>=0; i--)\n"
  28561. "{\n"
  28562. "vec2 offset = vogelDiskSample(i, sampleSize, noise);\n"
  28563. "vec2 finalOffset = offset * texelSize * size;\n"
  28564. "float s = testShadowValue(shadowMap, projCoords.xy + finalOffset, \n"
  28565. "currentDepth, bias, index);\n"
  28566. "shadow += s;\n"
  28567. "}\n"
  28568. "shadow /= sampleSize;\n"
  28569. "}\n"
  28570. "}\n"
  28571. "return clamp(shadow, 0, 1);\n"
  28572. "}\n"
  28573. "float shadowCalculationLinear(vec3 projCoords, vec3 normal, vec3 lightDir, sampler2DArrayShadow shadowMap, int index)\n"
  28574. "{\n"
  28575. "float bias = max((10.f/1024.f) * (1.0 - dot(normal, -lightDir)), 3.f/1024.f);\n"
  28576. "return shadowCalculation(projCoords, bias, shadowMap, index);\n"
  28577. "}\n"
  28578. "float linearizeDepth(float depth, float near, float far)\n"
  28579. "{\n"
  28580. "float z = depth * 2.0 - 1.0; \n"
  28581. "return (2.0 * near * far) / (far + near - z * (far - near));\n"
  28582. "}\n"
  28583. "float nonLinearDepth(float depth, float near, float far)\n"
  28584. "{\n"
  28585. "return ((1.f/depth) - (1.f/near)) / ((1.f/far) - (1.f/near));\n"
  28586. "}\n"
  28587. "float shadowCalculationLogaritmic(vec3 projCoords, vec3 normal, vec3 lightDir,\n"
  28588. "sampler2DArrayShadow shadowMap, int index, float near, float far)\n"
  28589. "{\n"
  28590. "float bias = max((0.01f) * (1.0 - dot(normal, -lightDir)), 0.001f);\n"
  28591. "float currentDepth = projCoords.z;\n"
  28592. "float liniarizedDepth = linearizeDepth(currentDepth, near, far);\n"
  28593. "liniarizedDepth += bias;\n"
  28594. "float biasedLogDepth = nonLinearDepth(liniarizedDepth, near, far);\n"
  28595. "bias = biasedLogDepth - currentDepth;\n"
  28596. "bias += 0.00003f;\n"
  28597. "return shadowCalculation(projCoords, bias, shadowMap, index);\n"
  28598. "}\n"
  28599. "vec3 getProjCoords(in mat4 matrix, in vec3 pos)\n"
  28600. "{\n"
  28601. "vec4 p = matrix * vec4(pos,1);\n"
  28602. "vec3 r = p .xyz / p .w;\n"
  28603. "r = r * 0.5 + 0.5;\n"
  28604. "return r;\n"
  28605. "}\n"
  28606. "void generateTangentSpace(in vec3 v, out vec3 outUp, out vec3 outRight)\n"
  28607. "{\n"
  28608. "vec3 up = vec3(0.f, 1.f, 0.f);\n"
  28609. "if (v == up)\n"
  28610. "{\n"
  28611. "outRight = vec3(1, 0, 0);\n"
  28612. "}\n"
  28613. "else\n"
  28614. "{\n"
  28615. "outRight = normalize(cross(v, up));\n"
  28616. "}\n"
  28617. "outUp = normalize(cross(outRight, v));\n"
  28618. "}\n"
  28619. "float pointShadowCalculation(vec3 pos, vec3 normal, int index)\n"
  28620. "{ \n"
  28621. "vec3 fragToLight = pos - light[index].positions; \n"
  28622. "vec3 lightDir = normalize(fragToLight);\n"
  28623. "float bias = max((60.f/512.f) * (1.0 - dot(normal, -lightDir)), 35.f/512.f);\n"
  28624. "float shadow = 0.0;\n"
  28625. "vec3 tangent;\n"
  28626. "vec3 coTangent;\n"
  28627. "generateTangentSpace(lightDir, tangent, coTangent);\n"
  28628. "float texel = 1.f / textureSize(u_pointShadows, 0).x;\n"
  28629. "int kernel = 5;\n"
  28630. "int kernelHalf = kernel/2;\n"
  28631. "for(int y = -kernelHalf; y<=kernelHalf; y++)\n"
  28632. "{\n"
  28633. "for(int x = -kernelHalf; x<=kernelHalf; x++)\n"
  28634. "{\n"
  28635. "vec3 fragToLight = pos - light[index].positions; \n"
  28636. "fragToLight += 6*x * texel * tangent;\n"
  28637. "fragToLight += 6*y * texel * coTangent;\n"
  28638. "float currentDepth = length(fragToLight); \n"
  28639. "float value = texture(u_pointShadows, \n"
  28640. "vec4(fragToLight, light[index].castShadowsIndex),\n"
  28641. "(currentDepth-bias)/light[index].dist ).r; \n"
  28642. "shadow += value;\n"
  28643. "}\n"
  28644. "}\n"
  28645. "if(shadow <3)\n"
  28646. "{\n"
  28647. "shadow = 0;\n"
  28648. "}\n"
  28649. "shadow /= (kernel * kernel);\n"
  28650. "shadow = clamp(shadow, 0, 1);\n"
  28651. "return shadow;\n"
  28652. "}\n"
  28653. "float cascadedShadowCalculation(vec3 pos, vec3 normal, vec3 lightDir, int index)\n"
  28654. "{\n"
  28655. "vec3 firstProjCoords = getProjCoords(dLight[index].firstLightSpaceMatrix, pos);\n"
  28656. "vec3 secondProjCoords = getProjCoords(dLight[index].secondLightSpaceMatrix, pos);\n"
  28657. "vec3 thirdProjCoords = getProjCoords(dLight[index].thirdLightSpaceMatrix, pos);\n"
  28658. "if(\n"
  28659. "firstProjCoords.x < 0.98 &&\n"
  28660. "firstProjCoords.x > 0.01 &&\n"
  28661. "firstProjCoords.y < 0.98 &&\n"
  28662. "firstProjCoords.y > 0.01 &&\n"
  28663. "firstProjCoords.z < 0.98 &&\n"
  28664. "firstProjCoords.z > 0\n"
  28665. ")\n"
  28666. "{\n"
  28667. "firstProjCoords.y /= 3.f;\n"
  28668. "return shadowCalculationLinear(firstProjCoords, normal, lightDir, u_cascades, index);\n"
  28669. "}else \n"
  28670. "if(\n"
  28671. "secondProjCoords.x > 0 &&\n"
  28672. "secondProjCoords.x < 1 &&\n"
  28673. "secondProjCoords.y > 0 &&\n"
  28674. "secondProjCoords.y < 1 &&\n"
  28675. "secondProjCoords.z < 0.98\n"
  28676. ")\n"
  28677. "{\n"
  28678. "secondProjCoords.y /= 3.f;\n"
  28679. "secondProjCoords.y += 1.f / 3.f;\n"
  28680. "return shadowCalculationLinear(secondProjCoords, normal, lightDir, u_cascades, index);\n"
  28681. "}\n"
  28682. "else\n"
  28683. "{\n"
  28684. "thirdProjCoords.y /= 3.f;\n"
  28685. "thirdProjCoords.y += 2.f / 3.f;\n"
  28686. "return shadowCalculationLinear(thirdProjCoords, normal, lightDir, u_cascades, index);\n"
  28687. "}\n"
  28688. "}\n"
  28689. "vec4 fromuShortToFloat2(ivec4 a)\n"
  28690. "{\n"
  28691. "vec4 ret = a;\n"
  28692. "ret /= 65536;\n"
  28693. "ret *= 4.f;\n"
  28694. "ret -= 2.f;\n"
  28695. "return ret;\n"
  28696. "}\n"
  28697. "vec3 fromuShortToFloat(ivec3 a)\n"
  28698. "{\n"
  28699. "vec3 ret = a;\n"
  28700. "ret /= 65536;\n"
  28701. "ret *= 2.f;\n"
  28702. "ret -= 1.f;\n"
  28703. "return normalize(ret);\n"
  28704. "}\n"
  28705. "vec2 BinarySearch(inout vec3 dir, inout vec3 hitCoord, \n"
  28706. "inout float dDepth, vec2 oldValue)\n"
  28707. "{\n"
  28708. "float depth;\n"
  28709. "vec4 projectedCoord;\n"
  28710. "vec2 foundProjectedCoord = oldValue;\n"
  28711. "for(int i = 0; i < lightPassData.SSR_numBinarySearchSteps; i++)\n"
  28712. "{\n"
  28713. "projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);\n"
  28714. "projectedCoord.xy /= projectedCoord.w;\n"
  28715. "projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;\n"
  28716. "depth = texture(u_positionViewSpace, projectedCoord.xy).z;\n"
  28717. "if(depth < -1000) \n"
  28718. "continue;\n"
  28719. "foundProjectedCoord = projectedCoord.xy;\n"
  28720. "dDepth = hitCoord.z - depth;\n"
  28721. "dir *= 0.5;\n"
  28722. "if(dDepth > 0.0)\n"
  28723. "hitCoord += dir;\n"
  28724. "else\n"
  28725. "hitCoord -= dir; \n"
  28726. "}\n"
  28727. "projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);\n"
  28728. "projectedCoord.xy /= projectedCoord.w;\n"
  28729. "projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;\n"
  28730. "depth = texture(u_positionViewSpace, projectedCoord.xy).z;\n"
  28731. "if(!(depth < -1000))\n"
  28732. "{\n"
  28733. "foundProjectedCoord = projectedCoord.xy;\n"
  28734. "}\n"
  28735. "return foundProjectedCoord.xy;\n"
  28736. "}\n"
  28737. "vec2 RayMarch(vec3 dir, inout vec3 hitCoord, out float dDepth, vec3 worldNormal, vec3 viewDir)\n"
  28738. "{\n"
  28739. "dir *= mix(lightPassData.SSR_minRayStep, lightPassData.SSR_maxRayStep, abs(dot(worldNormal, viewDir)));\n"
  28740. "float depth;\n"
  28741. "vec4 projectedCoord;\n"
  28742. "for(int i = 0; i < lightPassData.SSR_maxSteps; i++)\n"
  28743. "{\n"
  28744. "hitCoord += dir;\n"
  28745. "projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);\n"
  28746. "projectedCoord.xy /= projectedCoord.w;\n"
  28747. "projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;\n"
  28748. "if(projectedCoord.x > 1.f || projectedCoord.y > 1.f\n"
  28749. "||projectedCoord.x < -1.f || projectedCoord.y < -1.f\n"
  28750. ")\n"
  28751. "{\n"
  28752. "break;\n"
  28753. "}\n"
  28754. "depth = texture(u_positionViewSpace, projectedCoord.xy).z;\n"
  28755. "if(depth > 1000.0)\n"
  28756. "continue;\n"
  28757. "if(depth < -1000) \n"
  28758. "continue;\n"
  28759. "dDepth = hitCoord.z - depth;\n"
  28760. "if((dir.z - dDepth) < lightPassData.SSR_maxRayStep && dDepth <= 0.0)\n"
  28761. "{\n"
  28762. "vec2 Result;\n"
  28763. "Result = BinarySearch(dir, hitCoord, dDepth, projectedCoord.xy);\n"
  28764. "if(dDepth < -lightPassData.SSR_maxRayDelta)\n"
  28765. "{\n"
  28766. "break; \n"
  28767. "}\n"
  28768. "depth = texture(u_positionViewSpace, Result.xy).z;\n"
  28769. "if(depth < -10000)\n"
  28770. "{break;}\n"
  28771. "return Result;\n"
  28772. "}\n"
  28773. "}\n"
  28774. "dDepth = -INFINITY;\n"
  28775. "return vec2(0,0);\n"
  28776. "}\n"
  28777. "uvec3 murmurHash33(uvec3 src) {\n"
  28778. "const uint M = 0x5bd1e995u;\n"
  28779. "uvec3 h = uvec3(1190494759u, 2147483647u, 3559788179u);\n"
  28780. "src *= M; src ^= src>>24u; src *= M;\n"
  28781. "h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;\n"
  28782. "h ^= h>>13u; h *= M; h ^= h>>15u;\n"
  28783. "return h;\n"
  28784. "}\n"
  28785. "vec3 hash33(vec3 src) {\n"
  28786. "uvec3 h = murmurHash33(floatBitsToUint(src));\n"
  28787. "return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;\n"
  28788. "}\n"
  28789. "vec3 computeJitt(vec3 wp, vec2 Resolution, vec3 viewNormal, float Roughness)\n"
  28790. "{\n"
  28791. "vec2 NoiseScale = Resolution / 4.0;\n"
  28792. "vec3 random = hash33(wp);\n"
  28793. "random = dot(random, viewNormal) > 0.0 ? random : -random;\n"
  28794. "float factor = Roughness*0.20;\n"
  28795. "vec3 hs = random * 2.0 - 1.0;\n"
  28796. "vec3 jitt = hs * factor;\n"
  28797. "return vec3(jitt);\n"
  28798. "}\n"
  28799. "vec3 SSR(vec3 viewPos, vec3 N, float metallic, vec3 F, \n"
  28800. "out float mixFactor, float roughness, vec3 wp, vec3 viewDir, vec3 viewSpaceNormal, vec2 rezolution)\n"
  28801. "{\n"
  28802. "mixFactor = 0;\n"
  28803. "vec3 reflected = normalize(reflect(normalize(viewPos), viewSpaceNormal));\n"
  28804. "if(reflected.z > 0){return vec3(0,0,0);}\n"
  28805. "vec3 hitPos = viewPos;\n"
  28806. "float dDepth;\n"
  28807. "vec3 jitt = computeJitt(wp, rezolution, viewSpaceNormal, roughness); \n"
  28808. "vec2 coords = RayMarch( normalize((vec3(jitt) + reflected) *\n"
  28809. "max(lightPassData.SSR_minRayStep, -viewPos.z)), hitPos, dDepth,\n"
  28810. "N, viewDir);\n"
  28811. "if(dDepth < -1000){return vec3(0);}\n"
  28812. "vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5, 0.5) - coords.xy));\n"
  28813. "float screenEdgefactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);\n"
  28814. "float ReflectionMultiplier = \n"
  28815. "screenEdgefactor * \n"
  28816. "-reflected.z;\n"
  28817. "if(ReflectionMultiplier <= 0.001)\n"
  28818. "{\n"
  28819. "return vec3(0.f);\n"
  28820. "}\n"
  28821. "vec3 lastFrameColor = textureLod(u_lastFrameTexture, coords.xy, 0).rgb;\n"
  28822. "vec3 SSR = lastFrameColor;\n"
  28823. "mixFactor = clamp(ReflectionMultiplier, 0.0, 1.f); \n"
  28824. "return SSR;\n"
  28825. "}\n"
  28826. "vec3 computeAmbientTerm(vec3 N, vec3 V, vec3 F0, float roughness, vec3 R, \n"
  28827. "float metallic, vec3 albedo, vec3 wp, vec3 viewPos, vec3 viewSpaceNormal, vec2 rezolution)\n"
  28828. "{\n"
  28829. "vec3 gammaAmbient = pow(lightPassData.ambientColor.rgb, vec3(2.2)); \n"
  28830. "vec3 ambient = vec3(0);\n"
  28831. "float dotNVClamped = clamp(dot(N, V), 0.0, 0.99);\n"
  28832. "vec3 F = fresnelSchlickRoughness(dotNVClamped, F0, roughness);\n"
  28833. "vec3 kS = F;\n"
  28834. "vec3 irradiance = vec3(0,0,0); \n"
  28835. "vec3 radiance = vec3(0,0,0); \n"
  28836. "vec2 brdf = vec2(0,0);\n"
  28837. "vec2 brdfVec = vec2(dotNVClamped, roughness);\n"
  28838. "float mixFactor = 0;\n"
  28839. "if(u_hasLastFrameTexture != 0) \n"
  28840. "{\n"
  28841. "radiance = SSR(viewPos, N, metallic, F, mixFactor, roughness, wp, V, viewSpaceNormal, rezolution);\n"
  28842. "}\n"
  28843. "if(lightPassData.skyBoxPresent != 0)\n"
  28844. "{\n"
  28845. "irradiance = texture(u_skyboxIradiance, N).rgb * gammaAmbient; \n"
  28846. "const float MAX_REFLECTION_LOD = 4.0;\n"
  28847. "if(mixFactor < 0.999)\n"
  28848. "{\n"
  28849. "radiance = mix(textureLod(u_skyboxFiltered, R, roughness * MAX_REFLECTION_LOD).rgb * gammaAmbient, radiance, mixFactor);\n"
  28850. "}\n"
  28851. "brdf = texture(u_brdfTexture, brdfVec).rg;\n"
  28852. "}else\n"
  28853. "{\n"
  28854. "radiance = mix(gammaAmbient, radiance, mixFactor);\n"
  28855. "irradiance = gammaAmbient ; \n"
  28856. "brdf = texture(u_brdfTexture, brdfVec).rg;\n"
  28857. "}\n"
  28858. "if(lightPassData.lightSubScater == 0)\n"
  28859. "{\n"
  28860. "vec3 kD = 1.0 - kS;\n"
  28861. "kD *= 1.0 - metallic;\n"
  28862. "vec3 diffuse = irradiance * albedo;\n"
  28863. "vec3 specular = radiance * (F * brdf.x + brdf.y);\n"
  28864. "ambient = (kD * diffuse + specular);\n"
  28865. "}else\n"
  28866. "{\n"
  28867. "vec3 FssEss = kS * brdf.x + brdf.y;\n"
  28868. "float Ess = brdf.x + brdf.y;\n"
  28869. "float Ems = 1-Ess;\n"
  28870. "vec3 Favg = F0 + (1-F0)/21;\n"
  28871. "vec3 Fms = FssEss*Favg/(1-(1-Ess)*Favg);\n"
  28872. "vec3 Edss = 1 - (FssEss + Fms * Ems);\n"
  28873. "vec3 kD = albedo * Edss;\n"
  28874. "ambient = FssEss * radiance + (Fms*Ems+kD) * irradiance;\n"
  28875. "}\n"
  28876. "return ambient;\n"
  28877. "}\n"
  28878. "void main()\n"
  28879. "{\n"
  28880. "int materialIndex = textureLod(u_materialIndex, v_texCoords, 0).r;\n"
  28881. "if(materialIndex == 0)\n"
  28882. "{\n"
  28883. "if(u_transparentPass != 0)\n"
  28884. "{\n"
  28885. "discard;\n"
  28886. "}else\n"
  28887. "{\n"
  28888. "a_outColor = vec4(0,0,0,0);\n"
  28889. "a_outBloom = vec4(0,0,0,1);\n"
  28890. "return;\n"
  28891. "}\n"
  28892. "}\n"
  28893. "vec3 posViewSpace = texture(u_positionViewSpace, v_texCoords).xyz;\n"
  28894. "vec3 pos = vec3(u_inverseView * vec4(posViewSpace,1));\n"
  28895. "if(posViewSpace.z == -INFINITY){discard;}\n"
  28896. "vec3 normal = fromuShortToFloat(texture(u_normals, v_texCoords).xyz);\n"
  28897. "vec3 viewSpaceNormal = normalize( vec3(transpose(inverse(mat3(u_view))) * normal));\n"
  28898. "vec2 sampledUV = texture(u_textureUV, v_texCoords).xy;\n"
  28899. "ivec4 sampledDerivatesInt = texture(u_textureDerivates, v_texCoords).xyzw;\n"
  28900. "vec4 sampledDerivates = fromuShortToFloat2(sampledDerivatesInt);\n"
  28901. "vec2 rezolution = textureSize(u_lastFrameTexture, 0);\n"
  28902. "vec4 albedoAlpha = vec4(0,0,0,0);\n"
  28903. "vec3 emissive = vec3(0,0,0);\n"
  28904. "vec3 material = vec3(0,0,0);\n"
  28905. "{\n"
  28906. "uvec2 albedoSampler = mat[materialIndex-1].firstBIndlessSamplers.xy;\n"
  28907. "if(albedoSampler.x == 0 && albedoSampler.y == 0)\n"
  28908. "{\n"
  28909. "albedoAlpha.rgba = vec4(1,1,1,1); \n"
  28910. "}else\n"
  28911. "{\n"
  28912. "albedoAlpha = \n"
  28913. "textureGrad(sampler2D(albedoSampler), sampledUV.xy, \n"
  28914. "sampledDerivates.xy, sampledDerivates.zw).rgba;\n"
  28915. "}\n"
  28916. "albedoAlpha.rgb *= pow( vec3(mat[materialIndex-1].kd), vec3(1.0/2.2) );\n"
  28917. "albedoAlpha.a *= mat[materialIndex-1].kd.a;\n"
  28918. "uvec2 emmisiveSampler = mat[materialIndex-1].secondBIndlessSamplers.xy;\n"
  28919. "if(emmisiveSampler.x == 0 && emmisiveSampler.y == 0)\n"
  28920. "{\n"
  28921. "emissive.rgb = albedoAlpha.rgb;\n"
  28922. "}else\n"
  28923. "{\n"
  28924. "emissive = \n"
  28925. "textureGrad(sampler2D(emmisiveSampler), sampledUV.xy, \n"
  28926. "sampledDerivates.xy, sampledDerivates.zw).rgb;\n"
  28927. "}\n"
  28928. "emissive.rgb *= mat[materialIndex-1].rma.a;\n"
  28929. "emissive = pow(emissive , vec3(2.2)).rgb; \n"
  28930. "uvec2 rmaSampler = mat[materialIndex-1].firstBIndlessSamplers.zw;\n"
  28931. "if(rmaSampler.x == 0 && rmaSampler.y == 0 && mat[materialIndex-1].rmaLoaded != 0)\n"
  28932. "{\n"
  28933. "material.r = mat[materialIndex-1].rma.r;\n"
  28934. "material.g = mat[materialIndex-1].rma.g;\n"
  28935. "material.b = mat[materialIndex-1].rma.b;\n"
  28936. "}\n"
  28937. "else\n"
  28938. "{\n"
  28939. "vec3 materialData = textureGrad(sampler2D(rmaSampler), sampledUV.xy, \n"
  28940. "sampledDerivates.xy, sampledDerivates.zw).rgb;\n"
  28941. "int roughnessPrezent = mat[materialIndex-1].rmaLoaded & 0x4;\n"
  28942. "int metallicPrezent = mat[materialIndex-1].rmaLoaded & 0x2;\n"
  28943. "int ambientPrezent = mat[materialIndex-1].rmaLoaded & 0x1;\n"
  28944. "if(roughnessPrezent != 0)\n"
  28945. "{\n"
  28946. "material.r = materialData.r;\n"
  28947. "}else\n"
  28948. "{\n"
  28949. "material.r = mat[materialIndex-1].rma.r;\n"
  28950. "}\n"
  28951. "if(metallicPrezent != 0)\n"
  28952. "{\n"
  28953. "material.g = materialData.g;\n"
  28954. "}else\n"
  28955. "{\n"
  28956. "material.g = mat[materialIndex-1].rma.g;\n"
  28957. "}\n"
  28958. "if(ambientPrezent != 0)\n"
  28959. "{\n"
  28960. "material.b = materialData.b;\n"
  28961. "}else\n"
  28962. "{\n"
  28963. "material.b = mat[materialIndex-1].rma.b;\n"
  28964. "}\n"
  28965. "}\n"
  28966. "}\n"
  28967. "vec3 albedo = albedoAlpha.rgb;\n"
  28968. "albedo = pow(albedo , vec3(2.2)).rgb; \n"
  28969. "float roughness = clamp(material.r, 0.09, 0.99);\n"
  28970. "float metallic = clamp(material.g, 0.0, 0.98);\n"
  28971. "float ambientOcclution = material.b;\n"
  28972. "vec3 viewDir = normalize(u_eyePosition - pos); \n"
  28973. "vec3 R = reflect(-viewDir, normal); \n"
  28974. "vec3 Lo = vec3(0,0,0); \n"
  28975. "vec3 F0 = vec3(0.04); \n"
  28976. "F0 = mix(F0, albedo.rgb, vec3(metallic));\n"
  28977. "for(int i=0; i<u_pointLightCount;i++)\n"
  28978. "{\n"
  28979. "vec3 lightPosition = light[i].positions.xyz;\n"
  28980. "vec3 lightColor = light[i].color.rgb;\n"
  28981. "vec3 lightDirection = normalize(lightPosition - pos);\n"
  28982. "float currentDist = distance(lightPosition, pos);\n"
  28983. "if(currentDist >= light[i].dist)\n"
  28984. "{\n"
  28985. "continue;\n"
  28986. "}\n"
  28987. "float attenuation = attenuationFunctionNotClamped(currentDist, light[i].dist, light[i].attenuation); \n"
  28988. "float shadow = 1.f;\n"
  28989. "if(light[i].castShadows != 0)\n"
  28990. "{\n"
  28991. "shadow = pointShadowCalculation(pos, normal, i);\n"
  28992. "shadow = pow(shadow, light[i].hardness);\n"
  28993. "}\n"
  28994. "Lo += computePointLightSource(lightDirection, metallic, roughness, lightColor, \n"
  28995. "pos, viewDir, albedo, normal, F0) * attenuation * shadow;\n"
  28996. "}\n"
  28997. "for(int i=0; i<u_directionalLightCount; i++)\n"
  28998. "{\n"
  28999. "vec3 lightDirection = dLight[i].direction.xyz;\n"
  29000. "vec3 lightColor = dLight[i].color.rgb;\n"
  29001. "float shadow = 1;\n"
  29002. "if(dLight[i].castShadows != 0)\n"
  29003. "{ \n"
  29004. "int castShadowInd = dLight[i].castShadowsIndex;\n"
  29005. "shadow = cascadedShadowCalculation(pos, normal, lightDirection, castShadowInd);\n"
  29006. "shadow = pow(shadow, dLight[i].color.w);\n"
  29007. "}\n"
  29008. "Lo += computePointLightSource(-lightDirection, metallic, roughness, lightColor, \n"
  29009. "pos, viewDir, albedo, normal, F0) * shadow;\n"
  29010. "}\n"
  29011. "for(int i=0; i<u_spotLightCount; i++)\n"
  29012. "{\n"
  29013. "vec3 lightPosition = spotLights[i].position.xyz;\n"
  29014. "vec3 lightColor = spotLights[i].color.rgb;\n"
  29015. "vec3 spotLightDirection = spotLights[i].direction.xyz;\n"
  29016. "vec3 lightDirection = -normalize(lightPosition - pos);\n"
  29017. "float angle = spotLights[i].position.w;\n"
  29018. "float dist = spotLights[i].direction.w;\n"
  29019. "float at = spotLights[i].color.w;\n"
  29020. "float dotAngle = dot(normalize(vec3(pos - lightPosition)), spotLightDirection);\n"
  29021. "float currentDist = distance(lightPosition, pos);\n"
  29022. "if(currentDist >= dist)\n"
  29023. "{\n"
  29024. "continue;\n"
  29025. "}\n"
  29026. "if(dotAngle > angle && dotAngle > 0)\n"
  29027. "{\n"
  29028. "float attenuation = attenuationFunctionNotClamped(currentDist, dist, at);\n"
  29029. "float smoothingVal = 0.01; \n"
  29030. "float innerAngle = angle + smoothingVal;\n"
  29031. "float smoothing = clamp((dotAngle-angle)/smoothingVal,0.0,1.0);\n"
  29032. "vec3 shadowProjCoords = getProjCoords(spotLights[i].lightSpaceMatrix, pos);\n"
  29033. "float shadow = 1;\n"
  29034. "if(spotLights[i].castShadows != 0)\n"
  29035. "{\n"
  29036. "shadow = shadowCalculationLogaritmic(shadowProjCoords, normal, lightDirection, \n"
  29037. "u_spotShadows, spotLights[i].shadowIndex, spotLights[i].near, spotLights[i].far);\n"
  29038. "shadow = pow(shadow, spotLights[i].hardness);\n"
  29039. "}\n"
  29040. "smoothing = pow(smoothing, spotLights[i].hardness);\n"
  29041. "Lo += computePointLightSource(-lightDirection, metallic, roughness, lightColor, \n"
  29042. "pos, viewDir, albedo, normal, F0) * smoothing * attenuation * shadow;\n"
  29043. "}\n"
  29044. "}\n"
  29045. "vec3 color = Lo + computeAmbientTerm(normal, viewDir, F0, roughness, R, metallic, \n"
  29046. "albedo, pos, posViewSpace, viewSpaceNormal, rezolution)\n"
  29047. "* ambientOcclution; \n"
  29048. "if(u_transparentPass != 0)\n"
  29049. "{\n"
  29050. "float a = albedoAlpha.a;\n"
  29051. "a = 1-a;\n"
  29052. "a *= dot(viewDir, normal);\n"
  29053. "a = 1-a;\n"
  29054. "a_outColor = vec4(color.rgb + emissive.rgb, a);\n"
  29055. "a_outBloom = vec4(emissive.rgb, a);\n"
  29056. "}else\n"
  29057. "{\n"
  29058. "a_outColor = vec4(color.rgb + emissive.rgb, 1);\n"
  29059. "a_outBloom = vec4(emissive.rgb, 1);\n"
  29060. "}\n"
  29061. "}\n"},
  29062. std::pair<std::string, const char*>{"geometryPass.vert", "#version 430\n"
  29063. "layout(location = 0) in vec3 a_positions;\n"
  29064. "layout(location = 1) in vec3 a_normals;\n"
  29065. "layout(location = 2) in vec2 a_texCoord;\n"
  29066. "layout(location = 3) in ivec4 a_jointsId;\n"
  29067. "layout(location = 4) in vec4 a_weights;\n"
  29068. "uniform mat4 u_transform; \n"
  29069. "uniform mat4 u_modelTransform; \n"
  29070. "uniform mat4 u_motelViewTransform; \n"
  29071. "out vec3 v_normals;\n"
  29072. "out vec2 v_texCoord;\n"
  29073. "out vec3 v_positionViewSpace;\n"
  29074. "readonly restrict layout(std140) buffer u_jointTransforms\n"
  29075. "{\n"
  29076. "mat4 jointTransforms[];\n"
  29077. "};\n"
  29078. "uniform int u_hasAnimations;\n"
  29079. "void main()\n"
  29080. "{\n"
  29081. "vec4 totalLocalPos = vec4(0.f);\n"
  29082. "vec4 totalNorm = vec4(0.f);\n"
  29083. "if(u_hasAnimations != 0)\n"
  29084. "{\n"
  29085. "for(int i=0; i<4; i++)\n"
  29086. "{\n"
  29087. "if(a_jointsId[i] < 0){break;}\n"
  29088. "mat4 jointTransform = jointTransforms[a_jointsId[i]];\n"
  29089. "vec4 posePosition = jointTransform * vec4(a_positions, 1);\n"
  29090. "totalLocalPos += posePosition * a_weights[i];\n"
  29091. "vec3 worldNormal = mat3(transpose(inverse(mat3(jointTransform)))) * a_normals.xyz;\n"
  29092. "totalNorm.xyz += worldNormal.xyz * a_weights[i];\n"
  29093. "}\n"
  29094. "totalNorm.xyz = normalize(totalNorm.xyz);\n"
  29095. "}else\n"
  29096. "{\n"
  29097. "totalLocalPos = vec4(a_positions, 1.f);\n"
  29098. "totalNorm = vec4(a_normals, 1);\n"
  29099. "}\n"
  29100. "v_positionViewSpace = vec3(u_motelViewTransform * totalLocalPos);\n"
  29101. "gl_Position = u_transform * totalLocalPos;\n"
  29102. "v_normals = mat3(transpose(inverse(mat3(u_modelTransform)))) * totalNorm.xyz; \n"
  29103. "v_normals = normalize(v_normals);\n"
  29104. "v_texCoord = a_texCoord;\n"
  29105. "}\n"},
  29106. std::pair<std::string, const char*>{"geometryPass.frag", "#version 430\n"
  29107. "#extension GL_ARB_bindless_texture: require\n"
  29108. "layout(location = 0) out ivec3 a_normal;\n"
  29109. "layout(location = 1) out ivec4 a_textureDerivates;\n"
  29110. "layout(location = 2) out vec3 a_posViewSpace;\n"
  29111. "layout(location = 3) out int a_materialIndex;\n"
  29112. "layout(location = 4) out vec4 a_textureUV;\n"
  29113. "in vec3 v_normals;\n"
  29114. "in vec2 v_texCoord;\n"
  29115. "in vec3 v_positionViewSpace;\n"
  29116. "uniform sampler2D u_normalSampler;\n"
  29117. "uniform int u_materialIndex;\n"
  29118. "struct MaterialStruct\n"
  29119. "{\n"
  29120. "vec4 kd;\n"
  29121. "vec4 rma; \n"
  29122. "uvec4 firstBIndlessSamplers; \n"
  29123. "uvec2 secondBIndlessSamplers; \n"
  29124. "int rmaLoaded;\n"
  29125. "int notUsed;\n"
  29126. "};\n"
  29127. "readonly layout(std140) buffer u_material\n"
  29128. "{\n"
  29129. "MaterialStruct mat[];\n"
  29130. "};\n"
  29131. "float PI = 3.14159265359;\n"
  29132. "mat3x3 NormalToRotation(in vec3 normal)\n"
  29133. "{\n"
  29134. "vec3 tangent0 = cross(normal, vec3(1, 0, 0));\n"
  29135. "if (dot(tangent0, tangent0) < 0.001)\n"
  29136. "tangent0 = cross(normal, vec3(0, 1, 0));\n"
  29137. "tangent0 = normalize(tangent0);\n"
  29138. "vec3 tangent1 = normalize(cross(normal, tangent0));\n"
  29139. "return mat3x3(tangent0,tangent1,normal);\n"
  29140. "}\n"
  29141. "subroutine vec3 GetNormalMapFunc(vec3);\n"
  29142. "subroutine (GetNormalMapFunc) vec3 normalMapped(vec3 v)\n"
  29143. "{\n"
  29144. "vec3 normal = texture2D(u_normalSampler, v_texCoord).rgb;\n"
  29145. "normal = normalize(2*normal - 1.f);\n"
  29146. "mat3 rotMat = NormalToRotation(v);\n"
  29147. "normal = rotMat * normal;\n"
  29148. "normal = normalize(normal);\n"
  29149. "return normal;\n"
  29150. "}\n"
  29151. "subroutine (GetNormalMapFunc) vec3 noNormalMapped(vec3 v)\n"
  29152. "{\n"
  29153. "return v;\n"
  29154. "}\n"
  29155. "subroutine uniform GetNormalMapFunc getNormalMapFunc;\n"
  29156. "int fromFloat2TouShort(float a)\n"
  29157. "{\n"
  29158. "a += 2.f;\n"
  29159. "a /= 4.f;\n"
  29160. "a *= 65536;\n"
  29161. "return int(a);\n"
  29162. "}\n"
  29163. "ivec3 fromFloatTouShort(vec3 a)\n"
  29164. "{\n"
  29165. "a += 1.f;\n"
  29166. "a /= 2.f;\n"
  29167. "a *= 65536;\n"
  29168. "return ivec3(a);\n"
  29169. "}\n"
  29170. "void main()\n"
  29171. "{\n"
  29172. "uvec2 albedoSampler = mat[u_materialIndex].firstBIndlessSamplers.xy;\n"
  29173. "if(albedoSampler.x == 0 && albedoSampler.y == 0)\n"
  29174. "{\n"
  29175. "}else\n"
  29176. "{\n"
  29177. "float alphaData = texture2D(sampler2D(albedoSampler), v_texCoord).a;\n"
  29178. "if(alphaData*255 < 1)\n"
  29179. "discard;\n"
  29180. "}\n"
  29181. "vec3 noMappedNorals = normalize(v_normals);\n"
  29182. "vec3 normal = getNormalMapFunc(noMappedNorals);\n"
  29183. "normal = normalize(normal);\n"
  29184. "a_normal = fromFloatTouShort(normal);\n"
  29185. "a_posViewSpace = v_positionViewSpace;\n"
  29186. "a_materialIndex = u_materialIndex+1;\n"
  29187. "a_textureUV.xy = v_texCoord.xy;\n"
  29188. "a_textureDerivates.x = fromFloat2TouShort(dFdx(v_texCoord.x));\n"
  29189. "a_textureDerivates.y = fromFloat2TouShort(dFdy(v_texCoord.x));\n"
  29190. "a_textureDerivates.z = fromFloat2TouShort(dFdx(v_texCoord.y));\n"
  29191. "a_textureDerivates.w = fromFloat2TouShort(dFdy(v_texCoord.y));\n"
  29192. "}\n"},
  29193. std::pair<std::string, const char*>{"noaa.frag", "#version 150\n"
  29194. "out vec4 a_color;\n"
  29195. "noperspective in vec2 v_texCoords;\n"
  29196. "uniform sampler2D u_texture;\n"
  29197. "void main ()\n"
  29198. "{\n"
  29199. "vec4 tmpvar_1;\n"
  29200. "tmpvar_1.w = 1.0;\n"
  29201. "tmpvar_1.xyz = texture (u_texture, v_texCoords).xyz;\n"
  29202. "a_color = tmpvar_1;\n"
  29203. "}\n"},
  29204. std::pair<std::string, const char*>{"fxaa.frag", "#version 330 core\n"
  29205. "out vec4 a_color;\n"
  29206. "noperspective in vec2 v_texCoords;\n"
  29207. "uniform sampler2D u_texture;\n"
  29208. "float luminance(in vec3 color)\n"
  29209. "{\n"
  29210. "return dot(color, vec3(0.299, 0.587, 0.114));\n"
  29211. "}\n"
  29212. "float lumaSqr(in vec3 color)\n"
  29213. "{\n"
  29214. "return sqrt(luminance(color));\n"
  29215. "}\n"
  29216. "vec3 getTexture(in vec2 offset)\n"
  29217. "{\n"
  29218. "return texture2D(u_texture, v_texCoords + offset).rgb;\n"
  29219. "}\n"
  29220. "float quality(int i)\n"
  29221. "{\n"
  29222. "const int SIZE = 8;\n"
  29223. "const int FIRST_SAMPLES_COUNT = 5;\n"
  29224. "const float r[SIZE] = float[SIZE](1.5, 2.0, 2.0, 2.0, 2.0, 4.0, 6.0, 7.0);\n"
  29225. "if(i < FIRST_SAMPLES_COUNT)\n"
  29226. "{\n"
  29227. "return 1;\n"
  29228. "}else if(i >= FIRST_SAMPLES_COUNT + SIZE)\n"
  29229. "{\n"
  29230. "return 8;\n"
  29231. "}else return r[i-FIRST_SAMPLES_COUNT];\n"
  29232. "}\n"
  29233. "/*\n"
  29234. "default values example\n"
  29235. "float edgeMinTreshold = 0.028;\n"
  29236. "float edgeDarkTreshold = 0.125;\n"
  29237. "int ITERATIONS = 12;\n"
  29238. "float quaityMultiplier = 0.8;\n"
  29239. "float SUBPIXEL_QUALITY = 0.95;\n"
  29240. "*/\n"
  29241. "layout(std140) uniform u_FXAAData\n"
  29242. "{\n"
  29243. "float edgeMinTreshold;\n"
  29244. "float edgeDarkTreshold;\n"
  29245. "int ITERATIONS;\n"
  29246. "float quaityMultiplier;\n"
  29247. "float SUBPIXEL_QUALITY;\n"
  29248. "}fxaaData;\n"
  29249. "void main()\n"
  29250. "{\n"
  29251. "vec3 colorCenter = getTexture(vec2(0,0)).rgb;\n"
  29252. "float lumaCenter = lumaSqr(colorCenter);\n"
  29253. "float lumaDown = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(0,-1)).rgb);\n"
  29254. "float lumaUp = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(0,1)).rgb);\n"
  29255. "float lumaLeft = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(-1,0)).rgb);\n"
  29256. "float lumaRight = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(1,0)).rgb);\n"
  29257. "float lumaMin = min(lumaCenter,min(min(lumaDown,lumaUp),min(lumaLeft,lumaRight)));\n"
  29258. "float lumaMax = max(lumaCenter,max(max(lumaDown,lumaUp),max(lumaLeft,lumaRight)));\n"
  29259. "float lumaRange = lumaMax - lumaMin;\n"
  29260. "if(lumaRange < max(fxaaData.edgeMinTreshold,lumaMax*fxaaData.edgeDarkTreshold))\n"
  29261. "{\n"
  29262. "a_color = vec4(colorCenter, 1);\n"
  29263. "return;\n"
  29264. "}\n"
  29265. "float lumaDownLeft = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(-1,-1)).rgb);\n"
  29266. "float lumaUpRight = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(1,1)).rgb);\n"
  29267. "float lumaUpLeft = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(-1,1)).rgb);\n"
  29268. "float lumaDownRight = lumaSqr(textureOffset(u_texture,v_texCoords,ivec2(1,-1)).rgb);\n"
  29269. "float lumaDownUp = lumaDown + lumaUp;\n"
  29270. "float lumaLeftRight = lumaLeft + lumaRight;\n"
  29271. "float lumaLeftCorners = lumaDownLeft + lumaUpLeft;\n"
  29272. "float lumaDownCorners = lumaDownLeft + lumaDownRight;\n"
  29273. "float lumaRightCorners = lumaDownRight + lumaUpRight;\n"
  29274. "float lumaUpCorners = lumaUpRight + lumaUpLeft;\n"
  29275. "float edgeHorizontal = abs(-2.0 * lumaLeft + lumaLeftCorners) + abs(-2.0 * lumaCenter + lumaDownUp ) * 2.0 + abs(-2.0 * lumaRight + lumaRightCorners);\n"
  29276. "float edgeVertical = abs(-2.0 * lumaUp + lumaUpCorners) + abs(-2.0 * lumaCenter + lumaLeftRight) * 2.0 + abs(-2.0 * lumaDown + lumaDownCorners);\n"
  29277. "bool isHorizontal = (edgeHorizontal >= edgeVertical);\n"
  29278. "float luma1 = isHorizontal ? lumaDown : lumaLeft;\n"
  29279. "float luma2 = isHorizontal ? lumaUp : lumaRight;\n"
  29280. "float gradient1 = luma1 - lumaCenter;\n"
  29281. "float gradient2 = luma2 - lumaCenter;\n"
  29282. "bool is1Steepest = abs(gradient1) >= abs(gradient2);\n"
  29283. "float gradientScaled = 0.25*max(abs(gradient1),abs(gradient2));\n"
  29284. "vec2 inverseScreenSize = 1.f/textureSize(u_texture, 0);\n"
  29285. "float stepLength = isHorizontal ? inverseScreenSize.y : inverseScreenSize.x;\n"
  29286. "float lumaLocalAverage = 0.0;\n"
  29287. "if(is1Steepest)\n"
  29288. "{\n"
  29289. "stepLength = - stepLength;\n"
  29290. "lumaLocalAverage = 0.5*(luma1 + lumaCenter);\n"
  29291. "} \n"
  29292. "else\n"
  29293. "{\n"
  29294. "lumaLocalAverage = 0.5*(luma2 + lumaCenter);\n"
  29295. "}\n"
  29296. "vec2 currentUv = v_texCoords;\n"
  29297. "if(isHorizontal)\n"
  29298. "{\n"
  29299. "currentUv.y += stepLength * 0.5;\n"
  29300. "} else \n"
  29301. "{\n"
  29302. "currentUv.x += stepLength * 0.5;\n"
  29303. "}\n"
  29304. "vec2 offset = isHorizontal ? vec2(inverseScreenSize.x,0.0) : vec2(0.0,inverseScreenSize.y);\n"
  29305. "vec2 uv1 = currentUv - offset;\n"
  29306. "vec2 uv2 = currentUv + offset;\n"
  29307. "float lumaEnd1 = lumaSqr(texture(u_texture,uv1).rgb);\n"
  29308. "float lumaEnd2 = lumaSqr(texture(u_texture,uv2).rgb);\n"
  29309. "lumaEnd1 -= lumaLocalAverage;\n"
  29310. "lumaEnd2 -= lumaLocalAverage;\n"
  29311. "bool reached1 = abs(lumaEnd1) >= gradientScaled;\n"
  29312. "bool reached2 = abs(lumaEnd2) >= gradientScaled;\n"
  29313. "bool reachedBoth = reached1 && reached2;\n"
  29314. "if(!reached1){\n"
  29315. "uv1 -= offset;\n"
  29316. "}\n"
  29317. "if(!reached2){\n"
  29318. "uv2 += offset;\n"
  29319. "} \n"
  29320. "if(!reachedBoth)\n"
  29321. "{\n"
  29322. "for(int i = 0; i < fxaaData.ITERATIONS; i++)\n"
  29323. "{\n"
  29324. "if(!reached1){\n"
  29325. "lumaEnd1 = lumaSqr(texture(u_texture, uv1).rgb);\n"
  29326. "lumaEnd1 = lumaEnd1 - lumaLocalAverage;\n"
  29327. "}\n"
  29328. "if(!reached2){\n"
  29329. "lumaEnd2 = lumaSqr(texture(u_texture, uv2).rgb);\n"
  29330. "lumaEnd2 = lumaEnd2 - lumaLocalAverage;\n"
  29331. "}\n"
  29332. "reached1 = abs(lumaEnd1) >= gradientScaled;\n"
  29333. "reached2 = abs(lumaEnd2) >= gradientScaled;\n"
  29334. "reachedBoth = reached1 && reached2;\n"
  29335. "if(!reached1)\n"
  29336. "{\n"
  29337. "uv1 -= offset * quality(i) * fxaaData.quaityMultiplier;\n"
  29338. "}\n"
  29339. "if(!reached2)\n"
  29340. "{\n"
  29341. "uv2 += offset * quality(i) * fxaaData.quaityMultiplier;\n"
  29342. "}\n"
  29343. "if(reachedBoth){ break;}\n"
  29344. "}\n"
  29345. "}\n"
  29346. "float distance1 = isHorizontal ? (v_texCoords.x - uv1.x) : (v_texCoords.y - uv1.y);\n"
  29347. "float distance2 = isHorizontal ? (uv2.x - v_texCoords.x) : (uv2.y - v_texCoords.y);\n"
  29348. "bool isDirection1 = distance1 < distance2;\n"
  29349. "float distanceFinal = min(distance1, distance2);\n"
  29350. "float edgeThickness = (distance1 + distance2);\n"
  29351. "float pixelOffset = - distanceFinal / edgeThickness + 0.5;\n"
  29352. "bool isLumaCenterSmaller = lumaCenter < lumaLocalAverage;\n"
  29353. "bool correctVariation = ((isDirection1 ? lumaEnd1 : lumaEnd2) < 0.0) != isLumaCenterSmaller;\n"
  29354. "float finalOffset = correctVariation ? pixelOffset : 0.0;\n"
  29355. "float lumaAverage = (1.0/12.0) * (2.0 * (lumaDownUp + lumaLeftRight) + lumaLeftCorners + lumaRightCorners);\n"
  29356. "float subPixelOffset1 = clamp(abs(lumaAverage - lumaCenter)/lumaRange,0.0,1.0);\n"
  29357. "float subPixelOffset2 = (-2.0 * subPixelOffset1 + 3.0) * subPixelOffset1 * subPixelOffset1;\n"
  29358. "float subPixelOffsetFinal = subPixelOffset2 * subPixelOffset2 * fxaaData.SUBPIXEL_QUALITY;\n"
  29359. "finalOffset = max(finalOffset,subPixelOffsetFinal);\n"
  29360. "vec2 finalUv = v_texCoords;\n"
  29361. "if(isHorizontal){\n"
  29362. "finalUv.y += finalOffset * stepLength;\n"
  29363. "} else {\n"
  29364. "finalUv.x += finalOffset * stepLength;\n"
  29365. "}\n"
  29366. "vec3 finalColor = texture(u_texture, finalUv).rgb;\n"
  29367. "a_color = vec4(finalColor, 1);\n"
  29368. "}\n"},
  29369. std::pair<std::string, const char*>{"stencil.vert", "#version 330\n"
  29370. "in layout(location = 0) vec3 a_positions;\n"
  29371. "in layout(location = 1) vec3 a_normals;\n"
  29372. "uniform mat4 u_transform;\n"
  29373. "uniform mat4 u_modelTransform;\n"
  29374. "out vec3 v_normals;\n"
  29375. "out vec3 v_position;\n"
  29376. "void main()\n"
  29377. "{\n"
  29378. "gl_Position = u_transform * vec4(a_positions, 1.f);\n"
  29379. "v_position = (u_modelTransform * vec4(a_positions,1)).xyz;\n"
  29380. "v_normals = mat3(transpose(inverse(mat3(u_modelTransform)))) * a_normals; \n"
  29381. "v_normals = normalize(v_normals);\n"
  29382. "}\n"},
  29383. std::pair<std::string, const char*>{"stencil.frag", "#pragma once\n"},
  29384. std::pair<std::string, const char*>{"showNormals.vert", "#version 330\n"
  29385. "in layout(location = 0) vec3 a_positions;\n"
  29386. "in layout(location = 1) vec3 a_normals;\n"
  29387. "uniform mat4 u_modelTransform; \n"
  29388. "out vec3 v_normals;\n"
  29389. "void main()\n"
  29390. "{\n"
  29391. "gl_Position = u_modelTransform * vec4(a_positions, 1);\n"
  29392. "v_normals = mat3(transpose(inverse(mat3(u_modelTransform)))) * a_normals; \n"
  29393. "v_normals = normalize(v_normals);\n"
  29394. "}\n"},
  29395. std::pair<std::string, const char*>{"showNormals.geom", "#version 330 core\n"
  29396. "layout (triangles) in;\n"
  29397. "layout (line_strip, max_vertices = 6) out;\n"
  29398. "in vec3 v_normals[];\n"
  29399. "uniform float u_size = 0.5;\n"
  29400. "uniform mat4 u_projection; \n"
  29401. "void emitNormal(int index)\n"
  29402. "{\n"
  29403. "gl_Position = u_projection * gl_in[index].gl_Position;\n"
  29404. "EmitVertex();\n"
  29405. "gl_Position = u_projection * (gl_in[index].gl_Position + vec4(v_normals[index],0) * u_size);\n"
  29406. "EmitVertex();\n"
  29407. "EndPrimitive();\n"
  29408. "}\n"
  29409. "void main()\n"
  29410. "{\n"
  29411. "emitNormal(0);\n"
  29412. "emitNormal(1);\n"
  29413. "emitNormal(2);\n"
  29414. "}\n"},
  29415. std::pair<std::string, const char*>{"showNormals.frag", "#version 150\n"
  29416. "out vec4 a_outColor;\n"
  29417. "uniform vec3 u_color = vec3(0.7, 0.7, 0.1);\n"
  29418. "void main ()\n"
  29419. "{\n"
  29420. "vec4 tmpvar_1;\n"
  29421. "tmpvar_1.w = 1.0;\n"
  29422. "tmpvar_1.xyz = u_color;\n"
  29423. "a_outColor = tmpvar_1;\n"
  29424. "}\n"},
  29425. std::pair<std::string, const char*>{"normals.vert", "#version 330\n"
  29426. "in layout(location = 0) vec3 a_positions;\n"
  29427. "in layout(location = 1) vec3 a_normals;\n"
  29428. "in layout(location = 2) vec2 a_texCoord;\n"
  29429. "uniform mat4 u_transform; \n"
  29430. "uniform mat4 u_modelTransform; \n"
  29431. "out vec3 v_normals;\n"
  29432. "out vec3 v_position;\n"
  29433. "out vec2 v_texCoord;\n"
  29434. "void main()\n"
  29435. "{\n"
  29436. "gl_Position = u_transform * vec4(a_positions, 1.f);\n"
  29437. "v_position = (u_modelTransform * vec4(a_positions,1)).xyz;\n"
  29438. "v_normals = mat3(transpose(inverse(mat3(u_modelTransform)))) * a_normals; \n"
  29439. "v_normals = normalize(v_normals);\n"
  29440. "v_texCoord = a_texCoord;\n"
  29441. "}\n"},
  29442. std::pair<std::string, const char*>{"normals.frag", "#version 430\n"
  29443. "#extension GL_NV_shadow_samplers_cube : enable\n"
  29444. "out layout(location = 0) vec4 a_outColor;\n"
  29445. "in vec3 v_normals;\n"
  29446. "in vec3 v_position; \n"
  29447. "in vec2 v_texCoord;\n"
  29448. "uniform vec3 u_eyePosition;\n"
  29449. "uniform sampler2D u_albedoSampler;\n"
  29450. "uniform sampler2D u_normalSampler;\n"
  29451. "uniform samplerCube u_skybox;\n"
  29452. "uniform float u_gama;\n"
  29453. "uniform sampler2D u_RMASampler;\n"
  29454. "uniform int u_materialIndex;\n"
  29455. "struct Pointlight\n"
  29456. "{\n"
  29457. "vec3 positions; \n"
  29458. "float dist;\n"
  29459. "vec3 color; \n"
  29460. "float strength;\n"
  29461. "};\n"
  29462. "readonly layout(std140) buffer u_pointLights\n"
  29463. "{\n"
  29464. "Pointlight light[];\n"
  29465. "};\n"
  29466. "uniform int u_pointLightCount;\n"
  29467. "struct MaterialStruct\n"
  29468. "{\n"
  29469. "vec4 kd;\n"
  29470. "vec4 rma;\n"
  29471. "};\n"
  29472. "readonly layout(std140) buffer u_material\n"
  29473. "{\n"
  29474. "MaterialStruct mat[];\n"
  29475. "};\n"
  29476. "vec3 normal; \n"
  29477. "vec3 noMappedNorals; \n"
  29478. "vec3 viewDir;\n"
  29479. "float difuseTest; \n"
  29480. "vec4 color; \n"
  29481. "float PI = 3.14159265359;\n"
  29482. "mat3x3 NormalToRotation(in vec3 normal)\n"
  29483. "{\n"
  29484. "vec3 tangent0 = cross(normal, vec3(1, 0, 0));\n"
  29485. "if (dot(tangent0, tangent0) < 0.001)\n"
  29486. "tangent0 = cross(normal, vec3(0, 1, 0));\n"
  29487. "tangent0 = normalize(tangent0);\n"
  29488. "vec3 tangent1 = normalize(cross(normal, tangent0));\n"
  29489. "return mat3x3(tangent0,tangent1,normal);\n"
  29490. "}\n"
  29491. "subroutine vec3 GetNormalMapFunc(vec3);\n"
  29492. "subroutine (GetNormalMapFunc) vec3 normalMapped(vec3 v)\n"
  29493. "{\n"
  29494. "vec3 normal = texture2D(u_normalSampler, v_texCoord).rgb;\n"
  29495. "normal = normalize(2*normal - 1.f);\n"
  29496. "mat3 rotMat = NormalToRotation(v);\n"
  29497. "normal = rotMat * normal;\n"
  29498. "normal = normalize(normal);\n"
  29499. "return normal;\n"
  29500. "}\n"
  29501. "subroutine (GetNormalMapFunc) vec3 noNormalMapped(vec3 v)\n"
  29502. "{\n"
  29503. "return v;\n"
  29504. "}\n"
  29505. "subroutine uniform GetNormalMapFunc getNormalMapFunc;\n"
  29506. "subroutine vec4 GetAlbedoFunc();\n"
  29507. "subroutine (GetAlbedoFunc) vec4 sampledAlbedo()\n"
  29508. "{\n"
  29509. "color = texture2D(u_albedoSampler, v_texCoord).xyzw;\n"
  29510. "if(color.w <= 0.1)\n"
  29511. "discard;\n"
  29512. "color.rgb = pow(color.rgb, vec3(2.2,2.2,2.2)).rgb; \n"
  29513. "color *= vec4(mat[u_materialIndex].kd.r, mat[u_materialIndex].kd.g, mat[u_materialIndex].kd.b, 1); \n"
  29514. "return color;\n"
  29515. "}\n"
  29516. "subroutine (GetAlbedoFunc) vec4 notSampledAlbedo()\n"
  29517. "{\n"
  29518. "return vec4(mat[u_materialIndex].kd.r, mat[u_materialIndex].kd.g, mat[u_materialIndex].kd.b, 1); \n"
  29519. "}\n"
  29520. "subroutine uniform GetAlbedoFunc u_getAlbedo;\n"
  29521. "subroutine vec3 GetMaterialMapped();\n"
  29522. "subroutine (GetMaterialMapped) vec3 materialNone()\n"
  29523. "{\n"
  29524. "return vec3(mat[u_materialIndex].rma.x, mat[u_materialIndex].rma.y, mat[u_materialIndex].rma.z);\n"
  29525. "}\n"
  29526. "subroutine (GetMaterialMapped) vec3 materialR()\n"
  29527. "{\n"
  29528. "float r = texture2D(u_RMASampler, v_texCoord).r;\n"
  29529. "return vec3(r, mat[u_materialIndex].rma.y, mat[u_materialIndex].rma.z);\n"
  29530. "}\n"
  29531. "subroutine (GetMaterialMapped) vec3 materialM()\n"
  29532. "{\n"
  29533. "float m = texture2D(u_RMASampler, v_texCoord).r;\n"
  29534. "return vec3(mat[u_materialIndex].rma.x, m, mat[u_materialIndex].rma.z);\n"
  29535. "}\n"
  29536. "subroutine (GetMaterialMapped) vec3 materialA()\n"
  29537. "{\n"
  29538. "float a = texture2D(u_RMASampler, v_texCoord).r;\n"
  29539. "return vec3(mat[u_materialIndex].rma.x, mat[u_materialIndex].rma.y, a);\n"
  29540. "}\n"
  29541. "subroutine (GetMaterialMapped) vec3 materialRM()\n"
  29542. "{\n"
  29543. "vec2 v = texture2D(u_RMASampler, v_texCoord).rg;\n"
  29544. "return vec3(v.x, v.y, mat[u_materialIndex].rma.z);\n"
  29545. "}\n"
  29546. "subroutine (GetMaterialMapped) vec3 materialRA()\n"
  29547. "{\n"
  29548. "vec2 v = texture2D(u_RMASampler, v_texCoord).rb;\n"
  29549. "return vec3(v.x, mat[u_materialIndex].rma.y, v.y);\n"
  29550. "}\n"
  29551. "subroutine (GetMaterialMapped) vec3 materialMA()\n"
  29552. "{\n"
  29553. "vec2 v = texture2D(u_RMASampler, v_texCoord).gb;\n"
  29554. "return vec3(mat[u_materialIndex].rma.x, v.x, v.y);\n"
  29555. "}\n"
  29556. "subroutine (GetMaterialMapped) vec3 materialRMA()\n"
  29557. "{\n"
  29558. "return texture2D(u_RMASampler, v_texCoord).rgb;\n"
  29559. "}\n"
  29560. "subroutine uniform GetMaterialMapped u_getMaterialMapped;\n"
  29561. "float DistributionGGX(vec3 N, vec3 H, float roughness)\n"
  29562. "{\n"
  29563. "float a = roughness*roughness;\n"
  29564. "float a2 = a*a;\n"
  29565. "float NdotH = max(dot(N, H), 0.0);\n"
  29566. "float NdotH2 = NdotH*NdotH;\n"
  29567. "float denom = (NdotH2 * (a2 - 1.0) + 1.0);\n"
  29568. "denom = PI * denom * denom;\n"
  29569. "return a2 / max(denom, 0.0000001);\n"
  29570. "}\n"
  29571. "float GeometrySchlickGGX(float NdotV, float roughness)\n"
  29572. "{\n"
  29573. "float r = (roughness + 1.0);\n"
  29574. "float k = (r*r) / 8.0;\n"
  29575. "float num = NdotV;\n"
  29576. "float denom = NdotV * (1.0 - k) + k;\n"
  29577. "return num / denom;\n"
  29578. "}\n"
  29579. "float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)\n"
  29580. "{\n"
  29581. "float NdotV = max(dot(N, V), 0.0);\n"
  29582. "float NdotL = max(dot(N, L), 0.0);\n"
  29583. "float ggx2 = GeometrySchlickGGX(NdotV, roughness);\n"
  29584. "float ggx1 = GeometrySchlickGGX(NdotL, roughness);\n"
  29585. "return ggx1 * ggx2;\n"
  29586. "}\n"
  29587. "vec3 fresnelSchlick(float cosTheta, vec3 F0)\n"
  29588. "{\n"
  29589. "return F0 + (1.0 - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);\n"
  29590. "}\n"
  29591. "vec3 computePointLightSource(vec3 lightPosition, float metallic, float roughness, in vec3 lightColor)\n"
  29592. "{\n"
  29593. "vec3 lightDirection = normalize(lightPosition - v_position);\n"
  29594. "vec3 halfwayVec = normalize(lightDirection + viewDir);\n"
  29595. "float dist = length(lightPosition - v_position);\n"
  29596. "float attenuation = 1.0 / pow(dist,2);\n"
  29597. "attenuation = 1; \n"
  29598. "vec3 radiance = lightColor * attenuation; \n"
  29599. "vec3 F0 = vec3(0.04); \n"
  29600. "F0 = mix(F0, color.rgb, metallic); \n"
  29601. "vec3 F = fresnelSchlick(max(dot(halfwayVec, viewDir), 0.0), F0);\n"
  29602. "float NDF = DistributionGGX(normal, halfwayVec, roughness); \n"
  29603. "float G = GeometrySmith(normal, viewDir, lightDirection, roughness); \n"
  29604. "float denominator = 4.0 * max(dot(normal, viewDir), 0.0) \n"
  29605. "* max(dot(normal, lightDirection), 0.0);\n"
  29606. "vec3 specular = (NDF * G * F) / max(denominator, 0.001);\n"
  29607. "vec3 kS = F; \n"
  29608. "vec3 kD = vec3(1.0) - kS; \n"
  29609. "kD *= 1.0 - metallic; \n"
  29610. "float NdotL = max(dot(normal, lightDirection), 0.0); \n"
  29611. "vec3 Lo = (kD * color.rgb / PI + specular) * radiance * NdotL;\n"
  29612. "return Lo;\n"
  29613. "}\n"
  29614. "void main()\n"
  29615. "{\n"
  29616. "vec3 sampledMaterial = u_getMaterialMapped();\n"
  29617. "float roughnessSampled = sampledMaterial.r;\n"
  29618. "roughnessSampled = max(0.50,roughnessSampled);\n"
  29619. "float metallicSampled = sampledMaterial.g;\n"
  29620. "float sampledAo = sampledMaterial.b;\n"
  29621. "{ \n"
  29622. "color = u_getAlbedo();\n"
  29623. "noMappedNorals = normalize(v_normals);\n"
  29624. "normal = getNormalMapFunc(noMappedNorals);\n"
  29625. "viewDir = u_eyePosition - v_position;\n"
  29626. "viewDir = normalize(viewDir); \n"
  29627. "}\n"
  29628. "vec3 I = normalize(v_position - u_eyePosition); \n"
  29629. "vec3 R = reflect(I, normal); \n"
  29630. "vec3 skyBoxSpecular = textureCube(u_skybox, R).rgb; \n"
  29631. "vec3 skyBoxDiffuse = textureCube(u_skybox, normal).rgb; \n"
  29632. "vec3 Lo = vec3(0,0,0); \n"
  29633. "for(int i=0; i<u_pointLightCount;i++)\n"
  29634. "{\n"
  29635. "vec3 lightPosition = light[i].positions.xyz;\n"
  29636. "vec3 lightColor = light[i].color.rgb;\n"
  29637. "Lo += computePointLightSource(lightPosition, metallicSampled, roughnessSampled, lightColor);\n"
  29638. "}\n"
  29639. "vec3 ambient = vec3(0.03) * color.rgb * sampledAo; \n"
  29640. "vec3 color = Lo + ambient; \n"
  29641. "float exposure = 1;\n"
  29642. "color = vec3(1.0) - exp(-color * exposure);\n"
  29643. "color = pow(color, vec3(1.0/2.2));\n"
  29644. "a_outColor = clamp(vec4(color.rgb,1), 0, 1);\n"
  29645. "}\n"},
  29646. std::pair<std::string, const char*>{"drawQuads.vert", "#version 330 core\n"
  29647. "layout (location = 0) in vec3 a_Pos;\n"
  29648. "layout (location = 1) in vec2 a_TexCoords;\n"
  29649. "noperspective out vec2 v_texCoords;\n"
  29650. "void main()\n"
  29651. "{\n"
  29652. "v_texCoords = a_TexCoords;\n"
  29653. "gl_Position = vec4(a_Pos, 1.0);\n"
  29654. "}\n"},
  29655. std::pair<std::string, const char*>{"copyDepth.frag", "#version 330 core\n"
  29656. "noperspective in vec2 v_texCoords;\n"
  29657. "uniform sampler2D u_depth;\n"
  29658. "void main()\n"
  29659. "{\n"
  29660. "gl_FragDepth = texture(u_depth, v_texCoords).r;\n"
  29661. "}\n"},
  29662. std::pair<std::string, const char*>{"color.vert", "#version 330\n"
  29663. "in layout(location = 0) vec3 positions;\n"
  29664. "in layout(location = 1) vec3 colors;\n"
  29665. "uniform mat4 u_transform;\n"
  29666. "out vec3 v_colors;\n"
  29667. "void main()\n"
  29668. "{\n"
  29669. "gl_Position = u_transform * vec4(positions,1.f);\n"
  29670. "v_colors = colors;\n"
  29671. "} \n"},
  29672. std::pair<std::string, const char*>{"color.frag", "#version 150\n"
  29673. "out vec4 outColor;\n"
  29674. "in vec3 v_colors;\n"
  29675. "void main ()\n"
  29676. "{\n"
  29677. "vec4 tmpvar_1;\n"
  29678. "tmpvar_1.w = 1.0;\n"
  29679. "tmpvar_1.xyz = v_colors;\n"
  29680. "outColor = tmpvar_1;\n"
  29681. "}\n"},
  29682. //std::pair test stuff...
  29683. };
  29684. GLint createShaderFromFile(const char* source, GLenum shaderType, ErrorReporter &errorReporter, FileOpener &fileOpener)
  29685. {
  29686. std::string newFileName;
  29687. std::string strSource = source;
  29688. newFileName.reserve(30);
  29689. for(int i=strSource.size()-1; i >= 0; i--)
  29690. {
  29691. if (strSource[i] != '\\' && strSource[i] != '/')
  29692. {
  29693. newFileName.insert(newFileName.begin(), strSource[i]);
  29694. }
  29695. else
  29696. {
  29697. break;
  29698. }
  29699. }
  29700. auto rez = createShaderFromData(headerOnlyShaders[newFileName], shaderType, errorReporter);
  29701. return rez;
  29702. }
  29703. #else
  29704. GLint createShaderFromFile(const char* name, GLenum shaderType, ErrorReporter &errorReporter, FileOpener &fileOpener)
  29705. {
  29706. bool err = 0;
  29707. auto fileContent = fileOpener((std::string("../../../src/") + name).c_str(), err);
  29708. if (err)
  29709. {
  29710. errorReporter.callErrorCallback(std::string("Error openning file: ") + name);
  29711. return 0;
  29712. }
  29713. auto rez = createShaderFromData(fileContent.c_str(), shaderType, errorReporter);
  29714. return rez;
  29715. }
  29716. #endif
  29717. bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *fragmentShader,
  29718. ErrorReporter &errorReporter, FileOpener &fileOpener)
  29719. {
  29720. auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER, errorReporter, fileOpener);
  29721. auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER, errorReporter, fileOpener);
  29722. if (vertexId == 0 || fragmentId == 0)
  29723. {
  29724. return 0;
  29725. }
  29726. id = glCreateProgram();
  29727. glAttachShader(id, vertexId);
  29728. glAttachShader(id, fragmentId);
  29729. glLinkProgram(id);
  29730. glDeleteShader(vertexId);
  29731. glDeleteShader(fragmentId);
  29732. GLint info = 0;
  29733. glGetProgramiv(id, GL_LINK_STATUS, &info);
  29734. if (info != GL_TRUE)
  29735. {
  29736. char *message = 0;
  29737. int l = 0;
  29738. glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
  29739. message = new char[l];
  29740. glGetProgramInfoLog(id, l, &l, message);
  29741. errorReporter.callErrorCallback(std::string("Link error: ") + message);
  29742. delete[] message;
  29743. glDeleteProgram(id);
  29744. id = 0;
  29745. return 0;
  29746. }
  29747. glValidateProgram(id);
  29748. return true;
  29749. }
  29750. bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *geometryShader, const char *fragmentShader,
  29751. ErrorReporter &errorReporter, FileOpener &fileOpener)
  29752. {
  29753. auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER, errorReporter, fileOpener);
  29754. auto geometryId = createShaderFromFile(geometryShader, GL_GEOMETRY_SHADER, errorReporter, fileOpener);
  29755. auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER, errorReporter, fileOpener);
  29756. if (vertexId == 0 || fragmentId == 0 || geometryId == 0)
  29757. {
  29758. return 0;
  29759. }
  29760. id = glCreateProgram();
  29761. glAttachShader(id, vertexId);
  29762. glAttachShader(id, geometryId);
  29763. glAttachShader(id, fragmentId);
  29764. glLinkProgram(id);
  29765. glDeleteShader(vertexId);
  29766. glDeleteShader(geometryId);
  29767. glDeleteShader(fragmentId);
  29768. GLint info = 0;
  29769. glGetProgramiv(id, GL_LINK_STATUS, &info);
  29770. if (info != GL_TRUE)
  29771. {
  29772. char *message = 0;
  29773. int l = 0;
  29774. glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
  29775. message = new char[l];
  29776. glGetProgramInfoLog(id, l, &l, message);
  29777. errorReporter.callErrorCallback(std::string("Link error: ") + message);
  29778. delete[] message;
  29779. glDeleteProgram(id);
  29780. id = 0;
  29781. return 0;
  29782. }
  29783. glValidateProgram(id);
  29784. return true;
  29785. }
  29786. void Shader::bind()
  29787. {
  29788. glUseProgram(id);
  29789. }
  29790. void Shader::clear()
  29791. {
  29792. glDeleteProgram(id);
  29793. id = 0;
  29794. }
  29795. GLint getUniformSubroutine(GLuint id, GLenum shaderType, const char *name, ErrorReporter &errorReporter)
  29796. {
  29797. GLint uniform = glGetSubroutineUniformLocation(id, shaderType, name);
  29798. if (uniform == -1)
  29799. {
  29800. errorReporter.callErrorCallback("uniform subroutine error " + std::string(name));
  29801. }
  29802. return uniform;
  29803. };
  29804. GLint getUniform(GLuint id, const char *name, ErrorReporter &errorReporter)
  29805. {
  29806. GLint uniform = glGetUniformLocation(id, name);
  29807. if (uniform == -1)
  29808. {
  29809. errorReporter.callErrorCallback("uniform error " + std::string(name));
  29810. }
  29811. return uniform;
  29812. };
  29813. GLuint getUniformBlock(GLuint id, const char *name, ErrorReporter &errorReporter)
  29814. {
  29815. GLuint uniform = glGetUniformBlockIndex(id, name);
  29816. if (uniform == GL_INVALID_INDEX)
  29817. {
  29818. errorReporter.callErrorCallback("uniform block error " + std::string(name));
  29819. }
  29820. return uniform;
  29821. };
  29822. GLuint getUniformSubroutineIndex(GLuint id, GLenum shaderType, const char *name, ErrorReporter &errorReporter)
  29823. {
  29824. GLuint uniform = glGetSubroutineIndex(id, shaderType, name);
  29825. if (uniform == GL_INVALID_INDEX)
  29826. {
  29827. errorReporter.callErrorCallback("uniform subroutine index error " + std::string(name));
  29828. }
  29829. return uniform;
  29830. };
  29831. GLuint getStorageBlockIndex(GLuint id, const char *name, ErrorReporter &errorReporter)
  29832. {
  29833. GLuint uniform = glGetProgramResourceIndex(id, GL_SHADER_STORAGE_BLOCK, name);
  29834. if (uniform == GL_INVALID_INDEX)
  29835. {
  29836. errorReporter.callErrorCallback("storage block index error " + std::string(name));
  29837. }
  29838. return uniform;
  29839. };
  29840. //todo move
  29841. std::string LightShader::create(ErrorReporter &errorReporter, FileOpener &fileOpener,
  29842. const char *BRDFIntegrationMapFileLocation)
  29843. {
  29844. std::string error = "";
  29845. //todo proper quality choises
  29846. #pragma region brdf texture
  29847. error += brdfTexture.loadTextureFromFile(BRDFIntegrationMapFileLocation, fileOpener, TextureLoadQuality::linearMipmap, 3);
  29848. glBindTexture(GL_TEXTURE_2D, brdfTexture.id);
  29849. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  29850. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  29851. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  29852. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  29853. #pragma endregion
  29854. if (!error.empty()) { error += "\n"; };
  29855. prePass.shader.loadShaderProgramFromFile("shaders/deferred/zPrePass.vert", "shaders/deferred/zPrePass.frag", errorReporter, fileOpener);
  29856. prePass.u_transform = getUniform(prePass.shader.id, "u_transform", errorReporter);
  29857. prePass.u_albedoSampler = getUniform(prePass.shader.id, "u_albedoSampler", errorReporter);
  29858. prePass.u_hasTexture = getUniform(prePass.shader.id, "u_hasTexture", errorReporter);
  29859. prePass.u_hasAnimations = getUniform(prePass.shader.id, "u_hasAnimations", errorReporter);
  29860. prePass.u_jointTransforms = getStorageBlockIndex(prePass.shader.id, "u_jointTransforms", errorReporter);
  29861. glShaderStorageBlockBinding(prePass.shader.id, prePass.u_jointTransforms, internal::JointsTransformBlockBinding); //todo define or enums for this
  29862. pointShadowShader.shader.loadShaderProgramFromFile("shaders/shadows/pointShadow.vert",
  29863. "shaders/shadows/pointShadow.geom", "shaders/shadows/pointShadow.frag", errorReporter, fileOpener);
  29864. pointShadowShader.u_albedoSampler = getUniform(pointShadowShader.shader.id, "u_albedoSampler", errorReporter);
  29865. pointShadowShader.u_farPlane = getUniform(pointShadowShader.shader.id, "u_farPlane", errorReporter);
  29866. pointShadowShader.u_hasTexture = getUniform(pointShadowShader.shader.id, "u_hasTexture", errorReporter);
  29867. pointShadowShader.u_lightPos = getUniform(pointShadowShader.shader.id, "u_lightPos", errorReporter);
  29868. pointShadowShader.u_shadowMatrices = getUniform(pointShadowShader.shader.id, "u_shadowMatrices", errorReporter);
  29869. pointShadowShader.u_transform = getUniform(pointShadowShader.shader.id, "u_transform", errorReporter);
  29870. pointShadowShader.u_lightIndex = getUniform(pointShadowShader.shader.id, "u_lightIndex", errorReporter);
  29871. pointShadowShader.u_hasAnimations = getUniform(pointShadowShader.shader.id, "u_hasAnimations", errorReporter);
  29872. pointShadowShader.u_jointTransforms = getStorageBlockIndex(pointShadowShader.shader.id, "u_jointTransforms", errorReporter);
  29873. glShaderStorageBlockBinding(pointShadowShader.shader.id, pointShadowShader.u_jointTransforms, internal::JointsTransformBlockBinding); //todo define or enums for this
  29874. geometryPassShader.loadShaderProgramFromFile("shaders/deferred/geometryPass.vert",
  29875. "shaders/deferred/geometryPass.frag", errorReporter, fileOpener);
  29876. //geometryPassShader.bind();
  29877. u_transform = getUniform(geometryPassShader.id, "u_transform", errorReporter);
  29878. u_hasAnimations = getUniform(geometryPassShader.id, "u_hasAnimations", errorReporter);
  29879. u_modelTransform = getUniform(geometryPassShader.id, "u_modelTransform", errorReporter);
  29880. u_motelViewTransform = getUniform(geometryPassShader.id, "u_motelViewTransform", errorReporter);
  29881. //normalShaderLightposLocation = getUniform(shader.id, "u_lightPosition", errorReporter);
  29882. normalMapSamplerLocation = getUniform(geometryPassShader.id, "u_normalSampler", errorReporter);
  29883. //eyePositionLocation = getUniform(shader.id, "u_eyePosition", errorReporter);
  29884. //skyBoxSamplerLocation = getUniform(textureSamplerLocation.id, "u_skybox", errorReporter);
  29885. //gamaLocation = getUniform(shader.id, "u_gama", errorReporter);
  29886. //pointLightCountLocation = getUniform(shader.id, "u_pointLightCount", errorReporter);
  29887. materialIndexLocation = getUniform(geometryPassShader.id, "u_materialIndex", errorReporter);
  29888. //pointLightBufferLocation = getUniform(shader.id, "u_pointLights", errorReporter);
  29889. materialBlockLocation = getStorageBlockIndex(geometryPassShader.id, "u_material", errorReporter);
  29890. glShaderStorageBlockBinding(geometryPassShader.id, materialBlockLocation, internal::MaterialBlockBinding);
  29891. glGenBuffers(1, &materialBlockBuffer);
  29892. glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialBlockBuffer);
  29893. u_jointTransforms = getStorageBlockIndex(geometryPassShader.id, "u_jointTransforms", errorReporter);
  29894. glShaderStorageBlockBinding(geometryPassShader.id, u_jointTransforms, internal::JointsTransformBlockBinding); //todo define or enums for this
  29895. lightingPassShader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/deferred/lightingPass.frag",
  29896. errorReporter, fileOpener);
  29897. lightingPassShader.bind();
  29898. light_u_normals = getUniform(lightingPassShader.id, "u_normals", errorReporter);
  29899. light_u_skyboxFiltered = getUniform(lightingPassShader.id, "u_skyboxFiltered", errorReporter);
  29900. light_u_eyePosition = getUniform(lightingPassShader.id, "u_eyePosition", errorReporter);
  29901. light_u_pointLightCount = getUniform(lightingPassShader.id, "u_pointLightCount", errorReporter);
  29902. light_u_directionalLightCount = getUniform(lightingPassShader.id, "u_directionalLightCount", errorReporter);
  29903. light_u_spotLightCount = getUniform(lightingPassShader.id, "u_spotLightCount", errorReporter);
  29904. light_u_skyboxIradiance = getUniform(lightingPassShader.id, "u_skyboxIradiance", errorReporter);
  29905. light_u_brdfTexture = getUniform(lightingPassShader.id, "u_brdfTexture", errorReporter);
  29906. light_u_cascades = getUniform(lightingPassShader.id, "u_cascades", errorReporter);
  29907. light_u_spotShadows = getUniform(lightingPassShader.id, "u_spotShadows", errorReporter);
  29908. light_u_pointShadows = getUniform(lightingPassShader.id, "u_pointShadows", errorReporter);
  29909. light_u_materialIndex = getUniform(lightingPassShader.id, "u_materialIndex", errorReporter);
  29910. light_u_textureUV = getUniform(lightingPassShader.id, "u_textureUV", errorReporter);
  29911. light_u_textureDerivates = getUniform(lightingPassShader.id, "u_textureDerivates", errorReporter);
  29912. light_u_transparentPass = getUniform(lightingPassShader.id, "u_transparentPass", errorReporter);
  29913. light_u_lastTexture = getUniform(lightingPassShader.id, "u_lastFrameTexture", errorReporter);
  29914. light_u_hasLastFrameTexture = getUniform(lightingPassShader.id, "u_hasLastFrameTexture", errorReporter);
  29915. light_u_cameraProjection = getUniform(lightingPassShader.id, "u_cameraProjection", errorReporter);
  29916. light_u_positionViewSpace = getUniform(lightingPassShader.id, "u_positionViewSpace", errorReporter);
  29917. light_u_view = getUniform(lightingPassShader.id, "u_view", errorReporter);
  29918. light_u_inverseView = getUniform(lightingPassShader.id, "u_inverseView", errorReporter);
  29919. light_materialBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_material", errorReporter);
  29920. glShaderStorageBlockBinding(lightingPassShader.id, light_materialBlockLocation, internal::MaterialBlockBinding);
  29921. #pragma region uniform buffer
  29922. lightPassShaderData.u_lightPassData = glGetUniformBlockIndex(lightingPassShader.id, "u_lightPassData");
  29923. glGenBuffers(1, &lightPassShaderData.lightPassDataBlockBuffer);
  29924. glBindBuffer(GL_UNIFORM_BUFFER, lightPassShaderData.lightPassDataBlockBuffer);
  29925. glBufferData(GL_UNIFORM_BUFFER, sizeof(LightPassData), &lightPassUniformBlockCpuData, GL_DYNAMIC_DRAW);
  29926. glUniformBlockBinding(lightingPassShader.id, lightPassShaderData.u_lightPassData, internal::LightPassDataBlockBinding);
  29927. glBindBufferBase(GL_UNIFORM_BUFFER, internal::LightPassDataBlockBinding, lightPassShaderData.lightPassDataBlockBuffer);
  29928. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  29929. #pragma endregion
  29930. #pragma region block buffers
  29931. pointLightsBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_pointLights", errorReporter);
  29932. glShaderStorageBlockBinding(lightingPassShader.id, pointLightsBlockLocation, internal::PointLightsBlockBinding);
  29933. glGenBuffers(1, &pointLightsBlockBuffer);
  29934. glBindBuffer(GL_SHADER_STORAGE_BUFFER, pointLightsBlockBuffer);
  29935. glBufferData(GL_SHADER_STORAGE_BUFFER, 0, nullptr, GL_STREAM_DRAW);
  29936. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::PointLightsBlockBinding, pointLightsBlockBuffer);
  29937. directionalLightsBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_directionalLights", errorReporter);
  29938. glShaderStorageBlockBinding(lightingPassShader.id, directionalLightsBlockLocation, internal::DirectionalLightsBlockBinding);
  29939. glGenBuffers(1, &directionalLightsBlockBuffer);
  29940. glBindBuffer(GL_SHADER_STORAGE_BUFFER, directionalLightsBlockBuffer);
  29941. glBufferData(GL_SHADER_STORAGE_BUFFER, 0, nullptr, GL_STREAM_DRAW);
  29942. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::DirectionalLightsBlockBinding, directionalLightsBlockBuffer);
  29943. spotLightsBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_spotLights", errorReporter);
  29944. glShaderStorageBlockBinding(lightingPassShader.id, spotLightsBlockLocation, internal::SpotLightsBlockBinding);
  29945. glGenBuffers(1, &spotLightsBlockBuffer);
  29946. glBindBuffer(GL_SHADER_STORAGE_BUFFER, spotLightsBlockBuffer);
  29947. glBufferData(GL_SHADER_STORAGE_BUFFER, 0, nullptr, GL_STREAM_DRAW);
  29948. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::SpotLightsBlockBinding, spotLightsBlockBuffer);
  29949. #pragma endregion
  29950. glGenVertexArrays(1, &quadDrawer.quadVAO);
  29951. glBindVertexArray(quadDrawer.quadVAO);
  29952. glGenBuffers(1, &quadDrawer.quadBuffer);
  29953. glBindBuffer(GL_ARRAY_BUFFER, quadDrawer.quadBuffer);
  29954. float quadVertices[] = {
  29955. // positions // texture Coords
  29956. -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  29957. -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
  29958. 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
  29959. 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
  29960. };
  29961. // setup plane VAO
  29962. glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
  29963. glEnableVertexAttribArray(0);
  29964. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
  29965. glEnableVertexAttribArray(1);
  29966. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
  29967. glBindVertexArray(0);
  29968. return error;
  29969. }
  29970. void LightShader::getSubroutines(ErrorReporter &errorReporter)
  29971. {
  29972. normalSubroutine_noMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  29973. "noNormalMapped", errorReporter);
  29974. normalSubroutine_normalMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  29975. "normalMapped", errorReporter);
  29976. //
  29977. normalSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
  29978. "getNormalMapFunc", errorReporter);
  29979. }
  29980. void LightShader::clear()
  29981. {
  29982. brdfTexture.clear();
  29983. prePass.shader.clear();
  29984. pointShadowShader.shader.clear();
  29985. geometryPassShader.clear();
  29986. glDeleteBuffers(1, &materialBlockBuffer);
  29987. lightingPassShader.clear();
  29988. glDeleteBuffers(1, &lightPassShaderData.lightPassDataBlockBuffer);
  29989. glDeleteBuffers(1, &pointLightsBlockBuffer);
  29990. glDeleteBuffers(1, &directionalLightsBlockBuffer);
  29991. glDeleteBuffers(1, &spotLightsBlockBuffer);
  29992. glDeleteVertexArrays(1, &quadDrawer.quadVAO);
  29993. glDeleteBuffers(1, &quadDrawer.quadBuffer);
  29994. }
  29995. };
  29996. #pragma endregion
  29997. ////////////////////////////////////////////////
  29998. //Camera.cpp
  29999. ////////////////////////////////////////////////
  30000. #pragma region Camera
  30001. #define GLM_ENABLE_EXPERIMENTAL
  30002. #include <glm/gtc/matrix_transform.hpp>
  30003. #include <glm/gtc/type_ptr.hpp>
  30004. #include <glm/mat3x3.hpp>
  30005. #include <glm/gtx/transform.hpp>
  30006. namespace gl3d
  30007. {
  30008. glm::mat4x4 Camera::getProjectionMatrix()
  30009. {
  30010. auto mat = glm::perspective(this->fovRadians, this->aspectRatio, this->closePlane,
  30011. this->farPlane);
  30012. return mat;
  30013. }
  30014. glm::mat4x4 Camera::getWorldToViewMatrix()
  30015. {
  30016. glm::vec3 lookingAt = this->position;
  30017. lookingAt += viewDirection;
  30018. auto mat = glm::lookAt(this->position, lookingAt, this->up);
  30019. return mat;
  30020. }
  30021. void Camera::rotateCamera(const glm::vec2 delta)
  30022. {
  30023. glm::vec3 rotateYaxe = glm::cross(viewDirection, up);
  30024. viewDirection = glm::mat3(glm::rotate(delta.x, up)) * viewDirection;
  30025. if (delta.y < 0)
  30026. { //down
  30027. if (viewDirection.y < -0.99)
  30028. goto noMove;
  30029. }
  30030. else
  30031. { //up
  30032. if (viewDirection.y > 0.99)
  30033. goto noMove;
  30034. }
  30035. viewDirection = glm::mat3(glm::rotate(delta.y, rotateYaxe)) * viewDirection;
  30036. noMove:
  30037. viewDirection = glm::normalize(viewDirection);
  30038. }
  30039. void generateTangentSpace(glm::vec3 v, glm::vec3& outUp, glm::vec3& outRight)
  30040. {
  30041. glm::vec3 up(0, 1, 0);
  30042. if (v == up)
  30043. {
  30044. outRight = glm::vec3(1, 0, 0);
  30045. }
  30046. else
  30047. {
  30048. outRight = normalize(glm::cross(v, up));
  30049. }
  30050. outUp = normalize(cross(outRight, v));
  30051. }
  30052. //https://www.youtube.com/watch?v=lUo7s-i9Gy4&ab_channel=OREONENGINE
  30053. void computeFrustumDimensions(
  30054. glm::vec3 position, glm::vec3 viewDirection,
  30055. float fovRadians, float aspectRatio, float nearPlane, float farPlane,
  30056. glm::vec2& nearDimensions, glm::vec2& farDimensions, glm::vec3& centerNear, glm::vec3& centerFar)
  30057. {
  30058. float tanFov2 = tan(fovRadians) * 2;
  30059. nearDimensions.y = tanFov2 * nearPlane; //hNear
  30060. nearDimensions.x = nearDimensions.y * aspectRatio; //wNear
  30061. farDimensions.y = tanFov2 * farPlane; //hNear
  30062. farDimensions.x = farDimensions.y * aspectRatio; //wNear
  30063. centerNear = position + viewDirection * farPlane;
  30064. centerFar = position + viewDirection * farPlane;
  30065. }
  30066. //https://www.youtube.com/watch?v=lUo7s-i9Gy4&ab_channel=OREONENGINE
  30067. void computeFrustumSplitCorners(glm::vec3 directionVector,
  30068. glm::vec2 nearDimensions, glm::vec2 farDimensions, glm::vec3 centerNear, glm::vec3 centerFar,
  30069. glm::vec3& nearTopLeft, glm::vec3& nearTopRight, glm::vec3& nearBottomLeft, glm::vec3& nearBottomRight,
  30070. glm::vec3& farTopLeft, glm::vec3& farTopRight, glm::vec3& farBottomLeft, glm::vec3& farBottomRight)
  30071. {
  30072. glm::vec3 rVector = {};
  30073. glm::vec3 upVectpr = {};
  30074. generateTangentSpace(directionVector, upVectpr, rVector);
  30075. nearTopLeft = centerNear + upVectpr * nearDimensions.y / 2.f - rVector * nearDimensions.x / 2.f;
  30076. nearTopRight = centerNear + upVectpr * nearDimensions.y / 2.f + rVector * nearDimensions.x / 2.f;
  30077. nearBottomLeft = centerNear - upVectpr * nearDimensions.y / 2.f - rVector * nearDimensions.x / 2.f;
  30078. nearBottomRight = centerNear - upVectpr * nearDimensions.y / 2.f + rVector * nearDimensions.x / 2.f;
  30079. farTopLeft = centerNear + upVectpr * farDimensions.y / 2.f - rVector * farDimensions.x / 2.f;
  30080. farTopRight = centerNear + upVectpr * farDimensions.y / 2.f + rVector * farDimensions.x / 2.f;
  30081. farBottomLeft = centerNear - upVectpr * farDimensions.y / 2.f - rVector * farDimensions.x / 2.f;
  30082. farBottomRight = centerNear - upVectpr * farDimensions.y / 2.f + rVector * farDimensions.x / 2.f;
  30083. }
  30084. //radians
  30085. glm::vec3 fromAnglesToDirection(float zenith, float azimuth)
  30086. {
  30087. glm::vec4 vec(0, 1, 0, 0);
  30088. auto zenithRotate = glm::rotate(-zenith, glm::vec3( 1.f,0.f,0.f ));
  30089. vec = zenithRotate * vec;
  30090. auto azimuthRotate = glm::rotate(-azimuth, glm::vec3(0.f, 1.f, 0.f));
  30091. vec = azimuthRotate * vec;
  30092. return glm::normalize(glm::vec3(vec));
  30093. }
  30094. glm::vec2 fromDirectionToAngles(glm::vec3 direction)
  30095. {
  30096. if (direction == glm::vec3(0, 1, 0))
  30097. {
  30098. return glm::vec2(0, 0);
  30099. }
  30100. else
  30101. {
  30102. glm::vec3 zenith(0, 1, 0);
  30103. float zenithCos = glm::dot(zenith, direction);
  30104. float zenithAngle = std::acos(zenithCos);
  30105. glm::vec3 north(0, 0, -1);
  30106. glm::vec3 projectedVector(direction.x, 0, direction.z);
  30107. projectedVector = glm::normalize(projectedVector);
  30108. float azmuthCos = glm::dot(north, projectedVector);
  30109. float azmuthAngle = std::acos(azmuthCos);
  30110. return glm::vec2(zenithAngle, azmuthAngle);
  30111. }
  30112. }
  30113. void Camera::moveFPS(glm::vec3 direction)
  30114. {
  30115. viewDirection = glm::normalize(viewDirection);
  30116. //forward
  30117. float forward = -direction.z;
  30118. float leftRight = direction.x;
  30119. float upDown = direction.y;
  30120. glm::vec3 move = {};
  30121. move += up * upDown;
  30122. move += glm::normalize(glm::cross(viewDirection, up)) * leftRight;
  30123. move += viewDirection * forward;
  30124. this->position += move;
  30125. }
  30126. };
  30127. #pragma endregion
  30128. ////////////////////////////////////////////////
  30129. //GraphicModel.cpp
  30130. ////////////////////////////////////////////////
  30131. #pragma region GraphicModel
  30132. #include <algorithm>
  30133. #include "glm/gtx/matrix_decompose.hpp"
  30134. #include "glm/gtx/euler_angles.hpp"
  30135. namespace gl3d
  30136. {
  30137. void DebugGraphicModel::loadFromComputedData(size_t vertexSize, const float * vercies, size_t indexSize,
  30138. const unsigned int * indexes, bool noTexture)
  30139. {
  30140. gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
  30141. if (indexSize % 3 != 0)return;
  30142. glGenVertexArrays(1, &vertexArray);
  30143. glBindVertexArray(vertexArray);
  30144. glGenBuffers(1, &vertexBuffer);
  30145. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  30146. glBufferData(GL_ARRAY_BUFFER, vertexSize, vercies, GL_STATIC_DRAW);
  30147. if(noTexture)
  30148. {
  30149. glEnableVertexAttribArray(0);
  30150. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
  30151. glEnableVertexAttribArray(1);
  30152. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
  30153. }else
  30154. {
  30155. glEnableVertexAttribArray(0);
  30156. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  30157. glEnableVertexAttribArray(1);
  30158. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
  30159. glEnableVertexAttribArray(2);
  30160. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
  30161. }
  30162. if (indexSize && indexes)
  30163. {
  30164. glGenBuffers(1, &indexBuffer);
  30165. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  30166. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
  30167. primitiveCount = indexSize / sizeof(*indexes);
  30168. }
  30169. else
  30170. {
  30171. primitiveCount = vertexSize / sizeof(float);
  30172. }
  30173. glBindVertexArray(0);
  30174. }
  30175. void DebugGraphicModel::clear()
  30176. {
  30177. glDeleteBuffers(1, &vertexBuffer);
  30178. glDeleteBuffers(1, &indexBuffer);
  30179. glDeleteVertexArrays(1, &vertexArray);
  30180. vertexBuffer = 0;
  30181. indexBuffer = 0;
  30182. primitiveCount = 0;
  30183. vertexArray = 0;
  30184. }
  30185. void DebugGraphicModel::draw()
  30186. {
  30187. glBindVertexArray(vertexArray);
  30188. //glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  30189. //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
  30190. //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)(3 * sizeof(float)));
  30191. if (indexBuffer)
  30192. {
  30193. glDrawElements(GL_TRIANGLES, primitiveCount, GL_UNSIGNED_INT, 0);
  30194. }
  30195. else
  30196. {
  30197. glDrawArrays(GL_TRIANGLES, 0, primitiveCount);
  30198. }
  30199. glBindVertexArray(0);
  30200. }
  30201. glm::mat4 DebugGraphicModel::getTransformMatrix()
  30202. {
  30203. return gl3d::getTransformMatrix(position, rotation, scale);
  30204. }
  30205. void LoadedModelData::load(const char *file, ErrorReporter &errorReporter, FileOpener &fileOpener, float scale)
  30206. {
  30207. stbi_set_flip_vertically_on_load(true); //gltf and obj files hold textures flipped diferently...
  30208. bool shouldFlipUVs = 0;
  30209. loader.LoadFile(file, errorReporter, fileOpener, &shouldFlipUVs);
  30210. //parse path
  30211. path = file;
  30212. while (!path.empty() &&
  30213. *(path.end() - 1) != '\\' &&
  30214. *(path.end() - 1) != '/'
  30215. )
  30216. {
  30217. path.pop_back();
  30218. }
  30219. for (auto &i : loader.LoadedMeshes)
  30220. {
  30221. if (shouldFlipUVs)
  30222. {
  30223. for (auto &j : i.Vertices)
  30224. {
  30225. j.Position.X *= scale;
  30226. j.Position.Y *= scale;
  30227. j.Position.Z *= scale;
  30228. j.TextureCoordinate.Y = 1.f - j.TextureCoordinate.Y;
  30229. }
  30230. for (auto &j : i.VerticesAnimations)
  30231. {
  30232. j.Position.X *= scale;
  30233. j.Position.Y *= scale;
  30234. j.Position.Z *= scale;
  30235. j.TextureCoordinate.Y = 1.f - j.TextureCoordinate.Y;
  30236. }
  30237. }
  30238. else
  30239. {
  30240. for (auto &j : i.Vertices)
  30241. {
  30242. j.Position.X *= scale;
  30243. j.Position.Y *= scale;
  30244. j.Position.Z *= scale;
  30245. }
  30246. for (auto &j : i.VerticesAnimations)
  30247. {
  30248. j.Position.X *= scale;
  30249. j.Position.Y *= scale;
  30250. j.Position.Z *= scale;
  30251. }
  30252. }
  30253. }
  30254. for (auto &i : loader.joints)
  30255. {
  30256. //i.scale *= scale;
  30257. //i.trans *= scale;
  30258. }
  30259. for (auto &i : loader.animations)
  30260. {
  30261. for (auto &k1 : i.keyFramesTrans)
  30262. {
  30263. for (auto &k2 : k1)
  30264. {
  30265. //k2.translation *= scale;
  30266. }
  30267. }
  30268. for (auto &k1 : i.keyFramesScale)
  30269. {
  30270. for (auto &k2 : k1)
  30271. {
  30272. // k2.scale *= scale;
  30273. }
  30274. }
  30275. }
  30276. //errorReporter.currentErrorCallback(std::string("Loaded: ") + std::to_string(loader.LoadedMeshes.size()) + " meshes");
  30277. }
  30278. float skyboxVertices[] = {
  30279. // positions
  30280. -1.0f, 1.0f, -1.0f,
  30281. -1.0f, -1.0f, -1.0f,
  30282. 1.0f, -1.0f, -1.0f,
  30283. 1.0f, -1.0f, -1.0f,
  30284. 1.0f, 1.0f, -1.0f,
  30285. -1.0f, 1.0f, -1.0f,
  30286. -1.0f, -1.0f, 1.0f,
  30287. -1.0f, -1.0f, -1.0f,
  30288. -1.0f, 1.0f, -1.0f,
  30289. -1.0f, 1.0f, -1.0f,
  30290. -1.0f, 1.0f, 1.0f,
  30291. -1.0f, -1.0f, 1.0f,
  30292. 1.0f, -1.0f, -1.0f,
  30293. 1.0f, -1.0f, 1.0f,
  30294. 1.0f, 1.0f, 1.0f,
  30295. 1.0f, 1.0f, 1.0f,
  30296. 1.0f, 1.0f, -1.0f,
  30297. 1.0f, -1.0f, -1.0f,
  30298. -1.0f, -1.0f, 1.0f,
  30299. -1.0f, 1.0f, 1.0f,
  30300. 1.0f, 1.0f, 1.0f,
  30301. 1.0f, 1.0f, 1.0f,
  30302. 1.0f, -1.0f, 1.0f,
  30303. -1.0f, -1.0f, 1.0f,
  30304. -1.0f, 1.0f, -1.0f,
  30305. 1.0f, 1.0f, -1.0f,
  30306. 1.0f, 1.0f, 1.0f,
  30307. 1.0f, 1.0f, 1.0f,
  30308. -1.0f, 1.0f, 1.0f,
  30309. -1.0f, 1.0f, -1.0f,
  30310. -1.0f, -1.0f, -1.0f,
  30311. -1.0f, -1.0f, 1.0f,
  30312. 1.0f, -1.0f, -1.0f,
  30313. 1.0f, -1.0f, -1.0f,
  30314. -1.0f, -1.0f, 1.0f,
  30315. 1.0f, -1.0f, 1.0f
  30316. };
  30317. static glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
  30318. static glm::mat4 captureViews[] =
  30319. {
  30320. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
  30321. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
  30322. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
  30323. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
  30324. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
  30325. glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
  30326. };
  30327. //todo optimize
  30328. glm::mat4 getTransformMatrix(glm::vec3 position, glm::vec3 rotation, glm::vec3 scale)
  30329. {
  30330. auto s = glm::scale(scale);
  30331. //auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
  30332. // glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
  30333. // glm::rotate(rotation.z, glm::vec3(0, 0, 1));
  30334. auto r = glm::eulerAngleYXZ(rotation.y, rotation.x, rotation.z);
  30335. auto t = glm::translate(position);
  30336. return t * r * s;
  30337. }
  30338. glm::mat4 getTransformMatrix(const Transform& t)
  30339. {
  30340. return getTransformMatrix(t.position, t.rotation, t.scale);
  30341. }
  30342. glm::mat4 Transform::getTransformMatrix()
  30343. {
  30344. return gl3d::getTransformMatrix(*this);
  30345. }
  30346. //https://stackoverflow.com/questions/1996957/conversion-euler-to-matrix-and-matrix-to-euler
  30347. void getRotation(const glm::mat4 &mat, float& Yaw, float& Pitch, float& Roll)
  30348. {
  30349. Pitch = asinf(-mat[2][1]); // Pitch
  30350. if (abs(cosf(Pitch)) > 0.0001) // Not at poles
  30351. {
  30352. Yaw = atan2f(mat[2][0], mat[2][2]); // Yaw
  30353. Roll = atan2f(mat[0][1], mat[1][1]); // Roll
  30354. }
  30355. else
  30356. {
  30357. Yaw = 0.0f; // Yaw
  30358. Roll = atan2f(-mat[1][0], mat[0][0]); // Roll
  30359. }
  30360. }
  30361. void Transform::setFromMatrix(const glm::mat4& mat)
  30362. {
  30363. glm::quat rot = {};
  30364. glm::vec3 notUsed = {};
  30365. glm::vec4 notUsed2 = {};
  30366. glm::decompose(mat, scale, rot, position, notUsed, notUsed2);
  30367. //rot = glm::conjugate(rot);
  30368. //scale = glm::normalize(scale);
  30369. //rotation = glm::eulerAngles(rot);
  30370. //rotation.z *= -1;
  30371. //if (abs(rotation.x) < 0.01)
  30372. //{
  30373. // rotation.x = 0;
  30374. //}
  30375. //if (abs(rotation.y) < 0.01)
  30376. //{
  30377. // rotation.y = 0;
  30378. //}
  30379. //if (abs(rotation.z) < 0.01)
  30380. //{
  30381. // rotation.z = 0;
  30382. //}
  30383. //std::swap(rotation.x, rotation.z);
  30384. getRotation(mat, rotation.y, rotation.x, rotation.z);
  30385. //rotation.y = -rotation.y;
  30386. //rotation.x = -rotation.x;
  30387. //rotation = -rotation;
  30388. }
  30389. void ModelData::clear(Renderer3D& renderer)
  30390. {
  30391. for (auto m : models)
  30392. {
  30393. if (m.ownMaterial)
  30394. {
  30395. renderer.deleteMaterial(m.material);
  30396. }
  30397. }
  30398. internalClear();
  30399. }
  30400. void ModelData::internalClear()
  30401. {
  30402. for (auto &i : models)
  30403. {
  30404. i.clear();
  30405. }
  30406. for (auto &i : subModelsNames)
  30407. {
  30408. delete[] i;
  30409. }
  30410. subModelsNames.clear();
  30411. createdMaterials.clear();
  30412. models.clear();
  30413. }
  30414. void GraphicModel::loadFromComputedData(size_t vertexSize, const float *vertices, size_t indexSize,
  30415. const unsigned int *indexes, bool noTexture, bool hasAnimationData,
  30416. std::vector<Animation> animation, std::vector<Joint> joints)
  30417. {
  30418. /*
  30419. position vec3
  30420. normals vec3
  30421. (optional) texcoords vec2
  30422. (optional) joints id ivec4
  30423. (optional) joints weights vec4
  30424. */
  30425. //todo check has texture data.
  30426. #pragma region validate
  30427. if (!vertexSize) { return; }
  30428. gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
  30429. if (indexSize % 3 != 0)return;
  30430. if (hasAnimationData)
  30431. {
  30432. if (noTexture)
  30433. {
  30434. gl3dAssertComment(vertexSize % (sizeof(float) * 14) == 0,
  30435. "VertexSize count must be multiple of 14 * sizeof(float)\nwhen not using texture data\nand using animation data.");
  30436. if (vertexSize % (sizeof(float) * 14) != 0)return;
  30437. }
  30438. else
  30439. {
  30440. gl3dAssertComment(vertexSize % (sizeof(float) * 16) == 0,
  30441. "VertexSize count must be multiple of 16 * sizeof(float)\nwhen using texture data\nand using animation data.");
  30442. if (vertexSize % (sizeof(float) * 16) != 0)return;
  30443. }
  30444. }
  30445. else
  30446. {
  30447. if (noTexture)
  30448. {
  30449. gl3dAssertComment(vertexSize % (sizeof(float) * 6) == 0,
  30450. "VertexSize count must be multiple of 6 * sizeof(float)\nwhen not using texture data\nand no animation data.");
  30451. if (vertexSize % (sizeof(float) * 6) != 0)return;
  30452. }
  30453. else
  30454. {
  30455. gl3dAssertComment(vertexSize % (sizeof(float) * 8) == 0,
  30456. "VertexSize count must be multiple of 8 * sizeof(float)\nwhen using texture data\nand no animation data.");
  30457. if (vertexSize % (sizeof(float) * 8) != 0)return;
  30458. }
  30459. }
  30460. #pragma endregion
  30461. #pragma region determine object boundaries
  30462. if (noTexture)
  30463. {
  30464. float x = vertices[0];
  30465. float y = vertices[1];
  30466. float z = vertices[2];
  30467. minBoundary = glm::vec3(x, y, z);
  30468. maxBoundary = glm::vec3(x, y, z);
  30469. for (int i = 0; i < vertexSize / (sizeof(float)*6); i++)
  30470. {
  30471. float x = vertices[i*6+0];
  30472. float y = vertices[i*6+1];
  30473. float z = vertices[i*6+2];
  30474. if (x < minBoundary.x) { minBoundary.x = x; }
  30475. if (y < minBoundary.y) { minBoundary.y = y; }
  30476. if (z < minBoundary.z) { minBoundary.z = z; }
  30477. if (x > maxBoundary.x) { maxBoundary.x = x; }
  30478. if (y > maxBoundary.y) { maxBoundary.y = y; }
  30479. if (z > maxBoundary.z) { maxBoundary.z = z; }
  30480. }
  30481. }
  30482. else
  30483. {
  30484. float x = vertices[0];
  30485. float y = vertices[1];
  30486. float z = vertices[2];
  30487. minBoundary = glm::vec3(x, y, z);
  30488. maxBoundary = glm::vec3(x, y, z);
  30489. for (int i = 0; i < vertexSize / (sizeof(float) * 8); i++)
  30490. {
  30491. float x = vertices[i * 8 + 0];
  30492. float y = vertices[i * 8 + 1];
  30493. float z = vertices[i * 8 + 2];
  30494. if (x < minBoundary.x) { minBoundary.x = x; }
  30495. if (y < minBoundary.y) { minBoundary.y = y; }
  30496. if (z < minBoundary.z) { minBoundary.z = z; }
  30497. if (x > maxBoundary.x) { maxBoundary.x = x; }
  30498. if (y > maxBoundary.y) { maxBoundary.y = y; }
  30499. if (z > maxBoundary.z) { maxBoundary.z = z; }
  30500. }
  30501. }
  30502. #pragma endregion
  30503. glGenVertexArrays(1, &vertexArray);
  30504. glBindVertexArray(vertexArray);
  30505. glGenBuffers(1, &vertexBuffer);
  30506. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  30507. glBufferData(GL_ARRAY_BUFFER, vertexSize, vertices, GL_STATIC_DRAW);
  30508. if (hasAnimationData)
  30509. {
  30510. if (noTexture)
  30511. {
  30512. glEnableVertexAttribArray(0);
  30513. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void *)0);
  30514. glEnableVertexAttribArray(1);
  30515. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void *)(3 * sizeof(float)));
  30516. //skip texture
  30517. glEnableVertexAttribArray(3);
  30518. glVertexAttribIPointer(3, 4, GL_INT, 14 * sizeof(int), (void *)(6 * sizeof(int)));
  30519. glEnableVertexAttribArray(4);
  30520. glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void *)(10 * sizeof(float)));
  30521. }
  30522. else
  30523. {
  30524. glEnableVertexAttribArray(0);
  30525. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)0);
  30526. glEnableVertexAttribArray(1);
  30527. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)(3 * sizeof(float)));
  30528. glEnableVertexAttribArray(2);
  30529. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)(6 * sizeof(float)));
  30530. glEnableVertexAttribArray(3);
  30531. glVertexAttribIPointer(3, 4, GL_INT, 16 * sizeof(int), (void *)(8 * sizeof(int)));
  30532. glEnableVertexAttribArray(4);
  30533. glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)(12 * sizeof(float)));
  30534. }
  30535. }
  30536. else
  30537. {
  30538. //double check this
  30539. if (noTexture)
  30540. {
  30541. glEnableVertexAttribArray(0);
  30542. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
  30543. glEnableVertexAttribArray(1);
  30544. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
  30545. }
  30546. else
  30547. {
  30548. glEnableVertexAttribArray(0);
  30549. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  30550. glEnableVertexAttribArray(1);
  30551. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
  30552. glEnableVertexAttribArray(2);
  30553. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
  30554. }
  30555. }
  30556. if (indexSize && indexes)
  30557. {
  30558. glGenBuffers(1, &indexBuffer);
  30559. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  30560. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
  30561. primitiveCount = indexSize / sizeof(*indexes);
  30562. }
  30563. else
  30564. {
  30565. primitiveCount = vertexSize / sizeof(float);
  30566. }
  30567. glBindVertexArray(0);
  30568. }
  30569. // does not clear owned material
  30570. void GraphicModel::clear()
  30571. {
  30572. glDeleteBuffers(1, &vertexBuffer);
  30573. glDeleteBuffers(1, &indexBuffer);
  30574. glDeleteVertexArrays(1, &vertexArray);
  30575. *this = GraphicModel{};
  30576. }
  30577. void SkyBoxLoaderAndDrawer::createGpuData(ErrorReporter &errorReporter, FileOpener &fileOpener, GLuint frameBuffer)
  30578. {
  30579. normalSkyBox.shader.loadShaderProgramFromFile("shaders/skyBox/skyBox.vert", "shaders/skyBox/skyBox.frag", errorReporter, fileOpener);
  30580. normalSkyBox.samplerUniformLocation = getUniform(normalSkyBox.shader.id, "u_skybox", errorReporter);
  30581. normalSkyBox.modelViewUniformLocation = getUniform(normalSkyBox.shader.id, "u_viewProjection", errorReporter);
  30582. normalSkyBox.u_ambient = getUniform(normalSkyBox.shader.id, "u_ambient", errorReporter);
  30583. normalSkyBox.u_skyBoxPresent = getUniform(normalSkyBox.shader.id, "u_skyBoxPresent", errorReporter);
  30584. hdrtoCubeMap.shader.loadShaderProgramFromFile("shaders/skyBox/hdrToCubeMap.vert", "shaders/skyBox/hdrToCubeMap.frag", errorReporter, fileOpener);
  30585. hdrtoCubeMap.u_equirectangularMap = getUniform(hdrtoCubeMap.shader.id, "u_equirectangularMap", errorReporter);
  30586. hdrtoCubeMap.modelViewUniformLocation = getUniform(hdrtoCubeMap.shader.id, "u_viewProjection", errorReporter);
  30587. convolute.shader.loadShaderProgramFromFile("shaders/skyBox/hdrToCubeMap.vert", "shaders/skyBox/convolute.frag", errorReporter, fileOpener);
  30588. convolute.u_environmentMap = getUniform(convolute.shader.id, "u_environmentMap", errorReporter);
  30589. convolute.modelViewUniformLocation = getUniform(convolute.shader.id, "u_viewProjection", errorReporter);
  30590. convolute.u_sampleQuality = getUniform(convolute.shader.id, "u_sampleQuality", errorReporter);
  30591. preFilterSpecular.shader.loadShaderProgramFromFile("shaders/skyBox/hdrToCubeMap.vert", "shaders/skyBox/preFilterSpecular.frag", errorReporter, fileOpener);
  30592. preFilterSpecular.modelViewUniformLocation = getUniform(preFilterSpecular.shader.id, "u_viewProjection", errorReporter);
  30593. preFilterSpecular.u_environmentMap = getUniform(preFilterSpecular.shader.id, "u_environmentMap", errorReporter);
  30594. preFilterSpecular.u_roughness = getUniform(preFilterSpecular.shader.id, "u_roughness", errorReporter);
  30595. preFilterSpecular.u_sampleCount = getUniform(preFilterSpecular.shader.id, "u_sampleCount", errorReporter);
  30596. atmosphericScatteringShader.shader.loadShaderProgramFromFile("shaders/skyBox/hdrToCubeMap.vert",
  30597. "shaders/skyBox/atmosphericScattering.frag", errorReporter, fileOpener);
  30598. atmosphericScatteringShader.u_lightPos = getUniform(atmosphericScatteringShader.shader.id, "u_lightPos", errorReporter);
  30599. atmosphericScatteringShader.u_g = getUniform(atmosphericScatteringShader.shader.id, "u_g", errorReporter);
  30600. atmosphericScatteringShader.u_color1 = getUniform(atmosphericScatteringShader.shader.id, "u_color1", errorReporter);
  30601. atmosphericScatteringShader.u_color2 = getUniform(atmosphericScatteringShader.shader.id, "u_color2", errorReporter);
  30602. atmosphericScatteringShader.u_groundColor = getUniform(atmosphericScatteringShader.shader.id, "u_groundColor", errorReporter);
  30603. atmosphericScatteringShader.u_useGround = getUniform(atmosphericScatteringShader.shader.id, "u_useGround", errorReporter);
  30604. atmosphericScatteringShader.modelViewUniformLocation
  30605. = getUniform(atmosphericScatteringShader.shader.id, "u_viewProjection", errorReporter);
  30606. glGenVertexArrays(1, &vertexArray);
  30607. glBindVertexArray(vertexArray);
  30608. glGenBuffers(1, &vertexBuffer);
  30609. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  30610. glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
  30611. glEnableVertexAttribArray(0);
  30612. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
  30613. glBindVertexArray(0);
  30614. glGenFramebuffers(1, &captureFBO);
  30615. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); //also allocate gpu resources
  30616. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  30617. }
  30618. void SkyBoxLoaderAndDrawer::loadTexture(const char *names[6], SkyBox &skyBox, ErrorReporter &errorReporter, FileOpener &fileOpener,
  30619. GLuint frameBuffer)
  30620. {
  30621. skyBox = {};
  30622. glGenTextures(1, &skyBox.texture);
  30623. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30624. for (unsigned int i = 0; i < 6; i++)
  30625. {
  30626. int w=0, h=0, nrChannels=0;
  30627. unsigned char *data=0;
  30628. stbi_set_flip_vertically_on_load(false);
  30629. bool couldNotOpen = 0;
  30630. auto content = fileOpener.binary(names[i], couldNotOpen);
  30631. if (couldNotOpen)
  30632. {
  30633. errorReporter.callErrorCallback(std::string("Could not open file: ") + names[i]);
  30634. glDeleteTextures(1, &skyBox.texture);
  30635. return;
  30636. }
  30637. data = stbi_load_from_memory((unsigned char*)content.data(), content.size(), &w, &h, &nrChannels, 3);
  30638. if (data)
  30639. {
  30640. glTexImage2D(
  30641. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
  30642. 0, GL_SRGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data
  30643. );
  30644. stbi_image_free(data);
  30645. }
  30646. else
  30647. {
  30648. errorReporter.callErrorCallback(std::string("err loading ") + names[i]);
  30649. glDeleteTextures(1, &skyBox.texture);
  30650. return;
  30651. }
  30652. }
  30653. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30654. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  30655. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30656. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30657. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30658. createConvolutedAndPrefilteredTextureData(skyBox, frameBuffer);
  30659. }
  30660. void SkyBoxLoaderAndDrawer::loadTexture(const char *name, SkyBox &skyBox, ErrorReporter &errorReporter, FileOpener &fileOpener,
  30661. GLuint frameBuffer, int format)
  30662. {
  30663. skyBox = {};
  30664. int width=0, height=0, nrChannels=0;
  30665. unsigned char *data=0;
  30666. stbi_set_flip_vertically_on_load(false);
  30667. bool couldNotOpen = 0;
  30668. auto content = fileOpener.binary(name, couldNotOpen);
  30669. if (couldNotOpen)
  30670. {
  30671. errorReporter.callErrorCallback(std::string("Could not open file: ") + name);
  30672. glDeleteTextures(1, &skyBox.texture);
  30673. return;
  30674. }
  30675. data = stbi_load_from_memory((unsigned char *)content.data(), content.size(), &width, &height, &nrChannels, 3);
  30676. if (!data) { errorReporter.callErrorCallback(std::string("err loading ") + name); return; }
  30677. glGenTextures(1, &skyBox.texture);
  30678. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30679. //right
  30680. //left
  30681. //top
  30682. //bottom
  30683. //front//?
  30684. //back //?
  30685. auto getPixel = [&](int x, int y, unsigned char *data)
  30686. {
  30687. return data + 3 * (x + y * width);
  30688. };
  30689. glm::ivec2 paddings[6];
  30690. glm::ivec2 immageRatio = {};
  30691. int flipX[6] = {};
  30692. int flipY[6] = {};
  30693. if (format == 0)
  30694. {
  30695. immageRatio = { 4, 3 };
  30696. glm::ivec2 paddingscopy[6] =
  30697. {
  30698. { (width / 4) * 2, (height / 3) * 1, },
  30699. { (width / 4) * 0, (height / 3) * 1, },
  30700. { (width / 4) * 1, (height / 3) * 0, },
  30701. { (width / 4) * 1, (height / 3) * 2, },
  30702. { (width / 4) * 1, (height / 3) * 1, },
  30703. { (width / 4) * 3, (height / 3) * 1, },
  30704. };
  30705. memcpy(paddings, paddingscopy, sizeof(paddings));
  30706. }
  30707. else if (format == 1)
  30708. {
  30709. immageRatio = { 3, 4 };
  30710. glm::ivec2 paddingscopy[6] =
  30711. {
  30712. { (width / 3) * 2, (height / 4) * 1, },
  30713. { (width / 3) * 0, (height / 4) * 1, },
  30714. { (width / 3) * 1, (height / 4) * 0, },
  30715. { (width / 3) * 1, (height / 4) * 2, },
  30716. { (width / 3) * 1, (height / 4) * 1, },
  30717. { (width / 3) * 1, (height / 4) * 3, },
  30718. };
  30719. memcpy(paddings, paddingscopy, sizeof(paddings));
  30720. flipX[5] = 1;
  30721. flipY[5] = 1;
  30722. }else if(format == 2)
  30723. {
  30724. immageRatio = { 4, 3 };
  30725. glm::ivec2 paddingscopy[6] =
  30726. {
  30727. { (width / 4) * 3, (height / 3) * 1, },
  30728. { (width / 4) * 1, (height / 3) * 1, },
  30729. { (width / 4) * 2, (height / 3) * 0, },
  30730. { (width / 4) * 2, (height / 3) * 2, },
  30731. { (width / 4) * 2, (height / 3) * 1, },
  30732. { (width / 4) * 0, (height / 3) * 1, },
  30733. };
  30734. memcpy(paddings, paddingscopy, sizeof(paddings));
  30735. }else
  30736. {
  30737. gl3dAssertComment(0, "invalid format for texture");
  30738. }
  30739. if (data)
  30740. {
  30741. for (unsigned int i = 0; i < 6; i++)
  30742. {
  30743. unsigned char *extractedData = new unsigned char[3 *
  30744. (width / immageRatio.x) * (height / immageRatio.y)];
  30745. int index = 0;
  30746. int paddingX = paddings[i].x;
  30747. int paddingY = paddings[i].y;
  30748. #pragma region flip
  30749. int jBeg = 0;
  30750. int jAdvance = 1;
  30751. if(flipY[i])
  30752. {
  30753. jBeg = height / immageRatio.y - 1;
  30754. jAdvance = -1;
  30755. }
  30756. int xBeg = 0;
  30757. int xAdvance = 1;
  30758. if (flipX[i])
  30759. {
  30760. xBeg = width / immageRatio.x - 1;
  30761. xAdvance = -1;
  30762. }
  30763. #pragma endregion
  30764. for (int j = jBeg; j < height / immageRatio.y && j >= 0; j+= jAdvance)
  30765. for (int i = xBeg; i < width / immageRatio.x && i >= 0; i+= xAdvance)
  30766. {
  30767. extractedData[index] = *getPixel(i + paddingX, j + paddingY, data);
  30768. extractedData[index + 1] = *(getPixel(i + paddingX, j + paddingY, data) + 1);
  30769. extractedData[index + 2] = *(getPixel(i + paddingX, j + paddingY, data) + 2);
  30770. //extractedData[index] = 100;
  30771. //extractedData[index + 1] = 100;
  30772. //extractedData[index + 2] = 100;
  30773. index += 3;
  30774. }
  30775. glTexImage2D(
  30776. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
  30777. 0, GL_SRGB, width / immageRatio.x, height / immageRatio.y, 0,
  30778. GL_RGB, GL_UNSIGNED_BYTE, extractedData
  30779. );
  30780. delete[] extractedData;
  30781. }
  30782. stbi_image_free(data);
  30783. }
  30784. else
  30785. {
  30786. errorReporter.callErrorCallback(std::string("err loading ") + name);
  30787. }
  30788. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30789. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  30790. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30791. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30792. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30793. createConvolutedAndPrefilteredTextureData(skyBox, frameBuffer);
  30794. }
  30795. void SkyBoxLoaderAndDrawer::loadHDRtexture(const char *name, ErrorReporter &errorReporter,
  30796. FileOpener &fileOpener, SkyBox &skyBox, GLuint frameBuffer)
  30797. {
  30798. skyBox = {};
  30799. int width=0, height=0, nrChannels=0;
  30800. float *data=0;
  30801. stbi_set_flip_vertically_on_load(true);
  30802. bool couldNotOpen = 0;
  30803. auto content = fileOpener.binary(name, couldNotOpen);
  30804. if (couldNotOpen)
  30805. {
  30806. errorReporter.callErrorCallback(std::string("Could not open file: ") + name);
  30807. glDeleteTextures(1, &skyBox.texture);
  30808. return;
  30809. }
  30810. data = stbi_loadf_from_memory((unsigned char *)content.data(), content.size(), &width, &height, &nrChannels, 3);
  30811. if (!data) { errorReporter.callErrorCallback(std::string("err loading ") + name); return; }
  30812. GLuint hdrTexture;
  30813. glGenTextures(1, &hdrTexture);
  30814. glBindTexture(GL_TEXTURE_2D, hdrTexture);
  30815. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data);
  30816. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30817. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30818. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  30819. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30820. stbi_image_free(data);
  30821. //render into the cubemap
  30822. //https://learnopengl.com/PBR/IBL/Diffuse-irradiance
  30823. {
  30824. GLuint captureFBO; //todo cache this
  30825. glGenFramebuffers(1, &captureFBO);
  30826. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
  30827. glGenTextures(1, &skyBox.texture);
  30828. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30829. for (unsigned int i = 0; i < 6; ++i)
  30830. {
  30831. // note that we store each face with 16 bit floating point values
  30832. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F,
  30833. 512, 512, 0, GL_RGB, GL_FLOAT, nullptr);
  30834. }
  30835. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30836. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30837. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30838. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  30839. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30840. //rendering
  30841. {
  30842. hdrtoCubeMap.shader.bind();
  30843. glUniform1i(hdrtoCubeMap.u_equirectangularMap, 0);
  30844. glActiveTexture(GL_TEXTURE0);
  30845. glBindTexture(GL_TEXTURE_2D, hdrTexture);
  30846. glViewport(0, 0, 512, 512);
  30847. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
  30848. glBindVertexArray(vertexArray);
  30849. for (unsigned int i = 0; i < 6; ++i)
  30850. {
  30851. glm::mat4 viewProjMat = captureProjection * captureViews[i];
  30852. glUniformMatrix4fv(hdrtoCubeMap.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  30853. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  30854. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, skyBox.texture, 0);
  30855. glClear(GL_COLOR_BUFFER_BIT);
  30856. glDrawArrays(GL_TRIANGLES, 0, 6 * 6); // renders a 1x1 cube
  30857. }
  30858. glBindVertexArray(0);
  30859. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  30860. }
  30861. glDeleteFramebuffers(1, &captureFBO);
  30862. }
  30863. glDeleteTextures(1, &hdrTexture);
  30864. createConvolutedAndPrefilteredTextureData(skyBox, frameBuffer);
  30865. }
  30866. void SkyBoxLoaderAndDrawer::atmosphericScattering(glm::vec3 sun, glm::vec3 color1, glm::vec3 color2,
  30867. glm::vec3 groundColor, bool useGroundColor, float g,
  30868. SkyBox& skyBox, GLuint frameBuffer)
  30869. {
  30870. skyBox = {};
  30871. constexpr int skyBoxSize = 128;
  30872. //render into the cubemap
  30873. {
  30874. GLuint captureFBO;
  30875. glGenFramebuffers(1, &captureFBO);
  30876. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
  30877. glGenTextures(1, &skyBox.texture);
  30878. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30879. for (unsigned int i = 0; i < 6; ++i)
  30880. {
  30881. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R11F_G11F_B10F,
  30882. skyBoxSize, skyBoxSize, 0, GL_RGB, GL_FLOAT, nullptr);
  30883. }
  30884. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30885. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30886. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30887. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  30888. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30889. //rendering
  30890. {
  30891. atmosphericScatteringShader.shader.bind();
  30892. glUniform3fv(atmosphericScatteringShader.u_lightPos, 1, &sun[0]);
  30893. glUniform1f(atmosphericScatteringShader.u_g, g);
  30894. glUniform3fv(atmosphericScatteringShader.u_color1, 1, &color1[0]);
  30895. glUniform3fv(atmosphericScatteringShader.u_color2, 1, &color2[0]);
  30896. glUniform3fv(atmosphericScatteringShader.u_groundColor, 1, &groundColor[0]);
  30897. glUniform1i(atmosphericScatteringShader.u_useGround, (int)useGroundColor);
  30898. glViewport(0, 0, skyBoxSize, skyBoxSize);
  30899. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
  30900. glBindVertexArray(vertexArray);
  30901. for (unsigned int i = 0; i < 6; ++i)
  30902. {
  30903. glm::mat4 viewProjMat = captureProjection * captureViews[i];
  30904. glUniformMatrix4fv(atmosphericScatteringShader.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  30905. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  30906. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, skyBox.texture, 0);
  30907. glClear(GL_COLOR_BUFFER_BIT);
  30908. glDrawArrays(GL_TRIANGLES, 0, 6 * 6); // renders a 1x1 cube
  30909. }
  30910. glBindVertexArray(0);
  30911. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  30912. }
  30913. glDeleteFramebuffers(1, &captureFBO);
  30914. }
  30915. createConvolutedAndPrefilteredTextureData(skyBox, frameBuffer, 0.02, 64u);
  30916. }
  30917. void SkyBoxLoaderAndDrawer::createConvolutedAndPrefilteredTextureData(SkyBox &skyBox
  30918. , GLuint frameBuffer, float sampleQuality, unsigned int specularSamples)
  30919. {
  30920. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30921. glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  30922. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  30923. GLint viewPort[4] = {};
  30924. glGetIntegerv(GL_VIEWPORT, viewPort);
  30925. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  30926. #pragma region convoluted texturelayout(binding = 4) uniform sampler2D u_roughness;
  30927. glGenTextures(1, &skyBox.convolutedTexture);
  30928. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.convolutedTexture);
  30929. for (unsigned int i = 0; i < 6; ++i)
  30930. {
  30931. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0,
  30932. GL_RGB, GL_FLOAT, nullptr);
  30933. }
  30934. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30935. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30936. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30937. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  30938. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30939. glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
  30940. convolute.shader.bind();
  30941. glUniform1i(convolute.u_environmentMap, 0);
  30942. glUniform1f(convolute.u_sampleQuality, sampleQuality);
  30943. glActiveTexture(GL_TEXTURE0);
  30944. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30945. glViewport(0, 0, 32, 32);
  30946. glBindVertexArray(vertexArray);
  30947. for (unsigned int i = 0; i < 6; ++i)
  30948. {
  30949. glm::mat4 viewProjMat = captureProjection * captureViews[i];
  30950. glUniformMatrix4fv(convolute.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  30951. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  30952. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, skyBox.convolutedTexture, 0);
  30953. glClear(GL_COLOR_BUFFER_BIT);
  30954. glDrawArrays(GL_TRIANGLES, 0, 6 * 6); // renders a 1x1 cube, todo refactor to draw only a face lol
  30955. }
  30956. #pragma endregion
  30957. #pragma region prefiltered map
  30958. constexpr int maxMipMap = 5;
  30959. glGenTextures(1, &skyBox.preFilteredMap);
  30960. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.preFilteredMap);
  30961. for (unsigned int i = 0; i < 6; ++i)
  30962. {
  30963. //todo mabe be able to tweak rezolution
  30964. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 128, 128, 0, GL_RGB, GL_FLOAT, nullptr);
  30965. }
  30966. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  30967. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  30968. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  30969. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  30970. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  30971. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, maxMipMap);
  30972. glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  30973. preFilterSpecular.shader.bind();
  30974. glUniform1i(preFilterSpecular.u_environmentMap, 0);
  30975. glActiveTexture(GL_TEXTURE0);
  30976. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  30977. for (int mip = 0; mip < maxMipMap; mip++)
  30978. {
  30979. unsigned int mipWidth = 128 * std::pow(0.5, mip);
  30980. unsigned int mipHeight = 128 * std::pow(0.5, mip);
  30981. glViewport(0, 0, mipWidth, mipHeight);
  30982. float roughness = (float)mip / (float)(maxMipMap - 1);
  30983. roughness *= roughness;
  30984. glUniform1f(preFilterSpecular.u_roughness, roughness);
  30985. glUniform1ui(preFilterSpecular.u_sampleCount, specularSamples);
  30986. for (int i = 0; i < 6; i++)
  30987. {
  30988. glm::mat4 viewProjMat = captureProjection * captureViews[i];
  30989. glUniformMatrix4fv(preFilterSpecular.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  30990. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  30991. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, skyBox.preFilteredMap, mip);
  30992. glClear(GL_COLOR_BUFFER_BIT);
  30993. glDrawArrays(GL_TRIANGLES, 0, 6 * 6); // renders a 1x1 cube
  30994. }
  30995. }
  30996. #pragma endregion
  30997. glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  30998. glBindVertexArray(0);
  30999. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  31000. glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
  31001. //texture = convolutedTexture; //visualize convolutex texture
  31002. //texture = preFilteredMap;
  31003. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  31004. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  31005. //todo delete mipmaps
  31006. //GLuint newTexture = 0;
  31007. //glGenTextures(1, &newTexture);
  31008. //int w, h;
  31009. //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
  31010. //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
  31011. //glCopyTexImage2D(GL_TEXTURE_CUBE_MAP, 0, GL_SRGB, 0, 0, w, h, 0);
  31012. }
  31013. //deprecated
  31014. void SkyBoxLoaderAndDrawer::draw(const glm::mat4 &viewProjMat, SkyBox &skyBox, float exposure,
  31015. glm::vec3 ambient)
  31016. {
  31017. glBindVertexArray(vertexArray);
  31018. glActiveTexture(GL_TEXTURE0);
  31019. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  31020. normalSkyBox.shader.bind();
  31021. glUniformMatrix4fv(normalSkyBox.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  31022. glUniform1i(normalSkyBox.samplerUniformLocation, 0);
  31023. glUniform3f(normalSkyBox.u_ambient, ambient.r, ambient.g, ambient.b);
  31024. glDepthFunc(GL_LEQUAL);
  31025. glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
  31026. glDepthFunc(GL_LESS);
  31027. glBindVertexArray(0);
  31028. }
  31029. void SkyBoxLoaderAndDrawer::drawBefore(const glm::mat4& viewProjMat, SkyBox& skyBox, float exposure,
  31030. glm::vec3 ambient)
  31031. {
  31032. glBindVertexArray(vertexArray);
  31033. glActiveTexture(GL_TEXTURE0);
  31034. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture);
  31035. normalSkyBox.shader.bind();
  31036. bool skyBoxPresent = 1;
  31037. if (skyBox.texture == 0 || skyBox.convolutedTexture == 0 || skyBox.preFilteredMap == 0)
  31038. {
  31039. skyBoxPresent = 0;
  31040. }
  31041. glUniformMatrix4fv(normalSkyBox.modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  31042. glUniform1i(normalSkyBox.samplerUniformLocation, 0);
  31043. glUniform1i(normalSkyBox.u_skyBoxPresent, skyBoxPresent);
  31044. glUniform3f(normalSkyBox.u_ambient, ambient.r, ambient.g, ambient.b);
  31045. glDisable(GL_DEPTH_TEST);
  31046. glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
  31047. glEnable(GL_DEPTH_TEST);
  31048. glBindVertexArray(0);
  31049. }
  31050. void SkyBoxLoaderAndDrawer::clear()
  31051. {
  31052. normalSkyBox.shader.clear();
  31053. hdrtoCubeMap.shader.clear();
  31054. convolute.shader.clear();
  31055. preFilterSpecular.shader.clear();
  31056. atmosphericScatteringShader.shader.clear();
  31057. glDeleteVertexArrays(1, &vertexArray);
  31058. glDeleteBuffers(1, &vertexBuffer);
  31059. glDeleteFramebuffers(1, &captureFBO);
  31060. }
  31061. void SkyBox::clearTextures()
  31062. {
  31063. glDeleteTextures(3, (GLuint*)this);
  31064. texture = 0;
  31065. convolutedTexture = 0;
  31066. preFilteredMap = 0;
  31067. }
  31068. //does not clear materials owned
  31069. void CpuEntity::clear()
  31070. {
  31071. deleteGpuData();
  31072. for (auto &n : subModelsNames)
  31073. {
  31074. delete[] n;
  31075. }
  31076. for (auto &m : models)
  31077. {
  31078. m.clear();
  31079. }
  31080. *this = CpuEntity();
  31081. }
  31082. void CpuEntity::allocateGpuData()
  31083. {
  31084. glGenBuffers(1, &appliedSkinningMatricesBuffer);
  31085. }
  31086. void CpuEntity::deleteGpuData()
  31087. {
  31088. glDeleteBuffers(1, &appliedSkinningMatricesBuffer);
  31089. }
  31090. };
  31091. #pragma endregion
  31092. ////////////////////////////////////////////////
  31093. //gl3d.cpp
  31094. ////////////////////////////////////////////////
  31095. #pragma region gl3d
  31096. #include <algorithm>
  31097. #include <random>
  31098. #include <string>
  31099. #include <glm/gtx/matrix_decompose.hpp>
  31100. #ifdef _MSC_VER
  31101. //#pragma warning( disable : 4244 4305 4267 4996 4018)
  31102. #pragma warning( disable : 26812)
  31103. #endif
  31104. namespace gl3d
  31105. {
  31106. void Renderer3D::init(int x, int y, const char *BRDFIntegrationMapFileLocation, GLuint frameBuffer)
  31107. {
  31108. this->frameBuffer = frameBuffer;
  31109. internal.w = x; internal.h = y;
  31110. internal.adaptiveW = x;
  31111. internal.adaptiveH = y;
  31112. glEnable(GL_CULL_FACE);
  31113. glEnable(GL_DEPTH_TEST);
  31114. glDisable(GL_BLEND);
  31115. errorReporter.callErrorCallback(internal.lightShader.create(errorReporter, fileOpener, BRDFIntegrationMapFileLocation));
  31116. internal.skyBoxLoaderAndDrawer.createGpuData(errorReporter, fileOpener, frameBuffer);
  31117. internal.showNormalsProgram.shader.loadShaderProgramFromFile("shaders/showNormals.vert",
  31118. "shaders/showNormals.geom", "shaders/showNormals.frag", errorReporter, fileOpener);
  31119. //todo error report here + make this work :)))
  31120. internal.showNormalsProgram.modelTransformLocation = glGetUniformLocation(internal.showNormalsProgram.shader.id, "u_modelTransform");
  31121. internal.showNormalsProgram.projectionLocation = glGetUniformLocation(internal.showNormalsProgram.shader.id, "u_projection");
  31122. internal.showNormalsProgram.sizeLocation = glGetUniformLocation(internal.showNormalsProgram.shader.id, "u_size");
  31123. internal.showNormalsProgram.colorLocation = glGetUniformLocation(internal.showNormalsProgram.shader.id, "u_color");
  31124. //unsigned char textureData[] =
  31125. //{
  31126. // 20, 20, 20, 255,
  31127. // 212, 0, 219, 255,
  31128. // 212, 0, 219, 255,
  31129. // 20, 20, 20, 255,
  31130. //};
  31131. //defaultTexture.loadTextureFromMemory(textureData, 2, 2, 4, TextureLoadQuality::leastPossible);
  31132. internal.gBuffer.create(x, y, errorReporter, frameBuffer);
  31133. internal.ssao.create(x, y, errorReporter, fileOpener, frameBuffer);
  31134. internal.hbao.create(errorReporter, fileOpener);
  31135. postProcess.create(x, y, errorReporter, fileOpener, frameBuffer);
  31136. directionalShadows.create(frameBuffer);
  31137. spotShadows.create(frameBuffer);
  31138. pointShadows.create(frameBuffer);
  31139. antiAlias.create(errorReporter, fileOpener);
  31140. adaptiveResolution.create(x, y);
  31141. copyDepth.create(errorReporter, fileOpener);
  31142. internal.colorCorrection.create(x, y, errorReporter, fileOpener);
  31143. internal.pBRtextureMaker.init(errorReporter, fileOpener);
  31144. }
  31145. ErrorCallback_t *Renderer3D::setErrorCallback(ErrorCallback_t *errorCallback, void *userData)
  31146. {
  31147. auto a = errorReporter.currentErrorCallback;
  31148. errorReporter.currentErrorCallback = errorCallback;
  31149. errorReporter.userData = userData;
  31150. return a;
  31151. }
  31152. ErrorCallback_t *Renderer3D::getErrorCallback()
  31153. {
  31154. return errorReporter.currentErrorCallback;
  31155. }
  31156. Material Renderer3D::createMaterial(int quality, glm::vec4 kd,
  31157. float roughness, float metallic, float ao, float emissive, std::string name,
  31158. gl3d::Texture albedoTexture, gl3d::Texture normalTexture, gl3d::Texture roughnessTexture, gl3d::Texture metallicTexture,
  31159. gl3d::Texture occlusionTexture, gl3d::Texture emmisiveTexture)
  31160. {
  31161. int id = internal::generateNewIndex(internal.materialIndexes);
  31162. MaterialValues gpuMaterial;
  31163. gpuMaterial.kd = kd;
  31164. gpuMaterial.roughness = roughness;
  31165. gpuMaterial.metallic = metallic;
  31166. gpuMaterial.ao = ao;
  31167. gpuMaterial.emmisive = emissive;
  31168. TextureDataForMaterial textureData{};
  31169. textureData.albedoTexture = albedoTexture;
  31170. textureData.normalMapTexture = normalTexture;
  31171. textureData.emissiveTexture = emmisiveTexture;
  31172. textureData.pbrTexture = createPBRTexture(roughnessTexture, metallicTexture, occlusionTexture, quality);
  31173. internal.materialIndexes.push_back(id);
  31174. internal.materials.push_back(gpuMaterial);
  31175. internal.materialNames.push_back(name);
  31176. internal.materialTexturesData.push_back(textureData);
  31177. Material m;
  31178. m.id_ = id;
  31179. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  31180. m.lastFoundPos_ = internal.materialIndexes.size()-1;
  31181. #endif
  31182. return m;
  31183. }
  31184. Material Renderer3D::createMaterial(Material m)
  31185. {
  31186. auto newM = createMaterial(frameBuffer);
  31187. copyMaterialData(newM, m);
  31188. return newM;
  31189. }
  31190. static int max(int x, int y, int z)
  31191. {
  31192. return std::max(std::max(x, y), z);
  31193. }
  31194. //this is the function that loads a material from parsed data
  31195. gl3d::Material createMaterialFromLoadedData(gl3d::Renderer3D &renderer,
  31196. objl::Material &mat, const std::string &path, GLuint frameBuffer, int quality)
  31197. {
  31198. //todo mat.ke also mat. emissive texture
  31199. auto m = renderer.createMaterial(quality, mat.Kd, mat.roughness,
  31200. mat.metallic, mat.ao, 0, mat.name);
  31201. stbi_set_flip_vertically_on_load(true);
  31202. //todo i moved the code from here
  31203. {
  31204. //load textures for materials
  31205. TextureDataForMaterial textureData;
  31206. if (!mat.loadedDiffuse.data.empty())
  31207. {
  31208. textureData.albedoTexture = renderer.loadTextureFromMemory(mat.loadedDiffuse, quality);
  31209. }
  31210. else
  31211. if (!mat.map_Kd.empty())
  31212. {
  31213. textureData.albedoTexture = renderer.loadTexture(std::string(path + mat.map_Kd), quality);
  31214. }
  31215. if (!mat.loadedNormal.data.empty())
  31216. {
  31217. textureData.normalMapTexture = renderer.loadTextureFromMemory(mat.loadedNormal, quality);
  31218. }
  31219. else
  31220. if (!mat.map_Kn.empty())
  31221. {
  31222. textureData.normalMapTexture = renderer.loadTexture(std::string(path + mat.map_Kn), quality);
  31223. }
  31224. if (!mat.loadedEmissive.data.empty())
  31225. {
  31226. textureData.emissiveTexture = renderer.loadTextureFromMemory(mat.loadedEmissive, quality);
  31227. auto ind = renderer.internal.getMaterialIndex(m);
  31228. renderer.internal.materials[ind].emmisive = 1.f;
  31229. }
  31230. else
  31231. if (!mat.map_emissive.empty())
  31232. {
  31233. textureData.emissiveTexture = renderer.loadTexture(std::string(path + mat.map_emissive), quality);
  31234. auto ind = renderer.internal.getMaterialIndex(m);
  31235. renderer.internal.materials[ind].emmisive = 1.f;
  31236. }
  31237. textureData.pbrTexture.RMA_loadedTextures = 0;
  31238. //auto rmaQuality = TextureLoadQuality::linearMipmap;
  31239. //todo not working in all gltf formats
  31240. if (!mat.map_RMA.empty())
  31241. {
  31242. textureData.pbrTexture.texture = renderer.loadTexture((path + mat.map_RMA).c_str(), quality);
  31243. if (textureData.pbrTexture.texture.id_ != 0)
  31244. {
  31245. textureData.pbrTexture.RMA_loadedTextures = 0b111; //all textures loaded
  31246. }
  31247. }
  31248. else
  31249. if (!mat.loadedORM.data.empty())
  31250. {
  31251. auto &t = mat.loadedORM;
  31252. //convert from ORM ro RMA
  31253. for (int j = 0; j < t.h; j++)
  31254. for (int i = 0; i < t.w; i++)
  31255. {
  31256. unsigned char R = t.data[(i + j * t.w) * 4 + 1];
  31257. unsigned char M = t.data[(i + j * t.w) * 4 + 2];
  31258. unsigned char A = t.data[(i + j * t.w) * 4 + 0];
  31259. t.data[(i + j * t.w) * 3 + 0] = R;
  31260. t.data[(i + j * t.w) * 3 + 1] = M;
  31261. t.data[(i + j * t.w) * 3 + 2] = A;
  31262. }
  31263. GpuTexture tex;
  31264. tex.loadTextureFromMemory(t.data.data(), t.w, t.h, 3, quality);
  31265. textureData.pbrTexture.texture = renderer.createIntenralTexture(tex, 0, 0);
  31266. textureData.pbrTexture.RMA_loadedTextures = 0b111; //all textures loaded
  31267. }
  31268. else
  31269. if (!mat.map_ORM.empty() && textureData.pbrTexture.RMA_loadedTextures == 0)
  31270. {
  31271. stbi_set_flip_vertically_on_load(true);
  31272. int w = 0, h = 0;
  31273. unsigned char *data = 0;
  31274. {
  31275. data = stbi_load(std::string(path + mat.map_ORM).c_str(),
  31276. &w, &h, 0, 3);
  31277. if (!data)
  31278. {
  31279. renderer.errorReporter.callErrorCallback("err loading " + std::string(path + mat.map_ORM));
  31280. }
  31281. else
  31282. {
  31283. //convert from ORM ro RMA
  31284. for (int j = 0; j < h; j++)
  31285. for (int i = 0; i < w; i++)
  31286. {
  31287. unsigned char R = data[(i + j * w) * 3 + 1];
  31288. unsigned char M = data[(i + j * w) * 3 + 2];
  31289. unsigned char A = data[(i + j * w) * 3 + 0];
  31290. data[(i + j * w) * 3 + 0] = R;
  31291. data[(i + j * w) * 3 + 1] = M;
  31292. data[(i + j * w) * 3 + 2] = A;
  31293. }
  31294. GpuTexture t;
  31295. t.loadTextureFromMemory(data, w, h, 3, quality);
  31296. textureData.pbrTexture.texture = renderer.createIntenralTexture(t, 0, 0);
  31297. textureData.pbrTexture.RMA_loadedTextures = 0b111; //all textures loaded
  31298. stbi_image_free(data);
  31299. }
  31300. }
  31301. }
  31302. //RMA trexture
  31303. if (textureData.pbrTexture.RMA_loadedTextures == 0)
  31304. {
  31305. constexpr int MERGE_TEXTURES_ON_GPU = 1; //deprecated probably the old version
  31306. if constexpr (MERGE_TEXTURES_ON_GPU)
  31307. {
  31308. GpuTexture roughness{};
  31309. if (!mat.map_Pr.empty())
  31310. {
  31311. renderer.errorReporter.callErrorCallback(
  31312. roughness.loadTextureFromFile(std::string(path + mat.map_Pr).c_str(), renderer.fileOpener, dontSet, 1));
  31313. glBindTexture(GL_TEXTURE_2D, roughness.id);
  31314. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  31315. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  31316. }
  31317. GpuTexture metallic{};
  31318. if (!mat.map_Pm.empty())
  31319. {
  31320. renderer.errorReporter.callErrorCallback(metallic.loadTextureFromFile(
  31321. std::string(path + mat.map_Pm).c_str(), renderer.fileOpener, dontSet, 1));
  31322. glBindTexture(GL_TEXTURE_2D, metallic.id);
  31323. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  31324. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  31325. }
  31326. GpuTexture ambientOcclusion{};
  31327. if (!mat.map_Ka.empty())
  31328. {
  31329. renderer.errorReporter.callErrorCallback(ambientOcclusion.loadTextureFromFile(
  31330. std::string(path + mat.map_Ka).c_str(), renderer.fileOpener, dontSet, 1));
  31331. glBindTexture(GL_TEXTURE_2D, ambientOcclusion.id);
  31332. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  31333. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  31334. }
  31335. auto t = renderer.internal.pBRtextureMaker.createRMAtexture(
  31336. roughness, metallic, ambientOcclusion, renderer.internal.lightShader.quadDrawer.quadVAO,
  31337. textureData.pbrTexture.RMA_loadedTextures, frameBuffer, quality);
  31338. if (textureData.pbrTexture.RMA_loadedTextures != 0)
  31339. {
  31340. textureData.pbrTexture.texture = renderer.createIntenralTexture(t, 0, 0);
  31341. }
  31342. else
  31343. {
  31344. textureData.pbrTexture = {};
  31345. }
  31346. roughness.clear();
  31347. metallic.clear();
  31348. ambientOcclusion.clear();
  31349. }
  31350. else
  31351. {
  31352. stbi_set_flip_vertically_on_load(true);
  31353. int w1 = 0, h1 = 0;
  31354. unsigned char *data1 = 0;
  31355. unsigned char *data2 = 0;
  31356. unsigned char *data3 = 0;
  31357. if (!mat.map_Pr.empty())
  31358. {
  31359. data1 = stbi_load(std::string(path + mat.map_Pr).c_str(),
  31360. &w1, &h1, 0, 1);
  31361. if (!data1) { renderer.errorReporter.callErrorCallback("err loading " + std::string(path + mat.map_Pr)); }
  31362. }
  31363. int w2 = 0, h2 = 0;
  31364. if (!mat.map_Pm.empty())
  31365. {
  31366. data2 = stbi_load(std::string(path + mat.map_Pm).c_str(),
  31367. &w2, &h2, 0, 1);
  31368. if (!data2)
  31369. { renderer.errorReporter.callErrorCallback("err loading " + std::string(path + mat.map_Pm)); }
  31370. }
  31371. int w3 = 0, h3 = 0;
  31372. if (!mat.map_Ka.empty())
  31373. {
  31374. data3 = stbi_load(std::string(path + mat.map_Ka).c_str(),
  31375. &w3, &h3, 0, 1);
  31376. if (!data3) { renderer.errorReporter.callErrorCallback("err loading " + std::string(path + mat.map_Ka)); }
  31377. }
  31378. int w = max(w1, w2, w3);
  31379. int h = max(h1, h2, h3);
  31380. //calculate which function to use
  31381. //if (data1 && data2 && data3) { textureData.pbrTexture.RMA_loadedTextures = 7; }
  31382. //else
  31383. //if (data2 && data3) { textureData.pbrTexture.RMA_loadedTextures = 6; }
  31384. //else
  31385. //if (data1 && data3) { textureData.pbrTexture.RMA_loadedTextures = 5; }
  31386. //else
  31387. //if (data1 && data2) { textureData.pbrTexture.RMA_loadedTextures = 4; }
  31388. //else
  31389. //if (data3) { textureData.pbrTexture.RMA_loadedTextures = 3; }
  31390. //else
  31391. //if (data2) { textureData.pbrTexture.RMA_loadedTextures = 2; }
  31392. //else
  31393. //if (data1) { textureData.pbrTexture.RMA_loadedTextures = 1; }
  31394. //else { textureData.pbrTexture.RMA_loadedTextures = 0; }
  31395. textureData.pbrTexture.RMA_loadedTextures = 0;
  31396. if (data1) { textureData.pbrTexture.RMA_loadedTextures |= 0b100; }
  31397. if (data2) { textureData.pbrTexture.RMA_loadedTextures |= 0b010; }
  31398. if (data3) { textureData.pbrTexture.RMA_loadedTextures |= 0b001; }
  31399. if (textureData.pbrTexture.RMA_loadedTextures)
  31400. {
  31401. unsigned char *finalData = new unsigned char[w * h * 4];
  31402. for (int j = 0; j < h; j++)
  31403. {
  31404. for (int i = 0; i < w; i++)
  31405. {
  31406. if (data1) //rough
  31407. {
  31408. int texelI = (i / (float)w) * w1;
  31409. int texelJ = (j / float(h)) * h1;
  31410. finalData[((j * w) + i) * 4 + 0] =
  31411. data1[(texelJ * w1) + texelI];
  31412. }
  31413. else
  31414. {
  31415. finalData[((j * w) + i) * 4 + 0] = 0;
  31416. }
  31417. if (data2) //metalic
  31418. {
  31419. int texelI = (i / (float)w) * w2;
  31420. int texelJ = (j / float(h)) * h2;
  31421. finalData[((j * w) + i) * 4 + 1] =
  31422. data2[(texelJ * w2) + texelI];
  31423. }
  31424. else
  31425. {
  31426. finalData[((j * w) + i) * 4 + 1] = 0;
  31427. }
  31428. if (data3) //ambient
  31429. {
  31430. int texelI = (i / (float)w) * w3;
  31431. int texelJ = (j / float(h)) * h3;
  31432. finalData[((j * w) + i) * 4 + 2] =
  31433. data3[(texelJ * w3) + texelI];
  31434. }
  31435. else
  31436. {
  31437. finalData[((j * w) + i) * 4 + 2] = 0;
  31438. }
  31439. finalData[((j * w) + i) * 4 + 3] = 255; //used only for imgui, remove later
  31440. }
  31441. }
  31442. //gm.RMA_Texture.loadTextureFromMemory(finalData, w, h, 4,
  31443. // rmaQuality);
  31444. GpuTexture t;
  31445. t.loadTextureFromMemory(finalData, w, h, 4, quality);
  31446. textureData.pbrTexture.texture = renderer.createIntenralTexture(t, 0, 0);
  31447. stbi_image_free(data1);
  31448. stbi_image_free(data2);
  31449. stbi_image_free(data3);
  31450. delete[] finalData;
  31451. }
  31452. }
  31453. /*
  31454. */
  31455. }
  31456. renderer.setMaterialTextures(m, textureData);
  31457. }
  31458. return m;
  31459. }
  31460. std::vector<Material> Renderer3D::loadMaterial(std::string file, int quality)
  31461. {
  31462. objl::Loader loader;
  31463. if (!loader.LoadMaterials(file, errorReporter, fileOpener))
  31464. {
  31465. errorReporter.callErrorCallback("err loading: " + file);
  31466. return {};
  31467. }
  31468. std::vector<Material> ret;
  31469. ret.reserve(loader.LoadedMaterials.size());
  31470. std::string path = file;
  31471. while (!path.empty() &&
  31472. *(path.end() - 1) != '\\' &&
  31473. *(path.end() - 1) != '/'
  31474. )
  31475. {
  31476. path.pop_back();
  31477. }
  31478. for (auto &m : loader.LoadedMaterials)
  31479. {
  31480. auto material = createMaterialFromLoadedData(*this, m, path, frameBuffer, quality);
  31481. ret.push_back(material);
  31482. }
  31483. return std::move(ret);
  31484. }
  31485. bool Renderer3D::deleteMaterial(Material m)
  31486. {
  31487. auto pos = std::find(internal.materialIndexes.begin(), internal.materialIndexes.end(), m.id_);
  31488. if (pos == internal.materialIndexes.end())
  31489. {
  31490. gl3dAssertComment(pos != internal.materialIndexes.end(), "invalid delete material");
  31491. return 0;
  31492. }
  31493. int index = pos - internal.materialIndexes.begin();
  31494. internal.materialIndexes.erase(pos);
  31495. internal.materials.erase(internal.materials.begin() + index);
  31496. internal.materialNames.erase(internal.materialNames.begin() + index);
  31497. internal.materialTexturesData.erase(internal.materialTexturesData.begin() + index);
  31498. m.id_ = 0;
  31499. return 1;
  31500. }
  31501. bool Renderer3D::copyMaterialData(Material dest, Material source)
  31502. {
  31503. int destId = internal.getMaterialIndex(dest);
  31504. int sourceId = internal.getMaterialIndex(source);
  31505. if(destId == -1 || sourceId == -1)
  31506. {
  31507. gl3dAssertComment(destId != -1, "invaled dest material index");
  31508. gl3dAssertComment(sourceId != -1, "invaled source material index");
  31509. return 0;
  31510. }
  31511. internal.materials[destId] = internal.materials[sourceId];
  31512. internal.materialNames[destId] = internal.materialNames[sourceId];
  31513. internal.materialTexturesData[destId] = internal.materialTexturesData[destId];
  31514. return 1;
  31515. }
  31516. MaterialValues Renderer3D::getMaterialValues(Material m)
  31517. {
  31518. int id = internal.getMaterialIndex(m);
  31519. if(id == -1)
  31520. {
  31521. return {};
  31522. }
  31523. return internal.materials[id];
  31524. }
  31525. void Renderer3D::setMaterialValues(Material m, MaterialValues values)
  31526. {
  31527. int id = internal.getMaterialIndex(m);
  31528. if (id == -1)
  31529. {
  31530. return;
  31531. }
  31532. internal.materials[id] = values;
  31533. }
  31534. TextureDataForMaterial Renderer3D::getMaterialTextures(Material m)
  31535. {
  31536. int id = internal.getMaterialIndex(m);
  31537. if (id == -1)
  31538. {return {};}
  31539. return internal.materialTexturesData[id];
  31540. }
  31541. void Renderer3D::setMaterialTextures(Material m, TextureDataForMaterial textures)
  31542. {
  31543. int id = internal.getMaterialIndex(m);
  31544. if (id == -1)
  31545. {return;}
  31546. internal.materialTexturesData[id] = textures;
  31547. }
  31548. std::string Renderer3D::getMaterialName(Material m)
  31549. {
  31550. int id = internal.getMaterialIndex(m);
  31551. if (id == -1)
  31552. {
  31553. return "";
  31554. }
  31555. return internal.materialNames[id];
  31556. }
  31557. void Renderer3D::setMaterialName(Material m, const std::string& name)
  31558. {
  31559. int id = internal.getMaterialIndex(m);
  31560. if (id == -1)
  31561. {return;}
  31562. internal.materialNames[id] = name;
  31563. }
  31564. bool Renderer3D::isMaterial(Material& m)
  31565. {
  31566. int id = internal.getMaterialIndex(m);
  31567. if (id == -1)
  31568. {
  31569. return false;
  31570. }
  31571. else
  31572. {
  31573. return true;
  31574. }
  31575. }
  31576. //bool Renderer3D::setMaterialData(Material m, const MaterialValues &data, std::string *s)
  31577. //{
  31578. // int id = internal.getMaterialIndex(m);
  31579. //
  31580. // if (id == -1)
  31581. // {
  31582. // return 0;
  31583. // }
  31584. //
  31585. // internal.materials[id] = data;
  31586. //
  31587. // if (s)
  31588. // {
  31589. // internal.materialNames[id] = *s;
  31590. // }
  31591. //
  31592. // return 1;
  31593. //}
  31594. Texture Renderer3D::loadTexture(std::string path, int quality)
  31595. {
  31596. if (path == "")
  31597. {
  31598. return Texture{0};
  31599. }
  31600. int pos = 0;
  31601. for (auto &i : internal.loadedTexturesNames)
  31602. {
  31603. if (i == path)
  31604. {
  31605. Texture t;
  31606. t.id_ = internal.loadedTexturesIndexes[pos];
  31607. return t;
  31608. }
  31609. pos++;
  31610. }
  31611. GpuTexture t;
  31612. int alphaExists;
  31613. int alphaData;
  31614. errorReporter.callErrorCallback(t.loadTextureFromFileAndCheckAlpha(path.c_str(), alphaExists, alphaData, quality));
  31615. return createIntenralTexture(t.id, alphaExists, alphaData, path);
  31616. }
  31617. Texture Renderer3D::loadTextureFromMemory(objl::LoadedTexture &t, int quality)
  31618. {
  31619. if (t.data.empty())
  31620. {
  31621. return Texture{ 0 };
  31622. }
  31623. GpuTexture tex;
  31624. int alphaExists = 0;
  31625. int alphaWithData = 0;
  31626. tex.loadTextureFromMemoryAndCheckAlpha((void *)t.data.data(), t.w, t.h, alphaExists, t.components, 4, quality);
  31627. return createIntenralTexture(tex, alphaExists, alphaWithData);
  31628. }
  31629. GLuint Renderer3D::getTextureOpenglId(Texture& t)
  31630. {
  31631. auto p = getTextureData(t);
  31632. if(p == nullptr)
  31633. {
  31634. return 0;
  31635. }else
  31636. {
  31637. return p->id;
  31638. }
  31639. }
  31640. bool Renderer3D::isTexture(Texture& t)
  31641. {
  31642. int i = internal.getTextureIndex(t);
  31643. if (i > -1)
  31644. {
  31645. return true;
  31646. }
  31647. else
  31648. {
  31649. return false;
  31650. }
  31651. }
  31652. //todo delete from gpu
  31653. void Renderer3D::deleteTexture(Texture& t)
  31654. {
  31655. int index = internal.getTextureIndex(t);
  31656. if(index < 0)
  31657. {
  31658. return;
  31659. }
  31660. auto gpuTexture = internal.loadedTextures[index];
  31661. internal.loadedTexturesIndexes.erase(internal.loadedTexturesIndexes.begin() + index);
  31662. internal.loadedTexturesBindlessHandle.erase(internal.loadedTexturesBindlessHandle.begin() + index);
  31663. internal.loadedTextures.erase(internal.loadedTextures.begin() + index);
  31664. internal.loadedTexturesNames.erase(internal.loadedTexturesNames.begin() + index);
  31665. t.id_ = 0;
  31666. }
  31667. GpuTexture *Renderer3D::getTextureData(Texture& t)
  31668. {
  31669. int id = internal.getTextureIndex(t);
  31670. if (id == -1)
  31671. {
  31672. return nullptr;
  31673. }
  31674. auto data = &internal.loadedTextures[id];
  31675. return &data->texture;
  31676. }
  31677. Texture Renderer3D::createIntenralTexture(GpuTexture t, int alphaData, int alphaValues, const std::string& name)
  31678. {
  31679. //if t is null return an empty texture
  31680. if (t.id == 0)
  31681. {
  31682. return Texture{ 0 };
  31683. }
  31684. int id = internal::generateNewIndex(internal.loadedTexturesIndexes);
  31685. internal::GpuTextureWithFlags text;
  31686. text.texture = t;
  31687. text.setAlphaExists(alphaData);
  31688. text.setAlphaWithData(alphaValues);
  31689. auto handle = glGetTextureHandleARB(t.id);
  31690. glMakeTextureHandleResidentARB(handle);
  31691. internal.loadedTexturesIndexes.push_back(id);
  31692. internal.loadedTextures.push_back(text);
  31693. internal.loadedTexturesBindlessHandle.push_back(handle);
  31694. internal.loadedTexturesNames.push_back(name);
  31695. return Texture{ id };
  31696. }
  31697. //this takes an id and adds the texture to the internal system
  31698. Texture Renderer3D::createIntenralTexture(GLuint id_, int alphaData, int alphaValues, const std::string &name)
  31699. {
  31700. GpuTexture t;
  31701. t.id = id_;
  31702. return createIntenralTexture(t, alphaData, alphaValues, name);
  31703. }
  31704. PBRTexture Renderer3D::createPBRTexture(Texture& roughness, Texture& metallic,
  31705. Texture& ambientOcclusion, int quality)
  31706. {
  31707. PBRTexture ret = {};
  31708. auto t = internal.pBRtextureMaker.createRMAtexture(
  31709. {getTextureOpenglId(roughness)},
  31710. { getTextureOpenglId(metallic) },
  31711. { getTextureOpenglId(ambientOcclusion) }, internal.lightShader.quadDrawer.quadVAO, ret.RMA_loadedTextures,
  31712. frameBuffer, quality);
  31713. ret.texture = this->createIntenralTexture(t, 0, 0);
  31714. return ret;
  31715. }
  31716. void Renderer3D::deletePBRTexture(PBRTexture& t)
  31717. {
  31718. deleteTexture(t.texture);
  31719. t.RMA_loadedTextures = 0;
  31720. }
  31721. Model Renderer3D::createModelFromData(Material material, std::string name,
  31722. size_t vertexCount, const float *vertices, size_t indexesCount,
  31723. const unsigned int *indexes, bool noTexture)
  31724. {
  31725. ModelData returnModel;
  31726. //setup stuff
  31727. {
  31728. returnModel.createdMaterials.push_back(material);
  31729. GraphicModel gm;
  31730. gm.material = material;
  31731. gm.ownMaterial = false;
  31732. gm.name = name;
  31733. gm.hasBones = 0;
  31734. if (indexesCount == 0)
  31735. {
  31736. gm.loadFromComputedData(vertexCount * sizeof(float),
  31737. vertices,
  31738. 0, nullptr, noTexture);
  31739. }
  31740. else
  31741. {
  31742. gm.loadFromComputedData(vertexCount * sizeof(float),
  31743. vertices,
  31744. indexesCount * sizeof(unsigned int), indexes, noTexture);
  31745. }
  31746. char *c = new char[gm.name.size() + 1];
  31747. strcpy(c, gm.name.c_str());
  31748. returnModel.subModelsNames.push_back(c);
  31749. returnModel.models.push_back(gm);
  31750. }
  31751. int id = internal::generateNewIndex(internal.graphicModelsIndexes);
  31752. internal.graphicModelsIndexes.push_back(id);
  31753. internal.graphicModels.push_back(returnModel);
  31754. Model m;
  31755. m.id_ = id;
  31756. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  31757. m.lastFoundPos_ = internal.graphicModelsIndexes.size() - 1;
  31758. #endif
  31759. return m;
  31760. }
  31761. Model Renderer3D::loadModel(std::string path, int quality, float scale)
  31762. {
  31763. gl3d::LoadedModelData model(path.c_str(), errorReporter, fileOpener, scale);
  31764. if(model.loader.LoadedMeshes.empty())
  31765. {
  31766. errorReporter.callErrorCallback("err loading " + path);
  31767. return { 0 };
  31768. }
  31769. int id = internal::generateNewIndex(internal.graphicModelsIndexes);
  31770. ModelData returnModel; //todo move stuff into a function
  31771. {
  31772. int s = model.loader.LoadedMeshes.size();
  31773. returnModel.models.reserve(s);
  31774. #pragma region materials
  31775. returnModel.createdMaterials.reserve(model.loader.LoadedMaterials.size());
  31776. for(int i=0;i<model.loader.LoadedMaterials.size(); i++)
  31777. {
  31778. auto &mat = model.loader.LoadedMaterials[i];
  31779. auto m = createMaterialFromLoadedData(*this, mat, model.path, frameBuffer, quality);
  31780. returnModel.createdMaterials.push_back(m);
  31781. }
  31782. #pragma endregion
  31783. #pragma region aninmations
  31784. if (!model.loader.animations.empty())
  31785. {
  31786. returnModel.animations = model.loader.animations;
  31787. }
  31788. if (!model.loader.joints.empty())
  31789. {
  31790. returnModel.joints = model.loader.joints;
  31791. }
  31792. #pragma endregion
  31793. #pragma region meshes
  31794. for (int i = 0; i < s; i++)
  31795. {
  31796. GraphicModel gm;
  31797. int index = i;
  31798. //TextureDataForModel textureData = {};
  31799. auto &mesh = model.loader.LoadedMeshes[index];
  31800. if (!mesh.Vertices.empty()) //this has data without animation data
  31801. {
  31802. if (mesh.Indices.empty())
  31803. {
  31804. gm.loadFromComputedData(mesh.Vertices.size() * sizeof(mesh.Vertices[0]),
  31805. (float *)&mesh.Vertices[0],
  31806. 0, nullptr);
  31807. }
  31808. else
  31809. {
  31810. gm.loadFromComputedData(mesh.Vertices.size() * sizeof(mesh.Vertices[0]),
  31811. (float *)&mesh.Vertices[0],
  31812. mesh.Indices.size() * 4, &mesh.Indices[0]);
  31813. }
  31814. }
  31815. else if(mesh.VerticesAnimations.size())
  31816. {
  31817. if (mesh.Indices.empty())
  31818. {
  31819. gm.loadFromComputedData(mesh.VerticesAnimations.size() * sizeof(mesh.VerticesAnimations[0]),
  31820. (float *)&mesh.VerticesAnimations[0],
  31821. 0, nullptr, false, true);
  31822. }
  31823. else
  31824. {
  31825. gm.loadFromComputedData(mesh.VerticesAnimations.size() * sizeof(mesh.VerticesAnimations[0]),
  31826. (float *)&mesh.VerticesAnimations[0],
  31827. mesh.Indices.size() * 4, &mesh.Indices[0], false, true);
  31828. }
  31829. }
  31830. else
  31831. {
  31832. gl3dAssertComment(0, "Tried to load an emptty model");
  31833. return {0};
  31834. }
  31835. gm.hasBones = mesh.hasBones;
  31836. if(model.loader.LoadedMeshes[index].materialIndex > -1)
  31837. {
  31838. gm.material = returnModel.createdMaterials[model.loader.LoadedMeshes[index].materialIndex];
  31839. }else
  31840. {
  31841. //if no material loaded for this object create a new default one
  31842. gm.material = createMaterial(quality, glm::vec4{ 0.8f,0.8f,0.8f, 1.0f }, 0.5f, 0.f, 1.f, 0.f, "default material");
  31843. }
  31844. gm.ownMaterial = true;
  31845. gm.name = model.loader.LoadedMeshes[i].MeshName;
  31846. char *c = new char[gm.name.size() + 1];
  31847. strcpy(c, gm.name.c_str());
  31848. returnModel.subModelsNames.push_back(c);
  31849. returnModel.models.push_back(gm);
  31850. }
  31851. #pragma endregion
  31852. }
  31853. internal.graphicModelsIndexes.push_back(id);
  31854. internal.graphicModels.push_back(returnModel);
  31855. Model o;
  31856. o.id_ = id;
  31857. return o;
  31858. }
  31859. bool Renderer3D::isModel(Model& m)
  31860. {
  31861. auto pos = internal.getModelIndex(m);
  31862. if (pos < 0)
  31863. {
  31864. return 0;
  31865. }
  31866. else
  31867. {
  31868. return 1;
  31869. }
  31870. }
  31871. void Renderer3D::deleteModel(Model &m) //todo check if delete created materials and internal stuff is good
  31872. {
  31873. clearModelData(m);
  31874. auto pos = internal.getModelIndex(m);
  31875. if (pos < 0)
  31876. {
  31877. gl3dAssertComment(pos >= 0, "invalid delete model");
  31878. return;
  31879. }
  31880. internal.graphicModelsIndexes.erase(internal.graphicModelsIndexes.begin() + pos);
  31881. internal.graphicModels.erase(internal.graphicModels.begin() + pos);
  31882. m.id_ = 0;
  31883. }
  31884. void Renderer3D::clearModelData(Model& m)
  31885. {
  31886. auto pos = internal.getModelIndex(m);
  31887. if (pos < 0)
  31888. {
  31889. return;
  31890. }
  31891. internal.graphicModels[pos].clear(*this);
  31892. }
  31893. int Renderer3D::getModelMeshesCount(Model& m)
  31894. {
  31895. auto pos = internal.getModelIndex(m);
  31896. if (pos < 0)
  31897. {
  31898. return 0;
  31899. }
  31900. else
  31901. {
  31902. return internal.graphicModels[pos].models.size();
  31903. }
  31904. }
  31905. std::string Renderer3D::getModelMeshesName(Model& m, int index)
  31906. {
  31907. auto pos = internal.getModelIndex(m);
  31908. if (pos >= 0)
  31909. {
  31910. if(index < internal.graphicModels[pos].models.size())
  31911. {
  31912. return internal.graphicModels[pos].models[pos].name;
  31913. }
  31914. else
  31915. {
  31916. return "";
  31917. }
  31918. }
  31919. else
  31920. {
  31921. return "";
  31922. }
  31923. }
  31924. std::vector<char*>* Renderer3D::getModelMeshesNames(Model& m)
  31925. {
  31926. auto i = internal.getModelIndex(m);
  31927. if (i < 0) { return nullptr; } //warn or sthing
  31928. return &internal.graphicModels[i].subModelsNames;
  31929. }
  31930. #pragma region point light
  31931. PointLight Renderer3D::createPointLight(glm::vec3 position, glm::vec3 color,
  31932. float dist, float attenuation)
  31933. {
  31934. int id = internal::generateNewIndex(internal.pointLightIndexes);
  31935. internal::GpuPointLight light;
  31936. light.position = position;
  31937. light.color = color;
  31938. light.dist = glm::max(0.f, dist);
  31939. light.attenuation = glm::max(0.f, attenuation);
  31940. internal.pointLightIndexes.push_back(id);
  31941. internal.pointLights.push_back(light);
  31942. internal.perFrameFlags.shouldUpdatePointShadows = true;
  31943. PointLight pl = {};
  31944. pl.id_ = id;
  31945. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  31946. pl.lastFoundPos_ = internal.pointLightIndexes.size() - 1;
  31947. #endif
  31948. return { pl };
  31949. }
  31950. void Renderer3D::detletePointLight(PointLight& l)
  31951. {
  31952. auto pos = internal.getPointLightIndex(l);
  31953. if (pos < 0)
  31954. {
  31955. gl3dAssertComment(pos >= 0, "invalid delete point light");
  31956. return;
  31957. }
  31958. //if (internal.spotLights[pos].castShadows)
  31959. //{
  31960. // internal.perFrameFlags.shouldUpdateSpotShadows = true;
  31961. //}
  31962. internal.pointLightIndexes.erase(internal.pointLightIndexes.begin() + pos);
  31963. internal.pointLights.erase(internal.pointLights.begin() + pos);
  31964. l.id_ = 0;
  31965. internal.perFrameFlags.shouldUpdatePointShadows = true;
  31966. }
  31967. glm::vec3 Renderer3D::getPointLightPosition(PointLight& l)
  31968. {
  31969. auto i = internal.getPointLightIndex(l);
  31970. if (i < 0) { return {}; } //warn or sthing
  31971. return internal.pointLights[i].position;
  31972. }
  31973. void Renderer3D::setPointLightPosition(PointLight& l, glm::vec3 position)
  31974. {
  31975. auto i = internal.getPointLightIndex(l);
  31976. if (i < 0) { return; } //warn or sthing
  31977. if (internal.pointLights[i].position != position)
  31978. {
  31979. internal.pointLights[i].position = position;
  31980. internal.pointLights[i].changedThisFrame = true;
  31981. }
  31982. }
  31983. bool Renderer3D::isPointLight(PointLight& l)
  31984. {
  31985. auto i = internal.getPointLightIndex(l);
  31986. if (i < 0)
  31987. {
  31988. return false;
  31989. }
  31990. else
  31991. {
  31992. return true;
  31993. }
  31994. }
  31995. glm::vec3 Renderer3D::getPointLightColor(PointLight& l)
  31996. {
  31997. auto i = internal.getPointLightIndex(l);
  31998. if (i < 0) { return {}; } //warn or sthing
  31999. return internal.pointLights[i].color;
  32000. }
  32001. void Renderer3D::setPointLightColor(PointLight& l, glm::vec3 color)
  32002. {
  32003. auto i = internal.getPointLightIndex(l);
  32004. if (i < 0) { return; } //warn or sthing
  32005. internal.pointLights[i].color = color;
  32006. }
  32007. float Renderer3D::getPointLightDistance(PointLight& l)
  32008. {
  32009. auto i = internal.getPointLightIndex(l);
  32010. if (i < 0) { return {}; } //warn or sthing
  32011. return internal.pointLights[i].dist;
  32012. }
  32013. void Renderer3D::setPointLightDistance(PointLight& l, float distance)
  32014. {
  32015. auto i = internal.getPointLightIndex(l);
  32016. if (i < 0) { return; } //warn or sthing
  32017. distance = glm::max(0.f, distance);
  32018. if (internal.pointLights[i].dist != distance)
  32019. {
  32020. internal.pointLights[i].dist = distance;
  32021. internal.pointLights[i].changedThisFrame = true;
  32022. }
  32023. }
  32024. float Renderer3D::getPointLightAttenuation(PointLight& l)
  32025. {
  32026. auto i = internal.getPointLightIndex(l);
  32027. if (i < 0) { return {}; } //warn or sthing
  32028. return internal.pointLights[i].attenuation;
  32029. }
  32030. void Renderer3D::setPointLightAttenuation(PointLight& l, float attenuation)
  32031. {
  32032. auto i = internal.getPointLightIndex(l);
  32033. if (i < 0) { return; } //warn or sthing
  32034. internal.pointLights[i].attenuation = glm::max(attenuation, 0.f);
  32035. }
  32036. bool Renderer3D::getPointLightShadows(PointLight& l)
  32037. {
  32038. auto i = internal.getPointLightIndex(l);
  32039. if (i < 0) { return {}; } //warn or sthing
  32040. return internal.pointLights[i].castShadows;
  32041. }
  32042. void Renderer3D::setPointLightShadows(PointLight& l, bool castShadows)
  32043. {
  32044. auto i = internal.getPointLightIndex(l);
  32045. if (i < 0) { return; } //warn or sthing
  32046. if (internal.pointLights[i].castShadows != castShadows)
  32047. {
  32048. internal.pointLights[i].castShadows = castShadows;
  32049. internal.pointLights[i].changedThisFrame = true;
  32050. internal.perFrameFlags.shouldUpdatePointShadows = true;
  32051. }
  32052. }
  32053. float Renderer3D::getPointLightHardness(PointLight& l)
  32054. {
  32055. auto i = internal.getPointLightIndex(l);
  32056. if (i < 0) { return {}; } //warn or sthing
  32057. return internal.pointLights[i].hardness;
  32058. }
  32059. void Renderer3D::setPointLightHardness(PointLight& l, float hardness)
  32060. {
  32061. auto i = internal.getPointLightIndex(l);
  32062. if (i < 0) { return; } //warn or sthing
  32063. internal.pointLights[i].hardness = glm::max(hardness, 0.001f);
  32064. }
  32065. int Renderer3D::getPointLightShadowSize()
  32066. {
  32067. return pointShadows.shadowSize;
  32068. }
  32069. void Renderer3D::setPointLightShadowSize(int size)
  32070. {
  32071. size = std::min(std::max(256, size), 2048);
  32072. if (size != pointShadows.shadowSize)
  32073. {
  32074. pointShadows.shadowSize = size;
  32075. internal.perFrameFlags.shouldUpdatePointShadows = true;
  32076. }
  32077. }
  32078. #pragma endregion
  32079. #pragma region directional light
  32080. DirectionalLight Renderer3D::createDirectionalLight(glm::vec3 direction,
  32081. glm::vec3 color, float hardness, bool castShadows)
  32082. {
  32083. int id = internal::generateNewIndex(internal.directionalLightIndexes);
  32084. internal::GpuDirectionalLight light;
  32085. light.color = color;
  32086. light.hardness = glm::max(hardness, 0.001f);
  32087. if (castShadows)
  32088. {
  32089. light.castShadowsIndex = 1;
  32090. }
  32091. else
  32092. {
  32093. light.castShadowsIndex = -1;
  32094. }
  32095. if (glm::length(direction) == 0)
  32096. {
  32097. direction = glm::vec3{ 0, -1, 0 };
  32098. }
  32099. else
  32100. {
  32101. direction = glm::normalize(direction);
  32102. }
  32103. light.direction = glm::vec4(direction, 0);
  32104. internal.directionalLightIndexes.push_back(id);
  32105. internal.directionalLights.push_back(light);
  32106. internal.perFrameFlags.shouldUpdateDirectionalShadows = true;
  32107. DirectionalLight dl = {};
  32108. dl.id_ = id;
  32109. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  32110. dl.lastFoundPos_ = internal.directionalLightIndexes.size() - 1;
  32111. #endif
  32112. return {dl};
  32113. }
  32114. void Renderer3D::deleteDirectionalLight(DirectionalLight& l)
  32115. {
  32116. auto pos = internal.getDirectionalLightIndex(l);
  32117. if (pos < 0)
  32118. {
  32119. gl3dAssertComment(pos >= 0, "invalid delete directional light");
  32120. return;
  32121. }
  32122. //if (internal.directionalLights[pos].castShadows)
  32123. //{
  32124. // internal.perFrameFlags.shouldUpdateDirectionalShadows = true;
  32125. //}
  32126. internal.directionalLightIndexes.erase(internal.directionalLightIndexes.begin() + pos);
  32127. internal.directionalLights.erase(internal.directionalLights.begin() + pos);
  32128. l.id_ = 0;
  32129. internal.perFrameFlags.shouldUpdateDirectionalShadows = true;
  32130. }
  32131. bool Renderer3D::isDirectionalLight(DirectionalLight& l)
  32132. {
  32133. auto i = internal.getDirectionalLightIndex(l);
  32134. if (i < 0)
  32135. {
  32136. return false;
  32137. }
  32138. else
  32139. {
  32140. return true;
  32141. }
  32142. }
  32143. glm::vec3 Renderer3D::getDirectionalLightDirection(DirectionalLight& l)
  32144. {
  32145. auto i = internal.getDirectionalLightIndex(l);
  32146. if (i < 0) { return {}; } //warn or sthing
  32147. return internal.directionalLights[i].direction;
  32148. }
  32149. void Renderer3D::setDirectionalLightDirection(DirectionalLight& l, glm::vec3 direction)
  32150. {
  32151. auto i = internal.getDirectionalLightIndex(l);
  32152. if (i < 0) { return; } //warn or sthing
  32153. if (glm::length(direction) == 0)
  32154. {
  32155. direction = glm::vec3{ 0, -1, 0 };
  32156. }
  32157. else
  32158. {
  32159. direction = glm::normalize(direction);
  32160. }
  32161. if (glm::vec3(internal.directionalLights[i].direction) != direction)
  32162. {
  32163. internal.directionalLights[i].direction = glm::vec4(direction, 0);
  32164. internal.directionalLights[i].changedThisFrame = true;
  32165. }
  32166. }
  32167. glm::vec3 Renderer3D::getDirectionalLightColor(DirectionalLight& l)
  32168. {
  32169. auto i = internal.getDirectionalLightIndex(l);
  32170. if (i < 0) { return {}; } //warn or sthing
  32171. return internal.directionalLights[i].color;
  32172. }
  32173. void Renderer3D::setDirectionalLightColor(DirectionalLight& l, glm::vec3 color)
  32174. {
  32175. auto i = internal.getDirectionalLightIndex(l);
  32176. if (i < 0) { return; } //warn or sthing
  32177. internal.directionalLights[i].color = color;
  32178. }
  32179. float Renderer3D::getDirectionalLightHardness(DirectionalLight& l)
  32180. {
  32181. auto i = internal.getDirectionalLightIndex(l);
  32182. if (i < 0) { return {}; } //warn or sthing
  32183. return internal.directionalLights[i].hardness;
  32184. }
  32185. void Renderer3D::setDirectionalLightHardness(DirectionalLight& l, float hardness)
  32186. {
  32187. auto i = internal.getDirectionalLightIndex(l);
  32188. if (i < 0) { return; } //warn or sthing
  32189. internal.directionalLights[i].hardness = glm::max(hardness, 0.001f);
  32190. }
  32191. bool Renderer3D::getDirectionalLightShadows(DirectionalLight& l)
  32192. {
  32193. auto i = internal.getDirectionalLightIndex(l);
  32194. if (i < 0) { return {}; } //warn or sthing
  32195. return internal.directionalLights[i].castShadows;
  32196. }
  32197. void Renderer3D::setDirectionalLightShadows(DirectionalLight& l, bool castShadows)
  32198. {
  32199. auto i = internal.getDirectionalLightIndex(l);
  32200. if (i < 0) { return; } //warn or sthing
  32201. if (castShadows != internal.directionalLights[i].castShadows)
  32202. {
  32203. internal.directionalLights[i].castShadows = castShadows;
  32204. internal.directionalLights[i].changedThisFrame = true;
  32205. internal.perFrameFlags.shouldUpdateDirectionalShadows = true;
  32206. }
  32207. }
  32208. int Renderer3D::getDirectionalLightShadowSize()
  32209. {
  32210. return directionalShadows.shadowSize;
  32211. }
  32212. void Renderer3D::setDirectionalLightShadowSize(int size)
  32213. {
  32214. size = std::min(std::max(256, size), 2048);
  32215. if (size != directionalShadows.shadowSize)
  32216. {
  32217. directionalShadows.shadowSize = size;
  32218. //internal.perFrameFlags.shouldupdatedi
  32219. }
  32220. }
  32221. #pragma endregion
  32222. #pragma region spot light
  32223. SpotLight Renderer3D::createSpotLight(glm::vec3 position, float fovRadians, glm::vec3 direction,
  32224. float dist, float attenuation, glm::vec3 color, float hardness, int castShadows)
  32225. {
  32226. int id = internal::generateNewIndex(internal.spotLightIndexes);
  32227. internal::GpuSpotLight light = {};
  32228. light.position = position;
  32229. fovRadians = glm::clamp(fovRadians, glm::radians(0.f), glm::radians(160.f));
  32230. fovRadians /= 2.f;
  32231. fovRadians = std::cos(fovRadians);
  32232. light.cosHalfAngle = fovRadians;
  32233. if (glm::length(direction) == 0)
  32234. {
  32235. direction = glm::vec3{0, -1, 0};
  32236. }
  32237. else
  32238. {
  32239. direction = glm::normalize(direction);
  32240. }
  32241. light.direction = direction;
  32242. light.dist = glm::max(0.f, dist);
  32243. light.attenuation = glm::max(attenuation, 0.f);
  32244. light.color = color;
  32245. light.hardness = glm::max(hardness, 0.001f);
  32246. light.castShadows = castShadows;
  32247. light.changedThisFrame = true;
  32248. if (castShadows)
  32249. {
  32250. internal.perFrameFlags.shouldUpdateSpotShadows = true;
  32251. }
  32252. internal.spotLightIndexes.push_back(id);
  32253. internal.spotLights.push_back(light);
  32254. SpotLight sl = {};
  32255. sl.id_ = id;
  32256. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  32257. sl.lastFoundPos_ = internal.spotLightIndexes.size() - 1;
  32258. #endif
  32259. return {sl};
  32260. }
  32261. //todo check
  32262. SpotLight Renderer3D::createSpotLight(glm::vec3 position, float fovRadians, glm::vec2 anglesRadians, float dist, float attenuation, glm::vec3 color, float hardness, int castShadows)
  32263. {
  32264. glm::vec3 direction = fromAnglesToDirection(anglesRadians.x, anglesRadians.y);
  32265. return createSpotLight(position, fovRadians, direction, dist, attenuation,
  32266. color, hardness, castShadows);
  32267. }
  32268. void Renderer3D::deleteSpotLight(SpotLight& l)
  32269. {
  32270. auto pos = internal.getSpotLightIndex(l);
  32271. if (pos < 0)
  32272. {
  32273. gl3dAssertComment(pos >= 0, "invalid delete spot light");
  32274. return;
  32275. }
  32276. if (internal.spotLights[pos].castShadows)
  32277. {
  32278. internal.perFrameFlags.shouldUpdateSpotShadows = true;
  32279. }
  32280. internal.spotLightIndexes.erase(internal.spotLightIndexes.begin() + pos);
  32281. internal.spotLights.erase(internal.spotLights.begin() + pos);
  32282. l.id_ = 0;
  32283. }
  32284. glm::vec3 Renderer3D::getSpotLightPosition(SpotLight& l)
  32285. {
  32286. auto i = internal.getSpotLightIndex(l);
  32287. if (i < 0) { return {}; } //warn or sthing
  32288. return internal.spotLights[i].position;
  32289. }
  32290. void Renderer3D::setSpotLightPosition(SpotLight& l, glm::vec3 position)
  32291. {
  32292. auto i = internal.getSpotLightIndex(l);
  32293. if (i < 0) { return ; } //warn or sthing
  32294. if (internal.spotLights[i].position != position)
  32295. {
  32296. internal.spotLights[i].position = position;
  32297. internal.spotLights[i].changedThisFrame = true;
  32298. }
  32299. }
  32300. bool Renderer3D::isSpotLight(SpotLight& l)
  32301. {
  32302. auto i = internal.getSpotLightIndex(l);
  32303. if (i < 0)
  32304. {
  32305. return false;
  32306. }
  32307. else
  32308. {
  32309. return true;
  32310. }
  32311. }
  32312. glm::vec3 Renderer3D::getSpotLightColor(SpotLight& l)
  32313. {
  32314. auto i = internal.getSpotLightIndex(l);
  32315. if (i < 0) { return {}; } //warn or sthing
  32316. return internal.spotLights[i].color;
  32317. }
  32318. void Renderer3D::setSpotLightColor(SpotLight& l, glm::vec3 color)
  32319. {
  32320. auto i = internal.getSpotLightIndex(l);
  32321. if (i < 0) { return; } //warn or sthing
  32322. internal.spotLights[i].color = color;
  32323. }
  32324. float Renderer3D::getSpotLightFov(SpotLight& l)
  32325. {
  32326. auto i = internal.getSpotLightIndex(l);
  32327. if (i < 0) { return {}; } //warn or sthing
  32328. float angle = internal.spotLights[i].cosHalfAngle;
  32329. angle = std::acos(angle);
  32330. angle *= 2;
  32331. return angle;
  32332. }
  32333. void Renderer3D::setSpotLightFov(SpotLight& l, float fovRadians)
  32334. {
  32335. auto i = internal.getSpotLightIndex(l);
  32336. if (i < 0) { return; } //warn or sthing
  32337. fovRadians = glm::clamp(fovRadians, glm::radians(0.f), glm::radians(160.f)); //todo magic number
  32338. fovRadians /= 2.f;
  32339. fovRadians = std::cos(fovRadians);
  32340. if(internal.spotLights[i].cosHalfAngle != fovRadians)
  32341. {
  32342. internal.spotLights[i].cosHalfAngle = fovRadians;
  32343. internal.spotLights[i].changedThisFrame= true;
  32344. }
  32345. }
  32346. glm::vec3 Renderer3D::getSpotLightDirection(SpotLight& l)
  32347. {
  32348. auto i = internal.getSpotLightIndex(l);
  32349. if (i < 0) { return {}; } //warn or sthing
  32350. return internal.spotLights[i].direction;
  32351. }
  32352. void Renderer3D::setSpotLightDirection(SpotLight& l, glm::vec3 direction)
  32353. {
  32354. auto i = internal.getSpotLightIndex(l);
  32355. if (i < 0) { return; } //warn or sthing
  32356. if (glm::length(direction) == 0)
  32357. {
  32358. direction = glm::vec3{ 0, -1, 0 };
  32359. }
  32360. else
  32361. {
  32362. direction = glm::normalize(direction);
  32363. }
  32364. if (internal.spotLights[i].direction != direction)
  32365. {
  32366. internal.spotLights[i].direction = direction;
  32367. internal.spotLights[i].changedThisFrame = true;
  32368. }
  32369. }
  32370. float Renderer3D::getSpotLightDistance(SpotLight& l)
  32371. {
  32372. auto i = internal.getSpotLightIndex(l);
  32373. if (i < 0) { return {}; } //warn or sthing
  32374. return internal.spotLights[i].dist;
  32375. }
  32376. void Renderer3D::setSpotLightDistance(SpotLight& l, float distance)
  32377. {
  32378. auto i = internal.getSpotLightIndex(l);
  32379. if (i < 0) { return; } //warn or sthing
  32380. distance = glm::max(0.f, distance);
  32381. if (internal.spotLights[i].dist != distance)
  32382. {
  32383. internal.spotLights[i].dist = distance;
  32384. internal.spotLights[i].changedThisFrame = true;
  32385. }
  32386. }
  32387. float Renderer3D::getSpotLightAttenuation(SpotLight& l)
  32388. {
  32389. auto i = internal.getSpotLightIndex(l);
  32390. if (i < 0) { return {}; } //warn or sthing
  32391. return internal.spotLights[i].attenuation;
  32392. }
  32393. void Renderer3D::setSpotLightAttenuation(SpotLight& l, float attenuation)
  32394. {
  32395. auto i = internal.getSpotLightIndex(l);
  32396. if (i < 0) { return; } //warn or sthing
  32397. internal.spotLights[i].attenuation = glm::max(attenuation, 0.f);
  32398. }
  32399. float Renderer3D::getSpotLightHardness(SpotLight& l)
  32400. {
  32401. auto i = internal.getSpotLightIndex(l);
  32402. if (i < 0) { return {}; } //warn or sthing
  32403. return internal.spotLights[i].hardness;
  32404. }
  32405. void Renderer3D::setSpotLightHardness(SpotLight& l, float hardness)
  32406. {
  32407. auto i = internal.getSpotLightIndex(l);
  32408. if (i < 0) { return; } //warn or sthing
  32409. internal.spotLights[i].hardness = glm::max(hardness, 0.001f);
  32410. }
  32411. void Renderer3D::setSpotLightShadows(SpotLight& l, bool castShadows)
  32412. {
  32413. auto i = internal.getSpotLightIndex(l);
  32414. if (i < 0) { return; } //warn or sthing
  32415. if (internal.spotLights[i].castShadows != castShadows)
  32416. {
  32417. internal.spotLights[i].castShadows = castShadows;
  32418. internal.spotLights[i].changedThisFrame = true;
  32419. internal.perFrameFlags.shouldUpdateSpotShadows = true;
  32420. }
  32421. }
  32422. bool Renderer3D::getSpotLightShadows(SpotLight& l)
  32423. {
  32424. auto i = internal.getSpotLightIndex(l);
  32425. if (i < 0) { return {}; } //warn or sthing
  32426. return internal.spotLights[i].castShadows;
  32427. }
  32428. int Renderer3D::getSpotLightShadowSize()
  32429. {
  32430. return spotShadows.shadowSize;
  32431. }
  32432. void Renderer3D::setSpotLightShadowSize(int size)
  32433. {
  32434. size = std::min(std::max(256, size), 2048);
  32435. if (spotShadows.shadowSize != size)
  32436. {
  32437. spotShadows.shadowSize = size;
  32438. internal.perFrameFlags.shouldUpdateSpotShadows = true;
  32439. }
  32440. }
  32441. #pragma endregion
  32442. Entity Renderer3D::createEntity(Model m, Transform transform,
  32443. bool staticGeometry, bool visible, bool castShadows)
  32444. {
  32445. int id = internal::generateNewIndex(internal.entitiesIndexes);
  32446. CpuEntity entity;
  32447. entity.allocateGpuData();
  32448. entity.transform = transform;
  32449. entity.setStatic(staticGeometry);
  32450. entity.setVisible(visible);
  32451. entity.setCastShadows(castShadows);
  32452. internal.entitiesIndexes.push_back(id);
  32453. internal.cpuEntities.push_back(std::move(entity));
  32454. if (staticGeometry && visible && castShadows)
  32455. {
  32456. internal.perFrameFlags.staticGeometryChanged = true;
  32457. }
  32458. Entity e;
  32459. e.id_ = id;
  32460. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  32461. e.lastFoundPos_ = internal.entitiesIndexes.size() - 1;
  32462. #endif
  32463. setEntityModel(e, m);
  32464. return e;
  32465. }
  32466. Entity Renderer3D::duplicateEntity(Entity& e)
  32467. {
  32468. int oldIndex = internal.getEntityIndex(e);
  32469. if (oldIndex < 0)
  32470. {
  32471. return {};
  32472. }
  32473. int id = internal::generateNewIndex(internal.entitiesIndexes);
  32474. CpuEntity entity;
  32475. entity.allocateGpuData();
  32476. entity.transform = internal.cpuEntities[oldIndex].transform;
  32477. entity.flags = internal.cpuEntities[oldIndex].flags;
  32478. entity.subModelsNames.reserve(internal.cpuEntities[oldIndex].subModelsNames.size());
  32479. for (auto i : internal.cpuEntities[oldIndex].subModelsNames)
  32480. {
  32481. int size = strlen(i);
  32482. char* c = new char[size] {};
  32483. strcpy(c, i);
  32484. entity.subModelsNames.push_back(c);
  32485. }
  32486. entity.models.reserve(internal.cpuEntities[oldIndex].models.size());
  32487. for (auto i : internal.cpuEntities[oldIndex].models)
  32488. {
  32489. GraphicModel model = i;
  32490. if (model.ownMaterial)
  32491. {
  32492. model.material = createMaterial(frameBuffer);
  32493. this->copyMaterialData(model.material, i.material);
  32494. }
  32495. entity.models.push_back(std::move(model));
  32496. }
  32497. internal.entitiesIndexes.push_back(id);
  32498. internal.cpuEntities.push_back(std::move(entity));
  32499. Entity ret;
  32500. ret.id_ = id;
  32501. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  32502. ret.lastFoundPos_ = internal.entitiesIndexes.size() - 1;
  32503. #endif
  32504. return {ret};
  32505. }
  32506. void Renderer3D::setEntityModel(Entity& e, Model m)
  32507. {
  32508. auto i = internal.getEntityIndex(e);
  32509. if (i < 0) { return; } //warn
  32510. clearEntityModel(e);
  32511. auto& entity = internal.cpuEntities[i];
  32512. //clear if needed
  32513. int modelindex = internal.getModelIndex(m);
  32514. if (modelindex >= 0)
  32515. {
  32516. int size = internal.graphicModels[modelindex].models.size();
  32517. entity.models.reserve(size);
  32518. entity.animations = internal.graphicModels[modelindex].animations;
  32519. entity.joints = internal.graphicModels[modelindex].joints;
  32520. for (int i = 0; i < size; i++)
  32521. {
  32522. entity.models.push_back(internal.graphicModels[modelindex].models[i]);
  32523. entity.models.back().ownMaterial = false;
  32524. int charSize = strlen(internal.graphicModels[modelindex].subModelsNames[i]);
  32525. char* name = new char[charSize + 1]{};
  32526. strcpy(name, internal.graphicModels[modelindex].subModelsNames[i]);
  32527. entity.subModelsNames.push_back(name);
  32528. }
  32529. }
  32530. }
  32531. void Renderer3D::clearEntityModel(Entity& e)
  32532. {
  32533. auto i = internal.getEntityIndex(e);
  32534. if (i < 0) { return ; } //warn
  32535. auto& entity = internal.cpuEntities[i];
  32536. if (entity.isStatic() && entity.isVisible())
  32537. {
  32538. internal.perFrameFlags.staticGeometryChanged = true;
  32539. }
  32540. for (auto& i : entity.subModelsNames)
  32541. {
  32542. delete[] i;
  32543. }
  32544. for (auto& i : entity.models)
  32545. {
  32546. if (i.ownMaterial)
  32547. {
  32548. this->deleteMaterial(i.material);
  32549. }
  32550. }
  32551. entity.models.clear();
  32552. entity.subModelsNames.clear();
  32553. }
  32554. CpuEntity* Renderer3D::getEntityData(Entity &e)
  32555. {
  32556. auto i = internal.getEntityIndex(e);
  32557. if (i < 0) { return nullptr; }
  32558. return &internal.cpuEntities[i];
  32559. }
  32560. Transform Renderer3D::getEntityTransform(Entity &e)
  32561. {
  32562. auto i = internal.getEntityIndex(e);
  32563. if (i < 0) { return Transform{}; } //warn or sthing
  32564. return internal.cpuEntities[i].transform;
  32565. }
  32566. void Renderer3D::setEntityTransform(Entity &e, Transform transform)
  32567. {
  32568. auto i = internal.getEntityIndex(e);
  32569. if (i < 0) { return; } //warn or sthing
  32570. if (internal.cpuEntities[i].isStatic())
  32571. {
  32572. if (internal.cpuEntities[i].transform != transform)
  32573. {
  32574. internal.perFrameFlags.staticGeometryChanged = true;
  32575. };
  32576. }
  32577. internal.cpuEntities[i].transform = transform;
  32578. }
  32579. bool Renderer3D::isEntityStatic(Entity &e)
  32580. {
  32581. auto i = internal.getEntityIndex(e);
  32582. if (i < 0) { return 0; } //warn or sthing
  32583. return internal.cpuEntities[i].isStatic();
  32584. }
  32585. void Renderer3D::setEntityStatic(Entity &e, bool s)
  32586. {
  32587. auto i = internal.getEntityIndex(e);
  32588. if (i < 0) { return; } //warn or sthing
  32589. auto &en = internal.cpuEntities[i];
  32590. if (en.animate()) //entities that animate can't be static
  32591. {
  32592. s = false;
  32593. }
  32594. if ((en.isStatic() != s)
  32595. && en.isVisible()
  32596. && en.castShadows()
  32597. )
  32598. {
  32599. internal.perFrameFlags.staticGeometryChanged = true;
  32600. }
  32601. en.setStatic(s);
  32602. }
  32603. void Renderer3D::deleteEntity(Entity &e)
  32604. {
  32605. auto pos = internal.getEntityIndex(e);
  32606. if (pos < 0)
  32607. {
  32608. gl3dAssertComment(pos >= 0, "invalid delete entity");
  32609. return;
  32610. }
  32611. clearEntityModel(e);
  32612. if (internal.cpuEntities[pos].isStatic())
  32613. {
  32614. internal.perFrameFlags.staticGeometryChanged = true;
  32615. }
  32616. internal.cpuEntities[pos].deleteGpuData();
  32617. internal.entitiesIndexes.erase(internal.entitiesIndexes.begin() + pos);
  32618. internal.cpuEntities.erase(internal.cpuEntities.begin() + pos);
  32619. e.id_ = 0;
  32620. }
  32621. int Renderer3D::getEntityMeshesCount(Entity& e)
  32622. {
  32623. auto i = internal.getEntityIndex(e);
  32624. if (i < 0) { return 0; } //warn or sthing
  32625. return internal.cpuEntities[i].models.size();
  32626. }
  32627. MaterialValues Renderer3D::getEntityMeshMaterialValues(Entity& e, int meshIndex)
  32628. {
  32629. auto i = internal.getEntityIndex(e);
  32630. if (i < 0) { return {}; } //warn or sthing
  32631. if (meshIndex < internal.cpuEntities[i].models.size())
  32632. {
  32633. auto mat = internal.cpuEntities[i].models[meshIndex].material;
  32634. MaterialValues data = {};
  32635. bool succeeded = internal.getMaterialData(mat, &data, nullptr, nullptr);
  32636. if (succeeded)
  32637. {
  32638. return data;
  32639. }
  32640. else
  32641. {
  32642. return {}; //warn
  32643. }
  32644. }
  32645. else
  32646. {
  32647. return {}; //warn
  32648. }
  32649. }
  32650. void Renderer3D::setEntityMeshMaterialValues(Entity& e, int meshIndex, MaterialValues mat)
  32651. {
  32652. auto i = internal.getEntityIndex(e);
  32653. if (i < 0) { return ; } //warn or sthing
  32654. if (meshIndex < internal.cpuEntities[i].models.size())
  32655. {
  32656. auto currentMat = internal.cpuEntities[i].models[meshIndex].material;
  32657. MaterialValues data = {};
  32658. std::string name = {};
  32659. TextureDataForMaterial textures;
  32660. bool succeeded = internal.getMaterialData(currentMat, &data, &name, &textures);
  32661. if (succeeded)
  32662. {
  32663. if (internal.cpuEntities[i].models[meshIndex].ownMaterial == 1)
  32664. {
  32665. setMaterialValues(currentMat, mat);
  32666. }else
  32667. if (mat != data)
  32668. {
  32669. Material newMat = this->createMaterial(TextureLoadQuality::dontSet, mat.kd, mat.roughness,
  32670. mat.metallic, mat.ao, mat.emmisive, name);
  32671. int newMatIndex = internal.getMaterialIndex(newMat); //this should not fail
  32672. internal.materialTexturesData[newMatIndex] = textures;
  32673. internal.cpuEntities[i].models[meshIndex].material = newMat;
  32674. internal.cpuEntities[i].models[meshIndex].ownMaterial = 1;
  32675. }
  32676. }
  32677. else
  32678. {
  32679. return ; //warn
  32680. }
  32681. }
  32682. else
  32683. {
  32684. return ; //warn
  32685. }
  32686. }
  32687. std::string Renderer3D::getEntityMeshMaterialName(Entity& e, int meshIndex)
  32688. {
  32689. auto i = internal.getEntityIndex(e);
  32690. if (i < 0) { return {}; } //no valid entity
  32691. if (meshIndex < internal.cpuEntities[i].models.size())
  32692. {
  32693. auto currentMat = internal.cpuEntities[i].models[meshIndex].material;
  32694. std::string name = {};
  32695. bool succeeded = internal.getMaterialData(currentMat, nullptr, &name, nullptr);
  32696. if (succeeded)
  32697. {
  32698. return name;
  32699. }
  32700. else
  32701. {
  32702. return{};//no valid material
  32703. }
  32704. }
  32705. else
  32706. {
  32707. return {};//wrong index
  32708. }
  32709. }
  32710. void Renderer3D::setEntityMeshMaterialName(Entity& e, int meshIndex, const std::string& name)
  32711. {
  32712. auto i = internal.getEntityIndex(e);
  32713. if (i < 0) { return; } //warn or sthing
  32714. if (meshIndex < internal.cpuEntities[i].models.size())
  32715. {
  32716. auto currentMat = internal.cpuEntities[i].models[meshIndex].material;
  32717. MaterialValues data = {};
  32718. std::string oldName = {};
  32719. TextureDataForMaterial textures;
  32720. bool succeeded = internal.getMaterialData(currentMat, &data, &oldName, &textures);
  32721. if (succeeded)
  32722. {
  32723. if (internal.cpuEntities[i].models[meshIndex].ownMaterial == 1)
  32724. {
  32725. setMaterialName(currentMat, name);
  32726. }
  32727. else
  32728. if (name != oldName) //copy to new material
  32729. {
  32730. Material newMat = this->createMaterial(TextureLoadQuality::dontSet, data.kd, data.roughness,
  32731. data.metallic, data.ao, data.emmisive, name);
  32732. int newMatIndex = internal.getMaterialIndex(newMat); //this should not fail
  32733. internal.materialTexturesData[newMatIndex] = textures;
  32734. internal.cpuEntities[i].models[meshIndex].material = newMat;
  32735. internal.cpuEntities[i].models[meshIndex].ownMaterial = 1;
  32736. }
  32737. }
  32738. else
  32739. {
  32740. return; //warn
  32741. }
  32742. }
  32743. else
  32744. {
  32745. return; //warn
  32746. }
  32747. }
  32748. void Renderer3D::setEntityMeshMaterial(Entity& e, int meshIndex, Material mat)
  32749. {
  32750. auto i = internal.getEntityIndex(e);
  32751. if (i < 0) { return; } //invalid entity;
  32752. if (meshIndex < internal.cpuEntities[i].models.size())
  32753. {
  32754. if (internal.cpuEntities[i].models[meshIndex].ownMaterial)
  32755. {
  32756. deleteMaterial(internal.cpuEntities[i].models[meshIndex].material);
  32757. }
  32758. internal.cpuEntities[i].models[meshIndex].material = mat;
  32759. internal.cpuEntities[i].models[meshIndex].ownMaterial = 0;
  32760. //todo look into textures and see if they have alpha data
  32761. if (
  32762. internal.cpuEntities[i].isStatic()
  32763. && internal.cpuEntities[i].castShadows()
  32764. &&internal.cpuEntities[i].isVisible()
  32765. )
  32766. {
  32767. internal.perFrameFlags.staticGeometryChanged = true;
  32768. }
  32769. }
  32770. }
  32771. TextureDataForMaterial Renderer3D::getEntityMeshMaterialTextures(Entity& e, int meshIndex)
  32772. {
  32773. auto i = internal.getEntityIndex(e);
  32774. if (i < 0) { return {}; } //no valid entity
  32775. if (meshIndex < internal.cpuEntities[i].models.size())
  32776. {
  32777. auto currentMat = internal.cpuEntities[i].models[meshIndex].material;
  32778. TextureDataForMaterial t= {};
  32779. bool succeeded = internal.getMaterialData(currentMat, nullptr, nullptr, &t);
  32780. if (succeeded)
  32781. {
  32782. return t;
  32783. }
  32784. else
  32785. {
  32786. return{};//invalid material
  32787. }
  32788. }
  32789. else
  32790. {
  32791. return {};//invalid index
  32792. }
  32793. }
  32794. void Renderer3D::setEntityMeshMaterialTextures(Entity& e, int meshIndex, TextureDataForMaterial texture)
  32795. {
  32796. auto i = internal.getEntityIndex(e);
  32797. if (i < 0) { return; } //warn or sthing
  32798. if (meshIndex < internal.cpuEntities[i].models.size())
  32799. {
  32800. auto currentMat = internal.cpuEntities[i].models[meshIndex].material;
  32801. MaterialValues data = {};
  32802. std::string oldName = {};
  32803. TextureDataForMaterial oldTextures;
  32804. bool succeeded = internal.getMaterialData(currentMat, &data, &oldName, &oldTextures);
  32805. if (succeeded)
  32806. {
  32807. if (internal.cpuEntities[i].models[meshIndex].ownMaterial == 1)
  32808. {
  32809. setMaterialTextures(currentMat, texture);
  32810. }
  32811. else
  32812. if (texture != oldTextures) //copy to new material
  32813. {
  32814. Material newMat = this->createMaterial(TextureLoadQuality::dontSet, data.kd, data.roughness,
  32815. data.metallic, data.ao, data.emmisive, oldName);
  32816. int newMatIndex = internal.getMaterialIndex(newMat); //this should not fail
  32817. internal.materialTexturesData[newMatIndex] = texture; //new textures
  32818. internal.cpuEntities[i].models[meshIndex].material = newMat;
  32819. internal.cpuEntities[i].models[meshIndex].ownMaterial = 1;
  32820. }
  32821. }
  32822. else
  32823. {
  32824. return; //warn
  32825. }
  32826. }
  32827. else
  32828. {
  32829. return; //warn
  32830. }
  32831. }
  32832. bool Renderer3D::isEntity(Entity& e)
  32833. {
  32834. auto i = internal.getEntityIndex(e);
  32835. if (i < 0)
  32836. {
  32837. return false;
  32838. }
  32839. else
  32840. {
  32841. return true;
  32842. }
  32843. }
  32844. bool Renderer3D::isEntityVisible(Entity& e)
  32845. {
  32846. auto i = internal.getEntityIndex(e);
  32847. if (i < 0) { return 0; } //warn or sthing
  32848. return internal.cpuEntities[i].isVisible();
  32849. }
  32850. void Renderer3D::setEntityVisible(Entity& e, bool v)
  32851. {
  32852. auto i = internal.getEntityIndex(e);
  32853. if (i < 0) { return; } //warn or sthing
  32854. if (internal.cpuEntities[i].isVisible() != v)
  32855. {
  32856. internal.cpuEntities[i].setVisible(v);
  32857. if (internal.cpuEntities[i].isStatic()
  32858. && internal.cpuEntities[i].castShadows()
  32859. )
  32860. {
  32861. internal.perFrameFlags.staticGeometryChanged = true;
  32862. }
  32863. }
  32864. }
  32865. void Renderer3D::setEntityCastShadows(Entity& e, bool s)
  32866. {
  32867. auto i = internal.getEntityIndex(e);
  32868. if (i < 0) { return; } //warn or sthing
  32869. if(
  32870. internal.cpuEntities[i].isVisible()
  32871. && internal.cpuEntities[i].isStatic()
  32872. && (s != internal.cpuEntities[i].castShadows())
  32873. )
  32874. {
  32875. internal.perFrameFlags.staticGeometryChanged = true;
  32876. }
  32877. internal.cpuEntities[i].setCastShadows(s);
  32878. }
  32879. bool Renderer3D::getEntityCastShadows(Entity& e)
  32880. {
  32881. auto i = internal.getEntityIndex(e);
  32882. if (i < 0) { return 0; } //warn or sthing
  32883. return internal.cpuEntities[i].castShadows();
  32884. }
  32885. void Renderer3D::setEntityAnimationIndex(Entity &e, int ind)
  32886. {
  32887. auto i = internal.getEntityIndex(e);
  32888. if (i < 0) { return; } //warn or sthing
  32889. if (internal.cpuEntities[i].animationIndex != ind)
  32890. {
  32891. if (ind < 0 || ind >= internal.cpuEntities[i].animations.size())
  32892. {
  32893. return; //warn or sthing
  32894. }
  32895. internal.cpuEntities[i].totalTimePassed = 0;
  32896. internal.cpuEntities[i].animationIndex = ind;
  32897. }
  32898. }
  32899. void Renderer3D::transitionToAnimation(Entity& e, int newAnimationIndex, float transitionTimeSecconds,
  32900. float newAnimationTimeStampSecconds)
  32901. {
  32902. auto i = internal.getEntityIndex(e);
  32903. if (i < 0) { return; } //warn or sthing
  32904. auto& ent = internal.cpuEntities[i];
  32905. if (newAnimationIndex < 0 || newAnimationIndex >= ent.animations.size())
  32906. {
  32907. return; //warn or sthing
  32908. }
  32909. ent.animationTransition.remainintgTime = transitionTimeSecconds;
  32910. ent.animationTransition.totalTime = transitionTimeSecconds;
  32911. ent.animationTransition.ToTime = newAnimationTimeStampSecconds;
  32912. ent.animationTransition.ToIndex = newAnimationIndex;
  32913. }
  32914. int Renderer3D::getEntityAnimationIndex(Entity &e)
  32915. {
  32916. auto i = internal.getEntityIndex(e);
  32917. if (i < 0) { return 0; } //warn or sthing
  32918. return internal.cpuEntities[i].animationIndex;
  32919. }
  32920. void Renderer3D::setEntityAnimationSpeed(Entity &e, float speed)
  32921. {
  32922. auto i = internal.getEntityIndex(e);
  32923. if (i < 0) { return; } //warn or sthing
  32924. if (speed < 0) { speed = 0; } //todo negative speed mabe?
  32925. internal.cpuEntities[i].animationSpeed = speed;
  32926. }
  32927. float Renderer3D::getEntityAnimationSpeed(Entity &e)
  32928. {
  32929. auto i = internal.getEntityIndex(e);
  32930. if (i < 0) { return 0; } //warn or sthing
  32931. return internal.cpuEntities[i].animationSpeed;
  32932. }
  32933. std::vector<char*> *Renderer3D::getEntityMeshesNames(Entity& e)
  32934. {
  32935. auto i = internal.getEntityIndex(e);
  32936. if (i < 0) { return nullptr; } //warn or sthing
  32937. return &internal.cpuEntities[i].subModelsNames;
  32938. }
  32939. void Renderer3D::setEntityAnimate(Entity& e, bool animate)
  32940. {
  32941. auto i = internal.getEntityIndex(e);
  32942. if (i < 0) { return; } //warn or sthing
  32943. auto& en = internal.cpuEntities[i];
  32944. if (en.canBeAnimated())
  32945. {
  32946. en.setAnimate(animate);
  32947. if (animate && en.isStatic())
  32948. {
  32949. setEntityStatic(e, false);
  32950. }
  32951. }
  32952. }
  32953. bool Renderer3D::getEntityAnimate(Entity& e)
  32954. {
  32955. auto i = internal.getEntityIndex(e);
  32956. if (i < 0) { return 0; } //warn or sthing
  32957. auto& en = internal.cpuEntities[i];
  32958. return en.animate() && en.canBeAnimated();
  32959. }
  32960. bool Renderer3D::entityCanAnimate(Entity& e)
  32961. {
  32962. auto i = internal.getEntityIndex(e);
  32963. if (i < 0) { return 0; } //warn or sthing
  32964. auto& en = internal.cpuEntities[i];
  32965. return en.canBeAnimated();
  32966. }
  32967. int Renderer3D::getEntityJointIndex(Entity &e, std::string name)
  32968. {
  32969. auto i = internal.getEntityIndex(e);
  32970. if (i < 0) { return -1; } //warn or sthing
  32971. auto &en = internal.cpuEntities[i];
  32972. int index = 0;
  32973. for (auto &j : en.joints)
  32974. {
  32975. if (j.name == name)
  32976. {
  32977. return index;
  32978. }
  32979. index++;
  32980. }
  32981. return -1;
  32982. }
  32983. bool Renderer3D::getEntityJointTransform(Entity &e, std::string boneName, Transform &t)
  32984. {
  32985. return getEntityJointTransform(e, getEntityJointIndex(e, boneName), t);
  32986. }
  32987. bool Renderer3D::getEntityJointTransform(Entity &e, int boneIndex, Transform &t)
  32988. {
  32989. t = {};
  32990. if (boneIndex < 0) { return false; }
  32991. auto i = internal.getEntityIndex(e);
  32992. if (i < 0) { return -1; } //warn or sthing
  32993. auto &en = internal.cpuEntities[i];
  32994. if (en.joints.size() <= boneIndex)
  32995. {
  32996. return false;
  32997. }
  32998. glm::mat4 beginPos = en.joints[boneIndex].localBindTransform;
  32999. if (!en.animate())
  33000. {
  33001. //t.position = en.joints[boneIndex].trans;
  33002. //t.scale = en.joints[boneIndex].scale;
  33003. //t.rotation = glm::eulerAngles(en.joints[boneIndex].rotation);
  33004. //glm::mat4 mat = t.getTransformMatrix();
  33005. glm::mat4 mat = beginPos;
  33006. mat = getTransformMatrix(en.transform) * mat;
  33007. t.setFromMatrix(mat);
  33008. return true;
  33009. }
  33010. else
  33011. {
  33012. glm::mat4 mat = en.joints[boneIndex].worldMatrix;
  33013. mat = getTransformMatrix(en.transform) * mat * beginPos;
  33014. t.setFromMatrix(mat);
  33015. return true;
  33016. }
  33017. }
  33018. void Renderer3D::setExposure(float exposure)
  33019. {
  33020. internal.lightShader.lightPassUniformBlockCpuData.exposure =
  33021. std::max(exposure, 0.001f);
  33022. }
  33023. float Renderer3D::getExposure()
  33024. {
  33025. return internal.lightShader.lightPassUniformBlockCpuData.exposure;
  33026. }
  33027. void Renderer3D::enableNormalMapping(bool normalMapping)
  33028. {
  33029. internal.lightShader.normalMap = normalMapping;
  33030. }
  33031. bool Renderer3D::isNormalMappingEnabeled()
  33032. {
  33033. return internal.lightShader.normalMap;
  33034. }
  33035. void Renderer3D::enableLightSubScattering(bool lightSubScatter)
  33036. {
  33037. internal.lightShader.lightPassUniformBlockCpuData.lightSubScater = lightSubScatter;
  33038. }
  33039. bool Renderer3D::isLightSubScatteringEnabeled()
  33040. {
  33041. return internal.lightShader.lightPassUniformBlockCpuData.lightSubScater;
  33042. }
  33043. void Renderer3D::enableSSAO(bool ssao)
  33044. {
  33045. internal.lightShader.useSSAO = ssao;
  33046. }
  33047. bool &Renderer3D::isSSAOenabeled()
  33048. {
  33049. return internal.lightShader.useSSAO;
  33050. }
  33051. float &Renderer3D::getSSAOBias()
  33052. {
  33053. return internal.ssao.ssaoShaderUniformBlockData.bias;
  33054. }
  33055. void Renderer3D::setSSAOBias(float bias)
  33056. {
  33057. internal.ssao.ssaoShaderUniformBlockData.bias = std::max(bias, 0.f);
  33058. }
  33059. float &Renderer3D::getSSAORadius()
  33060. {
  33061. return internal.ssao.ssaoShaderUniformBlockData.radius;
  33062. }
  33063. void Renderer3D::setSSAORadius(float radius)
  33064. {
  33065. internal.ssao.ssaoShaderUniformBlockData.radius = std::max(radius, 0.01f);
  33066. }
  33067. int &Renderer3D::getSSAOSampleCount()
  33068. {
  33069. return internal.ssao.ssaoShaderUniformBlockData.samplesTestSize;
  33070. }
  33071. void Renderer3D::setSSAOSampleCount(int samples)
  33072. {
  33073. internal.ssao.ssaoShaderUniformBlockData.samplesTestSize = std::min(std::max(samples, 5), 64);
  33074. }
  33075. float &Renderer3D::getSSAOExponent()
  33076. {
  33077. return internal.ssao.ssao_finalColor_exponent;
  33078. }
  33079. void Renderer3D::setSSAOExponent(float exponent)
  33080. {
  33081. internal.ssao.ssao_finalColor_exponent = std::min(std::max(1.f, exponent), 64.f);
  33082. }
  33083. bool &Renderer3D::colorCorrection()
  33084. {
  33085. return internal.colorCorrection.colorCorrection;
  33086. }
  33087. ColorLookupTexture &Renderer3D::colorCorrectionTexture()
  33088. {
  33089. return internal.colorCorrection.currentTexture;
  33090. }
  33091. bool &Renderer3D::bloom()
  33092. {
  33093. return this->internal.lightShader.bloom;
  33094. }
  33095. float Renderer3D::getBloomTresshold()
  33096. {
  33097. return this->internal.lightShader.lightPassUniformBlockCpuData.bloomTresshold;
  33098. }
  33099. void Renderer3D::setBloomTresshold(float b)
  33100. {
  33101. b = std::max(b, 0.f);
  33102. b = std::min(b, 1.0f);
  33103. this->internal.lightShader.lightPassUniformBlockCpuData.bloomTresshold = b;
  33104. }
  33105. void Renderer3D::setBloomIntensisy(float b)
  33106. {
  33107. b = std::max(b, 0.f);
  33108. b = std::min(b, 15.0f);
  33109. this->postProcess.bloomIntensty = b;
  33110. }
  33111. bool &Renderer3D::bloomHighQualityDownSample()
  33112. {
  33113. return this->postProcess.highQualityDownSample;
  33114. }
  33115. bool &Renderer3D::bloomHighQualityUpSample()
  33116. {
  33117. return this->postProcess.highQualityUpSample;
  33118. }
  33119. LightShader::LightPassData::SSRdata &Renderer3D::getSSRdata()
  33120. {
  33121. return internal.lightShader.lightPassUniformBlockCpuData.SSR;
  33122. }
  33123. void Renderer3D::setSSRdata(LightShader::LightPassData::SSRdata data)
  33124. {
  33125. data.maxRayDelta = glm::clamp(data.maxRayDelta, 0.0001f, 2.f);
  33126. data.maxRayStep = glm::clamp(data.maxRayStep, 0.01f, 5.f);
  33127. data.maxSteps = glm::clamp(data.maxSteps, 5, 150);
  33128. data.minRayStep = glm::clamp(data.minRayStep, 0.001f, 1.f);
  33129. data.numBinarySearchSteps = glm::clamp(data.numBinarySearchSteps, 2, 20);
  33130. internal.lightShader.lightPassUniformBlockCpuData.SSR = data;
  33131. }
  33132. void Renderer3D::enableSSR(bool enable)
  33133. {
  33134. internal.hasLastFrameTexture = enable;
  33135. }
  33136. bool Renderer3D::isSSRenabeled()
  33137. {
  33138. return internal.hasLastFrameTexture;
  33139. }
  33140. float stub = 0;
  33141. float &Renderer3D::getDirectionalShadowCascadesFrustumSplit(int cascadeIndex)
  33142. {
  33143. if (cascadeIndex >= DirectionalShadows::CASCADES || cascadeIndex < 0)
  33144. {
  33145. errorReporter.callErrorCallback("index out of cascades range");
  33146. stub = 0;
  33147. return stub;
  33148. }
  33149. return directionalShadows.frustumSplits[cascadeIndex];
  33150. // TODO: insert return statement here
  33151. }
  33152. bool &Renderer3D::chromaticAberationEnabeled()
  33153. {
  33154. return postProcess.chromaticAberationOn;
  33155. }
  33156. float Renderer3D::getChromaticAberationStrength()
  33157. {
  33158. return postProcess.chromaticAberationStrength;
  33159. }
  33160. void Renderer3D::setChromaticAberationStrength(float pixels)
  33161. {
  33162. postProcess.chromaticAberationStrength = std::max(0.f, pixels);
  33163. }
  33164. float Renderer3D::getChromaticAberationUnfocusDistance()
  33165. {
  33166. return postProcess.unfocusDistance;
  33167. }
  33168. void Renderer3D::setChromaticAberationUnfocusDistance(float distance)
  33169. {
  33170. postProcess.unfocusDistance = std::max(distance, 0.f);
  33171. }
  33172. void Renderer3D::enableFXAA(bool fxaa)
  33173. {
  33174. this->antiAlias.usingFXAA = fxaa;
  33175. }
  33176. Renderer3D::FXAAData& Renderer3D::getFxaaSettings()
  33177. {
  33178. return antiAlias.fxaaData;
  33179. }
  33180. bool &Renderer3D::isFXAAenabeled()
  33181. {
  33182. return antiAlias.usingFXAA;
  33183. }
  33184. //todo flags
  33185. std::string Renderer3D::saveSettingsToJson(bool includeRenderingSettings, std::string skyBoxName,
  33186. gl3d::AtmosfericScatteringSettings *atmosphericScattering)
  33187. {
  33188. using Json = nlohmann::json;
  33189. Json j;
  33190. if (!skyBoxName.empty())
  33191. {
  33192. j["sky box"] = skyBoxName;
  33193. }
  33194. if (atmosphericScattering != nullptr)
  33195. {
  33196. Json a;
  33197. a["sunx"] = atmosphericScattering->sun.x;
  33198. a["suny"] = atmosphericScattering->sun.y;
  33199. a["sunz"] = atmosphericScattering->sun.z;
  33200. a["color1x"] = atmosphericScattering->color1.x;
  33201. a["color1y"] = atmosphericScattering->color1.y;
  33202. a["color1z"] = atmosphericScattering->color1.z;
  33203. a["color2x"] = atmosphericScattering->color2.x;
  33204. a["color2y"] = atmosphericScattering->color2.y;
  33205. a["color2z"] = atmosphericScattering->color2.z;
  33206. a["groundx"] = atmosphericScattering->ground.x;
  33207. a["groundy"] = atmosphericScattering->ground.y;
  33208. a["groundz"] = atmosphericScattering->ground.z;
  33209. a["g"] = atmosphericScattering->g;
  33210. a["useGround"] = atmosphericScattering->useGroundColor;
  33211. j["atmosphericScattering"] = a;
  33212. }
  33213. //if (!skyBoxName.empty() || atmosphericScattering != nullptr)
  33214. {
  33215. j["ambientr"] = skyBox.color.r;
  33216. j["ambientg"] = skyBox.color.g;
  33217. j["ambientb"] = skyBox.color.b;
  33218. }
  33219. if (includeRenderingSettings)
  33220. {
  33221. j["exposure"] = getExposure();
  33222. j["normal mapping"] = isNormalMappingEnabeled();
  33223. j["light subscatter"] = isLightSubScatteringEnabeled();
  33224. j["colorCorrection"] = colorCorrection();
  33225. //fxaa
  33226. {
  33227. j["fxaa"] = isFXAAenabeled();
  33228. Json fxaaData;
  33229. auto data = getFxaaSettings();
  33230. fxaaData["edgeDarkTreshold"] = data.edgeDarkTreshold;
  33231. fxaaData["edgeMinTreshold"] = data.edgeMinTreshold;
  33232. fxaaData["qualityMultiplyer"] = data.quaityMultiplier;
  33233. fxaaData["iterations"] = data.ITERATIONS;
  33234. fxaaData["subPixelQuality"] = data.SUBPIXEL_QUALITY;
  33235. j["fxaaData"] = fxaaData;
  33236. }
  33237. //todo separate thing
  33238. j["adaptiveResolution"] = adaptiveResolution.useAdaptiveResolution; //todo setter getter
  33239. //j["zprePass"] = zPrePass; //todo setter getter //todo add back if will be used
  33240. j["frustumCulling"] = frustumCulling;
  33241. //ssao
  33242. {
  33243. j["ssao"] = isSSAOenabeled();
  33244. Json ssaoData;
  33245. ssaoData["bias"] = getSSAOBias();
  33246. ssaoData["radius"] = getSSAORadius();
  33247. ssaoData["sampleCount"] = getSSAOSampleCount();
  33248. ssaoData["exponent"] = getSSAOExponent();
  33249. j["ssaoData"] = ssaoData;
  33250. }
  33251. //chromatic aberation
  33252. {
  33253. j["chromaticAberation"] = chromaticAberationEnabeled();
  33254. Json chromaticAberationData;
  33255. chromaticAberationData["strength"] = getChromaticAberationStrength();
  33256. chromaticAberationData["unfocusDistance"] = getChromaticAberationUnfocusDistance();
  33257. j["chromaticAberationData"] = chromaticAberationData;
  33258. }
  33259. {
  33260. j["SSR"] = isSSRenabeled();
  33261. Json SSR;
  33262. auto d = getSSRdata();
  33263. SSR["maxRayDelta"] = d.maxRayDelta;
  33264. SSR["maxRayStep"] = d.maxRayStep;
  33265. SSR["maxSteps"] = d.maxSteps;
  33266. SSR["minRayStep"] = d.minRayStep;
  33267. SSR["numBinarySearchSteps"] = d.numBinarySearchSteps;
  33268. j["SSRdata"] = SSR;
  33269. }
  33270. }
  33271. return j.dump();
  33272. }
  33273. //https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c
  33274. inline bool endsWith(std::string const &value, std::string const &ending)
  33275. {
  33276. if (ending.size() > value.size()) return false;
  33277. return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
  33278. }
  33279. void Renderer3D::loadSettingsFromJson(const char *data, bool includeRenderingSettings, bool loadSkyBox, bool loadAtmosphericScattering)
  33280. {
  33281. using Json = nlohmann::json;
  33282. auto rez = Json::parse(data);
  33283. if(includeRenderingSettings)
  33284. {
  33285. auto exposure = rez["exposure"];
  33286. if (exposure.is_number())
  33287. {
  33288. setExposure(exposure);
  33289. }
  33290. auto colorCorrection = rez["colorCorrection"];
  33291. if (colorCorrection.is_number())
  33292. {
  33293. this->colorCorrection() = colorCorrection;
  33294. }
  33295. auto normalMapping = rez["normal mapping"];
  33296. if (normalMapping.is_boolean())
  33297. {
  33298. enableNormalMapping(normalMapping);
  33299. }
  33300. auto lightSubscatter = rez["light subscatter"];
  33301. if (lightSubscatter.is_boolean())
  33302. {
  33303. enableLightSubScattering(lightSubscatter);
  33304. }
  33305. auto adaptiveResolution = rez["adaptiveResolution"];
  33306. if (adaptiveResolution.is_boolean())
  33307. {
  33308. this->adaptiveResolution.useAdaptiveResolution = adaptiveResolution;
  33309. }
  33310. auto frustumCulling = rez["frustumCulling"];
  33311. if (frustumCulling.is_boolean())
  33312. {
  33313. this->frustumCulling = frustumCulling;
  33314. }
  33315. //SSAO
  33316. {
  33317. auto ssao = rez["ssao"];
  33318. if(ssao.is_boolean())
  33319. {
  33320. enableSSAO(ssao);
  33321. }
  33322. auto ssaoData = rez["ssaoData"];
  33323. if (ssaoData.is_object())
  33324. {
  33325. auto bias = ssaoData["bias"];
  33326. if (bias.is_number()) { setSSAOBias(bias); }
  33327. auto radius = ssaoData["radius"];
  33328. if (radius.is_number()) { setSSAORadius(radius); }
  33329. auto sampleCount = ssaoData["sampleCount"];
  33330. if (sampleCount.is_number()) { setSSAOSampleCount(sampleCount); }
  33331. auto exponent = ssaoData["exponent"];
  33332. if (exponent.is_number()) { setSSAOExponent(exponent); }
  33333. }
  33334. }
  33335. //FXAA
  33336. {
  33337. auto fxaaEnabeled = rez["fxaa"];
  33338. if (fxaaEnabeled.is_boolean()) { enableFXAA(fxaaEnabeled); }
  33339. auto fxaaData = rez["fxaaData"];
  33340. if (fxaaData.is_object())
  33341. {
  33342. auto &data = getFxaaSettings();
  33343. auto edgeDarkTreshold = fxaaData["edgeDarkTreshold"];
  33344. auto edgeMinTreshold = fxaaData["edgeMinTreshold"];
  33345. auto qualityMultiplyer = fxaaData["qualityMultiplyer"];
  33346. auto iterations = fxaaData["iterations"];
  33347. auto subPixelQuality = fxaaData["subPixelQuality"];
  33348. if (edgeDarkTreshold.is_number())
  33349. {
  33350. data.edgeDarkTreshold = edgeDarkTreshold;
  33351. }
  33352. if (edgeMinTreshold.is_number())
  33353. {
  33354. data.edgeMinTreshold = edgeMinTreshold;
  33355. }
  33356. if (qualityMultiplyer.is_number())
  33357. {
  33358. data.quaityMultiplier = qualityMultiplyer;
  33359. }
  33360. if (iterations.is_number())
  33361. {
  33362. data.ITERATIONS = iterations;
  33363. }
  33364. if (subPixelQuality.is_number())
  33365. {
  33366. data.SUBPIXEL_QUALITY = subPixelQuality;
  33367. }
  33368. }
  33369. }
  33370. //Chromatic Aberation
  33371. {
  33372. auto chromaticAberationEnabeled = rez["chromaticAberation"];
  33373. if (chromaticAberationEnabeled.is_boolean()) { this->chromaticAberationEnabeled() = chromaticAberationEnabeled; }
  33374. auto chromaticAberationData = rez["chromaticAberationData"];
  33375. if (chromaticAberationData.is_object())
  33376. {
  33377. auto strength = chromaticAberationData["strength"];
  33378. auto unfocusDistance = chromaticAberationData["unfocusDistance"];
  33379. if (strength.is_number()) { setChromaticAberationStrength(strength); }
  33380. if (unfocusDistance.is_number()) { setChromaticAberationUnfocusDistance(unfocusDistance); }
  33381. }
  33382. }
  33383. //SSR
  33384. {
  33385. auto ssrEnabeled = rez["SSR"];
  33386. if (ssrEnabeled.is_boolean()) { enableSSR(ssrEnabeled); }
  33387. auto ssrData = rez["SSRdata"];
  33388. if (ssrData.is_object())
  33389. {
  33390. auto &d = getSSRdata();
  33391. #define ADD_ENTRY(X) auto X = ssrData[#X]; if (X .is_number()) { d. X = X; }
  33392. ADD_ENTRY(maxRayDelta)
  33393. ADD_ENTRY(maxRayStep)
  33394. ADD_ENTRY(maxSteps)
  33395. ADD_ENTRY(minRayStep)
  33396. ADD_ENTRY(numBinarySearchSteps)
  33397. #undef ADD_ENTRY
  33398. }
  33399. }
  33400. }
  33401. bool loadSkyBoxFailed = 1;
  33402. if (loadSkyBox)
  33403. {
  33404. auto s = rez["sky box"];
  33405. if (s.is_string())
  33406. {
  33407. std::string str = s;
  33408. if (endsWith(str, ".hdr") || endsWith(str, ".HDR"))
  33409. {
  33410. skyBox.clearTextures();
  33411. skyBox = loadHDRSkyBox(str.c_str());
  33412. if (skyBox.texture != 0) { loadSkyBoxFailed = 0; }
  33413. }else
  33414. if (endsWith(str, ".png") || endsWith(str, ".PNG"))
  33415. {
  33416. skyBox.clearTextures();
  33417. skyBox = this->loadSkyBox(str.c_str(), 0);
  33418. if (skyBox.texture != 0) { loadSkyBoxFailed = 0; }
  33419. }
  33420. }
  33421. }
  33422. if (loadAtmosphericScattering && loadSkyBoxFailed)
  33423. {
  33424. auto a = rez["atmosphericScattering"];
  33425. if (a.is_object())
  33426. {
  33427. auto sunx = a["sunx"];
  33428. auto suny = a["suny"];
  33429. auto sunz = a["sunz"];
  33430. auto color1x = a["color1x"];
  33431. auto color1y = a["color1y"];
  33432. auto color1z = a["color1z"];
  33433. auto color2x = a["color2x"];
  33434. auto color2y = a["color2y"];
  33435. auto color2z = a["color2z"];
  33436. auto groundx = a["groundx"];
  33437. auto groundy = a["groundy"];
  33438. auto groundz = a["groundz"];
  33439. auto g = a["g"];
  33440. auto useGround = a["useGround"];
  33441. gl3d::AtmosfericScatteringSettings s;
  33442. if (
  33443. sunx.is_number() &&
  33444. suny.is_number() &&
  33445. sunz.is_number() &&
  33446. color1x.is_number() &&
  33447. color1y.is_number() &&
  33448. color1z.is_number() &&
  33449. color2x.is_number() &&
  33450. color2y.is_number() &&
  33451. color2z.is_number() &&
  33452. groundx.is_number() &&
  33453. groundy.is_number() &&
  33454. groundz.is_number() &&
  33455. useGround.is_boolean() &&
  33456. g.is_number()
  33457. )
  33458. {
  33459. skyBox.clearTextures();
  33460. s.sun = glm::normalize(glm::vec3{sunx, suny, sunz});
  33461. s.color1 = {color1x, color1y, color1z};
  33462. s.color2 = {color2x, color2y, color2z};
  33463. s.ground = {groundx,groundy,groundz};
  33464. s.useGroundColor = useGround;
  33465. s.g = g;
  33466. skyBox = this->atmosfericScattering(s);
  33467. }
  33468. }
  33469. }
  33470. if (loadSkyBox || loadAtmosphericScattering)
  33471. {
  33472. auto r = rez["ambientr"];
  33473. auto g = rez["ambientg"];
  33474. auto b = rez["ambientb"];
  33475. if (r.is_number() && g.is_number() && b.is_number())
  33476. {
  33477. skyBox.color = glm::vec3{r,g,b};
  33478. }
  33479. }
  33480. }
  33481. //todo look into glProgramUniform
  33482. //in order to send less stuff tu uniforms
  33483. //
  33484. //todo not crash the program when you can't load a file.....
  33485. //todo investigate ssao darkening sky
  33486. //todo look into
  33487. //ATI/AMD created GL_ATI_meminfo. This extension is very easy to use.
  33488. //You basically need to call glGetIntegerv with the appropriate token values.
  33489. //https://www.khronos.org/registry/OpenGL/extensions/ATI/ATI_meminfo.txt
  33490. //http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt
  33491. void Renderer3D::renderModelNormals(Model o, glm::vec3 position, glm::vec3 rotation,
  33492. glm::vec3 scale, float normalSize, glm::vec3 normalColor)
  33493. {
  33494. auto obj = internal.getModelData(o);
  33495. if(!obj)
  33496. {
  33497. return;
  33498. }
  33499. for(int i=0; i<obj->models.size(); i++)
  33500. {
  33501. renderSubModelNormals(o, i, position, rotation, scale, normalSize, normalColor);
  33502. }
  33503. }
  33504. void Renderer3D::renderSubModelNormals(Model o, int index, glm::vec3 position, glm::vec3 rotation,
  33505. glm::vec3 scale, float normalSize, glm::vec3 normalColor)
  33506. {
  33507. internal.showNormalsProgram.shader.bind();
  33508. auto projMat = camera.getProjectionMatrix();
  33509. auto viewMat = camera.getWorldToViewMatrix();
  33510. auto transformMat = gl3d::getTransformMatrix(position, rotation, scale);
  33511. auto viewTransformMat = viewMat * transformMat;
  33512. glUniformMatrix4fv(internal.showNormalsProgram.modelTransformLocation,
  33513. 1, GL_FALSE, &viewTransformMat[0][0]);
  33514. glUniformMatrix4fv(internal.showNormalsProgram.projectionLocation,
  33515. 1, GL_FALSE, &projMat[0][0]);
  33516. glUniform1f(internal.showNormalsProgram.sizeLocation, normalSize);
  33517. glUniform3fv(internal.showNormalsProgram.colorLocation, 1, &(normalColor[0]));
  33518. auto modelIndex = this->internal.getModelIndex(o);
  33519. auto obj = internal.getModelData(o);
  33520. if(obj == nullptr)
  33521. {
  33522. return;
  33523. }
  33524. {
  33525. if(index >= obj->models.size())
  33526. {
  33527. return;
  33528. }
  33529. auto &i = obj->models[index];
  33530. glBindVertexArray(i.vertexArray);
  33531. if (i.indexBuffer)
  33532. {
  33533. glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
  33534. }
  33535. else
  33536. {
  33537. glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
  33538. }
  33539. glBindVertexArray(0);
  33540. }
  33541. }
  33542. void Renderer3D::renderSubModelBorder(Model o, int index, glm::vec3 position, glm::vec3 rotation, glm::vec3 scale, float borderSize, glm::vec3 borderColor)
  33543. {
  33544. //auto modelIndex = this->getObjectIndex(o);
  33545. //
  33546. //auto obj = getObjectData(o);
  33547. //if (obj == nullptr)
  33548. //{
  33549. // return;
  33550. //}
  33551. //
  33552. //if (index >= obj->models.size())
  33553. //{
  33554. // return;
  33555. //}
  33556. //
  33557. //
  33558. //glEnable(GL_STENCIL_TEST);
  33559. //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  33560. //glStencilFunc(GL_ALWAYS, 1, 0xFF);
  33561. //glStencilMask(0xFF);
  33562. //
  33563. //auto projMat = renderer.camera.getProjectionMatrix();
  33564. //auto viewMat = renderer.camera.getWorldToViewMatrix();
  33565. //auto transformMat = models[0].getTransformMatrix();
  33566. //
  33567. //auto viewProjMat = projMat * viewMat * transformMat;
  33568. //
  33569. ////lightShader.bind(viewProjMat, transformMat,
  33570. //// lightCubeModel.position, renderer.camera.position, gamaCorection,
  33571. //// models[itemCurrent].models[subItemCurent].material, renderer.pointLights);
  33572. //
  33573. //glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  33574. //models[itemCurrent].models[subItemCurent].draw();
  33575. //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  33576. //
  33577. //glDisable(GL_STENCIL_TEST);
  33578. //
  33579. //glEnable(GL_STENCIL_TEST);
  33580. //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  33581. //glDepthFunc(GL_ALWAYS);
  33582. //glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
  33583. //glStencilMask(0x00);
  33584. //
  33585. //auto &m = models[itemCurrent].models[subItemCurent];
  33586. //projMat = renderer.camera.getProjectionMatrix();
  33587. //viewMat = renderer.camera.getWorldToViewMatrix();
  33588. //
  33589. //auto rotation = models[itemCurrent].rotation;
  33590. //auto scale = models[itemCurrent].scale;
  33591. //scale *= 1.05;
  33592. //auto position = models[itemCurrent].position;
  33593. //
  33594. //
  33595. //auto s = glm::scale(scale);
  33596. //auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
  33597. // glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
  33598. // glm::rotate(rotation.z, glm::vec3(0, 0, 1));
  33599. //auto t = glm::translate(position);
  33600. //
  33601. //transformMat = t * r * s;
  33602. //
  33603. //viewProjMat = projMat * viewMat * transformMat;
  33604. //
  33605. //shader.bind();
  33606. //glUniformMatrix4fv(location, 1, GL_FALSE, &viewProjMat[0][0]);
  33607. //
  33608. //glBindBuffer(GL_ARRAY_BUFFER, m.vertexBuffer);
  33609. //
  33610. //glEnableVertexAttribArray(0);
  33611. //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  33612. //glVertexAttrib3f(1, 98 / 255.f, 24 / 255.f, 201 / 255.f);
  33613. //
  33614. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.indexBuffer);
  33615. //glDrawElements(GL_TRIANGLES, m.primitiveCount, GL_UNSIGNED_INT, 0);
  33616. //
  33617. //glDisable(GL_STENCIL_TEST);
  33618. //glDepthFunc(GL_LESS);
  33619. }
  33620. template<class T>
  33621. bool tryCachedPosition(T &t, std::vector<int> &indexes)
  33622. {
  33623. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  33624. if (t.lastFoundPos_ < indexes.size())
  33625. {
  33626. auto id = indexes[t.lastFoundPos_];
  33627. if (id == t.id_)
  33628. {
  33629. return true;
  33630. }
  33631. }
  33632. #endif
  33633. return 0;
  33634. }
  33635. template<class T>
  33636. int getIndex(T &t, std::vector<int> &indexes, const char *errMessage)
  33637. {
  33638. if (tryCachedPosition(t, indexes))
  33639. {
  33640. return t.lastFoundPos_;
  33641. }
  33642. int id = t.id_;
  33643. if (id <= 0) { return -1; }
  33644. auto found = std::find(indexes.begin(), indexes.end(), id);
  33645. if (found == indexes.end())
  33646. {
  33647. gl3dAssertComment(found != indexes.end(), errMessage);
  33648. return -1;
  33649. }
  33650. int pos = found - indexes.begin();
  33651. #if GL3D_OPTIMIZE_CACHED_SEARCH != 0
  33652. t.lastFoundPos_ = pos;
  33653. #endif
  33654. return pos;
  33655. }
  33656. int Renderer3D::InternalStruct::getMaterialIndex(Material &m)
  33657. {
  33658. return getIndex(m, materialIndexes, "invalid material");
  33659. }
  33660. int Renderer3D::InternalStruct::getModelIndex(Model &o)
  33661. {
  33662. return getIndex(o, graphicModelsIndexes, "invalid model");
  33663. }
  33664. int Renderer3D::InternalStruct::getTextureIndex(Texture &t)
  33665. {
  33666. return getIndex(t, loadedTexturesIndexes, "invalid texture");
  33667. }
  33668. int Renderer3D::InternalStruct::getEntityIndex(Entity &e)
  33669. {
  33670. return getIndex(e, entitiesIndexes, "invalid entity");
  33671. }
  33672. int Renderer3D::InternalStruct::getSpotLightIndex(SpotLight &l)
  33673. {
  33674. return getIndex(l, spotLightIndexes, "invalid enspot lighttity");
  33675. }
  33676. int Renderer3D::InternalStruct::getPointLightIndex(PointLight &l)
  33677. {
  33678. return getIndex(l, pointLightIndexes, "invalid point light");
  33679. }
  33680. int Renderer3D::InternalStruct::getDirectionalLightIndex(DirectionalLight &l)
  33681. {
  33682. return getIndex(l, directionalLightIndexes, "invalid directional light");
  33683. }
  33684. bool Renderer3D::InternalStruct::getMaterialData(Material m, MaterialValues* gpuMaterial, std::string* name, TextureDataForMaterial* textureData)
  33685. {
  33686. int id = getMaterialIndex(m);
  33687. if (id == -1)
  33688. {
  33689. return false;
  33690. }
  33691. if (gpuMaterial)
  33692. {
  33693. *gpuMaterial = materials[id];
  33694. }
  33695. if (name)
  33696. {
  33697. *name = materialNames[id];
  33698. }
  33699. if (textureData)
  33700. {
  33701. *textureData = materialTexturesData[id];
  33702. }
  33703. return true;
  33704. }
  33705. ModelData* Renderer3D::InternalStruct::getModelData(Model o)
  33706. {
  33707. int id = getModelIndex(o);
  33708. if (id == -1)
  33709. {
  33710. return nullptr;
  33711. }
  33712. auto data = &graphicModels[id];
  33713. return data;
  33714. }
  33715. //todo add to other projects and places
  33716. glm::mat4 lookAtSafe(glm::vec3 const& eye, glm::vec3 const& center, glm::vec3 const& upVec)
  33717. {
  33718. glm::vec3 up = glm::normalize(upVec);
  33719. glm::vec3 f;
  33720. glm::vec3 s;
  33721. glm::vec3 u;
  33722. f = (normalize(center - eye));
  33723. if (f == up || f == -up)
  33724. {
  33725. s = glm::vec3(up.z, up.x, up.y);
  33726. u = (cross(s, f));
  33727. }
  33728. else
  33729. {
  33730. s = (normalize(cross(f, up)));
  33731. u = (cross(s, f));
  33732. }
  33733. glm::mat4 Result(1);
  33734. Result[0][0] = s.x;
  33735. Result[1][0] = s.y;
  33736. Result[2][0] = s.z;
  33737. Result[0][1] = u.x;
  33738. Result[1][1] = u.y;
  33739. Result[2][1] = u.z;
  33740. Result[0][2] = -f.x;
  33741. Result[1][2] = -f.y;
  33742. Result[2][2] = -f.z;
  33743. Result[3][0] = -dot(s, eye);
  33744. Result[3][1] = -dot(u, eye);
  33745. Result[3][2] = dot(f, eye);
  33746. return Result;
  33747. }
  33748. bool shouldCullObject(glm::vec3 minBoundary, glm::vec3 maxBoundary, glm::mat4& modelViewProjMat)
  33749. {
  33750. glm::vec3 cubePoints[8] = {};
  33751. int c = 0;
  33752. for (int x = 0; x < 2; x++)
  33753. for (int y = 0; y < 2; y++)
  33754. for (int z = 0; z < 2; z++)
  33755. {
  33756. float xVal = x ? minBoundary.x : maxBoundary.x;
  33757. float yVal = y ? minBoundary.y : maxBoundary.y;
  33758. float zVal = z ? minBoundary.z : maxBoundary.z;
  33759. cubePoints[c] = { xVal, yVal, zVal };
  33760. glm::vec4 augmentedPoint = glm::vec4(cubePoints[c], 1.f);
  33761. augmentedPoint = modelViewProjMat * augmentedPoint;
  33762. augmentedPoint.x /= augmentedPoint.w;
  33763. augmentedPoint.y /= augmentedPoint.w;
  33764. augmentedPoint.z /= augmentedPoint.w;
  33765. if (augmentedPoint.z > 1.f)
  33766. {
  33767. augmentedPoint.y = -augmentedPoint.y;
  33768. }
  33769. cubePoints[c] = glm::vec3(augmentedPoint);
  33770. c++;
  33771. }
  33772. int cull = 1;
  33773. cull = 1;
  33774. for (int p = 0; p < 8; p++)
  33775. {
  33776. if (cubePoints[p].z <= 1.f) { cull = 0; break; }
  33777. }
  33778. if (cull) { return true; }
  33779. cull = 1;
  33780. for (int p = 0; p < 8; p++)
  33781. {
  33782. if (cubePoints[p].y <= 1.f) { cull = 0; break; }
  33783. }
  33784. if (cull) { return true; }
  33785. cull = 1;
  33786. for (int p = 0; p < 8; p++)
  33787. {
  33788. if (cubePoints[p].y >= -1.f) { cull = 0; break; }
  33789. }
  33790. if (cull) { return true; }
  33791. cull = 1;
  33792. for (int p = 0; p < 8; p++)
  33793. {
  33794. if (cubePoints[p].x <= 1.f) { cull = 0; break; }
  33795. }
  33796. if (cull) { return true; }
  33797. cull = 1;
  33798. for (int p = 0; p < 8; p++)
  33799. {
  33800. if (cubePoints[p].x >= -1.f) { cull = 0; break; }
  33801. }
  33802. if (cull) { return true; }
  33803. cull = 1;
  33804. for (int p = 0; p < 8; p++)
  33805. {
  33806. if (cubePoints[p].z >= 0.f) { cull = 0; break; }
  33807. }
  33808. if (cull) { return true; }
  33809. return false;
  33810. }
  33811. void applyPoseToJoints(
  33812. std::vector<glm::mat4> &skinningMatrixes,
  33813. std::vector<glm::mat4> &appliedSkinningMatrixes,
  33814. std::vector<Joint> &joints, int index,
  33815. glm::mat4 parentTransform
  33816. )
  33817. {
  33818. auto currentLocalTransform = skinningMatrixes[index];
  33819. auto worldSpaceTransform = parentTransform * currentLocalTransform;
  33820. auto &j = joints[index];
  33821. for (auto &c : j.children)
  33822. {
  33823. applyPoseToJoints(skinningMatrixes, appliedSkinningMatrixes, joints, c, worldSpaceTransform);
  33824. }
  33825. appliedSkinningMatrixes[index] = worldSpaceTransform * j.inverseBindTransform;
  33826. //appliedSkinningMatrixes[index] = glm::mat4(1.f);
  33827. };
  33828. void applyPoseToJointsForExtractingPositions(
  33829. std::vector<glm::mat4> &skinningMatrixes,
  33830. std::vector<Joint> &joints, int index,
  33831. glm::mat4 parentTransform
  33832. )
  33833. {
  33834. auto currentLocalTransform = skinningMatrixes[index];
  33835. auto worldSpaceTransform = parentTransform * currentLocalTransform;
  33836. auto &j = joints[index];
  33837. for (auto &c : j.children)
  33838. {
  33839. applyPoseToJointsForExtractingPositions(skinningMatrixes, joints, c, worldSpaceTransform);
  33840. }
  33841. joints[index].worldMatrix = worldSpaceTransform * j.localBindTransform;
  33842. };
  33843. ColorLookupTexture Renderer3D::loadColorLookupTextureFromFile(const char *path)
  33844. {
  33845. GpuTexture gpuTexture;
  33846. gpuTexture.loadTextureFromFile(path, fileOpener, -1, 3);
  33847. glBindTexture(GL_TEXTURE_2D, gpuTexture.id);
  33848. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  33849. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  33850. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  33851. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  33852. return {gpuTexture.id};
  33853. }
  33854. void Renderer3D::render(float deltaTime)
  33855. {
  33856. glEnable(GL_DEPTH_TEST);
  33857. glDisable(GL_BLEND);
  33858. if (internal.w <= 0 || internal.h <= 0)
  33859. {
  33860. return;
  33861. }
  33862. camera.aspectRatio = (float)internal.w / internal.h;
  33863. #pragma region adaptive rezolution
  33864. if (adaptiveResolution.timeSample >= adaptiveResolution.timeSamplesCount)
  33865. {
  33866. float ms = 0;
  33867. for (int i = 0; i < adaptiveResolution.timeSamplesCount; i++)
  33868. {
  33869. ms += adaptiveResolution.msSampled[i];
  33870. }
  33871. ms /= adaptiveResolution.timeSamplesCount;
  33872. float seconds = ms * 1000;
  33873. if (seconds < adaptiveResolution.stepUpSecTarget)
  33874. {
  33875. adaptiveResolution.rezRatio += 0.1f;
  33876. if (adaptiveResolution.rezRatio >= 1.f)
  33877. {
  33878. adaptiveResolution.rezRatio = 1.f;
  33879. adaptiveResolution.shouldUseAdaptiveResolution = false;
  33880. }
  33881. }
  33882. else if(seconds > adaptiveResolution.stepDownSecTarget)
  33883. {
  33884. adaptiveResolution.rezRatio -= 0.1f;
  33885. if (adaptiveResolution.rezRatio <= adaptiveResolution.maxScaleDown)
  33886. {
  33887. adaptiveResolution.rezRatio = adaptiveResolution.maxScaleDown;
  33888. }
  33889. adaptiveResolution.shouldUseAdaptiveResolution = true;
  33890. }
  33891. adaptiveResolution.timeSample = 0;
  33892. }
  33893. else
  33894. {
  33895. adaptiveResolution.msSampled[adaptiveResolution.timeSample] = deltaTime;
  33896. adaptiveResolution.timeSample++;
  33897. }
  33898. updateWindowMetrics(internal.w, internal.h);
  33899. #pragma endregion
  33900. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  33901. glStencilMask(0xFF);
  33902. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  33903. glDepthFunc(GL_LESS);
  33904. if (antiAlias.usingFXAA || adaptiveResolution.useAdaptiveResolution)
  33905. {
  33906. glBindFramebuffer(GL_FRAMEBUFFER, adaptiveResolution.fbo);
  33907. //glClear(GL_COLOR_BUFFER_BIT);
  33908. GLenum attachments[1] = {GL_COLOR_ATTACHMENT0};
  33909. glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments);
  33910. }
  33911. {
  33912. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.fbo);
  33913. //glClear(GL_COLOR_BUFFER_BIT);
  33914. GLenum attachments[1] = {GL_COLOR_ATTACHMENT0};
  33915. glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments);
  33916. }
  33917. glViewport(0, 0, internal.adaptiveW, internal.adaptiveH);
  33918. internal.renderSkyBoxBefore(camera, skyBox);
  33919. auto worldToViewMatrix = camera.getWorldToViewMatrix();
  33920. auto projectionMatrix = camera.getProjectionMatrix();
  33921. auto worldProjectionMatrix = projectionMatrix * worldToViewMatrix;
  33922. //todo pass last and new camera matrix to the ssr to better calculate the ssr color
  33923. #pragma region check camera changes
  33924. bool cameraChanged = false;
  33925. if (camera != internal.lastFrameCamera)
  33926. {
  33927. cameraChanged = true;
  33928. }
  33929. internal.lastFrameCamera = camera;
  33930. #pragma endregion
  33931. #pragma region animations
  33932. {
  33933. std::vector<glm::mat4> appliedSkinningMatrixes;
  33934. for (auto& entity : internal.cpuEntities)
  33935. {
  33936. if (!entity.isVisible())
  33937. {
  33938. continue;
  33939. }
  33940. if (entity.models.empty())
  33941. {
  33942. continue;
  33943. }
  33944. if (entity.canBeAnimated() && entity.animate())
  33945. {
  33946. int index = entity.animationIndex;
  33947. index = std::min(index, (int)entity.animations.size() - 1);
  33948. auto& animation = entity.animations[index];
  33949. std::vector<glm::mat4> skinningMatrixes;
  33950. skinningMatrixes.resize(entity.joints.size(), glm::mat4(1.f));
  33951. if (entity.animationTransition.remainintgTime > 0)
  33952. {
  33953. //perform a transition (this will get delta time substracted later down the code).
  33954. }
  33955. else
  33956. {
  33957. //performa a normal animation
  33958. entity.totalTimePassed += deltaTime * entity.animationSpeed;
  33959. while (entity.totalTimePassed >= animation.animationDuration)
  33960. {
  33961. entity.totalTimePassed -= animation.animationDuration;
  33962. }
  33963. }
  33964. //compute per bone position
  33965. for (int b = 0; b < entity.joints.size(); b++)
  33966. {
  33967. glm::quat rotation = {0.f,0.f,0.f,1.f};
  33968. glm::vec3 translation = {0.f,0.f,0.f};
  33969. glm::vec3 scale = {1.f,1.f,1.f};
  33970. auto& joint = entity.joints[b];
  33971. if (
  33972. animation.keyFramesRot[b].empty() &&
  33973. animation.keyFramesTrans[b].empty() &&
  33974. animation.keyFramesScale[b].empty()
  33975. )
  33976. {
  33977. //no animations for this joint
  33978. skinningMatrixes[b] = joint.localBindTransform;
  33979. }
  33980. else
  33981. {
  33982. struct FoundFrames
  33983. {
  33984. int id1;
  33985. int id2;
  33986. float interpolate;
  33987. };
  33988. //trans, rot, scale
  33989. auto searchFrame = [&](auto& frames, float time, int type)
  33990. {
  33991. int size = frames.size();
  33992. int begin = size - 1;
  33993. int end = 0;
  33994. if (time >= frames.back().timeStamp)
  33995. {
  33996. return FoundFrames{size-1, size-1, 0};
  33997. }
  33998. //for (int frame = begin; frame >= end; frame--)
  33999. while (true)
  34000. {
  34001. int frame = ((begin - end) / 2) + end;
  34002. auto& currentFrame = frames[frame];
  34003. if (time >= currentFrame.timeStamp
  34004. && (frame == size - 1 || time <= frames[frame + 1].timeStamp)
  34005. )
  34006. {
  34007. if (frame == size - 1)
  34008. {
  34009. //last frame reached
  34010. return FoundFrames{frame, frame, 0};
  34011. }
  34012. else
  34013. {
  34014. float secondTime = 0;
  34015. if (type == 0)
  34016. {
  34017. if (animation.keyFramesTrans[b].size() <= frame + 1)
  34018. {
  34019. secondTime = 0;
  34020. }else
  34021. {
  34022. secondTime = animation.keyFramesTrans[b][frame + 1].timeStamp;
  34023. }
  34024. }
  34025. else if (type == 1)
  34026. {
  34027. if (animation.keyFramesRot[b].size() <= frame + 1)
  34028. {
  34029. secondTime = 0;
  34030. }
  34031. else
  34032. {
  34033. secondTime = animation.keyFramesRot[b][frame + 1].timeStamp;
  34034. }
  34035. }
  34036. else if (type == 2)
  34037. {
  34038. if (animation.keyFramesScale[b].size() <= frame + 1)
  34039. {
  34040. secondTime = 0;
  34041. }
  34042. else
  34043. {
  34044. secondTime = animation.keyFramesScale[b][frame + 1].timeStamp;
  34045. }
  34046. }
  34047. else
  34048. {
  34049. assert(0);
  34050. }
  34051. if (secondTime != 0)
  34052. {
  34053. float interpolation = (time - currentFrame.timeStamp) / (secondTime - currentFrame.timeStamp);
  34054. return FoundFrames{frame, frame + 1, interpolation};
  34055. }
  34056. else
  34057. {
  34058. //last frame reached
  34059. return FoundFrames{frame, frame, 0};
  34060. }
  34061. }
  34062. }
  34063. else //not found this time
  34064. {
  34065. if (begin <= end)
  34066. {
  34067. break;
  34068. }
  34069. if (time >= currentFrame.timeStamp)
  34070. {
  34071. end = frame;
  34072. }
  34073. else
  34074. {
  34075. begin = frame;
  34076. }
  34077. }
  34078. }
  34079. return FoundFrames{0,0,0.f}; //first frame
  34080. };
  34081. auto lerp = [](glm::vec3 a, glm::vec3 b, float x) -> glm::vec3
  34082. {
  34083. return a * (1.f - x) + (b * x);
  34084. };
  34085. struct BonePositions
  34086. {
  34087. glm::quat rotation = {0.f,0.f,0.f,1.f};
  34088. glm::vec3 translation = {0.f,0.f,0.f};
  34089. glm::vec3 scale = {1.f,1.f,1.f};
  34090. };
  34091. auto getBonePositions = [&](gl3d::Animation& animation, float time)
  34092. {
  34093. if (!animation.keyFramesRot[b].empty())
  34094. {
  34095. auto foundFrames = searchFrame(animation.keyFramesRot[b], time, 1);
  34096. rotation = glm::slerp(
  34097. animation.keyFramesRot[b][foundFrames.id1].rotation,
  34098. animation.keyFramesRot[b][foundFrames.id2].rotation,
  34099. foundFrames.interpolate);
  34100. }
  34101. else
  34102. {
  34103. //no key frames for this bone...
  34104. //rotMat = glm::toMat4(joint.rotation);
  34105. rotation = joint.rotation;
  34106. }
  34107. if (!animation.keyFramesTrans[b].empty())
  34108. {
  34109. auto foundFrames = searchFrame(animation.keyFramesTrans[b], time, 0);
  34110. translation = lerp(
  34111. animation.keyFramesTrans[b][foundFrames.id1].translation,
  34112. animation.keyFramesTrans[b][foundFrames.id2].translation,
  34113. foundFrames.interpolate);
  34114. }
  34115. else
  34116. {
  34117. //no key frames for this bone...
  34118. //transMat = glm::translate(joint.trans);
  34119. translation = joint.trans;
  34120. }
  34121. if (!animation.keyFramesScale[b].empty())
  34122. {
  34123. auto foundFrames = searchFrame(animation.keyFramesScale[b], time, 2);
  34124. scale = lerp(
  34125. animation.keyFramesScale[b][foundFrames.id1].scale,
  34126. animation.keyFramesScale[b][foundFrames.id2].scale,
  34127. foundFrames.interpolate);
  34128. }
  34129. else
  34130. {
  34131. //no key frames for this bone...
  34132. //scaleMat = glm::scale(joint.scale);
  34133. scale = joint.scale;
  34134. }
  34135. BonePositions positions = {rotation, translation, scale};
  34136. return positions;
  34137. };
  34138. auto positions = getBonePositions(animation, entity.totalTimePassed);
  34139. if (entity.animationTransition.remainintgTime > 0)
  34140. {
  34141. //we now perform a new interpolation to the new state
  34142. auto positions2
  34143. = getBonePositions(entity.animations[entity.animationTransition.ToIndex],
  34144. entity.animationTransition.ToTime);
  34145. float interpolate =
  34146. (entity.animationTransition.totalTime - entity.animationTransition.remainintgTime)/
  34147. entity.animationTransition.totalTime;
  34148. positions.rotation = glm::slerp(positions.rotation, positions2.rotation, interpolate);
  34149. positions.translation = lerp(positions.translation, positions2.translation, interpolate);
  34150. positions.scale = lerp(positions.scale, positions2.scale, interpolate);
  34151. }
  34152. glm::mat4 rotMat(1.f);
  34153. glm::mat4 transMat(1.f);
  34154. glm::mat4 scaleMat(1.f);
  34155. rotMat = glm::toMat4(positions.rotation);
  34156. transMat = glm::translate(positions.translation);
  34157. scaleMat = glm::scale(positions.scale);
  34158. skinningMatrixes[b] = transMat * rotMat * scaleMat;
  34159. //skinningMatrixes[b] = i.joints[b].localBindTransform; //no animations
  34160. }
  34161. }
  34162. //check if the transation finished
  34163. if (entity.animationTransition.remainintgTime > 0)
  34164. {
  34165. entity.animationTransition.remainintgTime -= deltaTime; //here we can apply animation speed if wanted
  34166. if (entity.animationTransition.remainintgTime < 0)
  34167. {
  34168. entity.totalTimePassed = entity.animationTransition.ToTime;
  34169. entity.animationIndex = entity.animationTransition.ToIndex;
  34170. //std::cout << entity.totalTimePassed << "\n";
  34171. }
  34172. }
  34173. //skinningMatrixes[24] = skinningMatrixes[24] * glm::rotate(glm::radians(90.f), glm::vec3{ 1,0,0 });
  34174. //std::vector<glm::mat4> appliedSkinningMatrixes;
  34175. //calculate per bone matrix to be send to the gpu
  34176. appliedSkinningMatrixes.clear();
  34177. appliedSkinningMatrixes.resize(entity.joints.size(), glm::mat4(1.f));
  34178. for (auto r : animation.root)
  34179. {
  34180. applyPoseToJoints(skinningMatrixes, appliedSkinningMatrixes, entity.joints,
  34181. r, glm::mat4(1.f));
  34182. }
  34183. for (auto r : animation.root)
  34184. {
  34185. applyPoseToJointsForExtractingPositions(skinningMatrixes, entity.joints, r, glm::mat4(1.f));
  34186. }
  34187. #pragma region save animation data to the gpu
  34188. glBindBuffer(GL_SHADER_STORAGE_BUFFER, entity.appliedSkinningMatricesBuffer);
  34189. glBufferData(GL_SHADER_STORAGE_BUFFER, appliedSkinningMatrixes.size() * sizeof(glm::mat4),
  34190. &appliedSkinningMatrixes[0], GL_STREAM_DRAW);
  34191. #pragma endregion
  34192. }
  34193. }
  34194. }
  34195. #pragma endregion
  34196. #pragma region setup bindless textures
  34197. //todo cache stuff?
  34198. for (int i = 0; i < internal.materials.size(); i++)
  34199. {
  34200. auto &textures = internal.materialTexturesData[i];
  34201. auto &material = internal.materials[i];
  34202. auto albedoData = internal.getTextureIndex(textures.albedoTexture);
  34203. if (albedoData >= 0)
  34204. {
  34205. material.albedoSampler = internal.loadedTexturesBindlessHandle[albedoData];
  34206. }
  34207. else
  34208. {
  34209. material.albedoSampler = 0;
  34210. }
  34211. auto emmisiveData = internal.getTextureIndex(textures.emissiveTexture);
  34212. if (emmisiveData >= 0)
  34213. {
  34214. material.emmissiveSampler = internal.loadedTexturesBindlessHandle[emmisiveData];
  34215. }
  34216. else
  34217. {
  34218. material.emmissiveSampler = 0;
  34219. }
  34220. auto materialData = internal.getTextureIndex(textures.pbrTexture.texture);
  34221. if (materialData >= 0)
  34222. {
  34223. material.rmaSampler = internal.loadedTexturesBindlessHandle[materialData];
  34224. material.rmaLoaded = textures.pbrTexture.RMA_loadedTextures;
  34225. }
  34226. else
  34227. {
  34228. material.rmaSampler = 0;
  34229. material.rmaLoaded = 0;
  34230. }
  34231. }
  34232. #pragma endregion
  34233. #pragma region send material data
  34234. //material buffer //todo lazyness or sthing, don't forget to also change it on clearing all data
  34235. if (internal.materials.size())
  34236. {
  34237. glBindBuffer(GL_SHADER_STORAGE_BUFFER, internal.lightShader.materialBlockBuffer);
  34238. glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(MaterialValues) * internal.materials.size()
  34239. , &internal.materials[0], GL_STREAM_DRAW);
  34240. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::MaterialBlockBinding,
  34241. internal.lightShader.materialBlockBuffer);
  34242. }
  34243. #pragma endregion
  34244. #pragma region render shadow maps
  34245. //filter true and onlyStatic true renders only static geometry
  34246. auto renderModelsShadows = [&](glm::mat4& lightSpaceMatrix, bool filter =0, bool onlyStatic=0)
  34247. {
  34248. //render shadow of the models
  34249. for (auto& i : internal.cpuEntities)
  34250. {
  34251. if (!i.isVisible() || !i.castShadows())
  34252. {
  34253. continue;
  34254. }
  34255. if (filter)
  34256. {
  34257. if (onlyStatic != i.isStatic())
  34258. {
  34259. continue;
  34260. }
  34261. }
  34262. auto transformMat = i.transform.getTransformMatrix();
  34263. auto modelViewProjMat = lightSpaceMatrix * transformMat;
  34264. glUniformMatrix4fv(internal.lightShader.prePass.u_transform, 1, GL_FALSE,
  34265. &modelViewProjMat[0][0]);
  34266. bool potentialAnimations = false;
  34267. if (!i.canBeAnimated() || !i.animate())
  34268. {
  34269. glUniform1i(internal.lightShader.prePass.u_hasAnimations, false);
  34270. }
  34271. else
  34272. {
  34273. //send animation data
  34274. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::JointsTransformBlockBinding,
  34275. i.appliedSkinningMatricesBuffer);
  34276. potentialAnimations = true;
  34277. }
  34278. for (auto& j : i.models)
  34279. {
  34280. if (!(potentialAnimations && j.hasBones))
  34281. {
  34282. if (frustumCulling && shouldCullObject(j.minBoundary, j.maxBoundary, modelViewProjMat))
  34283. {
  34284. continue;
  34285. }
  34286. }
  34287. if (potentialAnimations)
  34288. {
  34289. if (j.hasBones)
  34290. {
  34291. glUniform1i(internal.lightShader.prePass.u_hasAnimations, true);
  34292. }
  34293. else
  34294. {
  34295. glUniform1i(internal.lightShader.prePass.u_hasAnimations, false);
  34296. }
  34297. }
  34298. auto m = internal.getMaterialIndex(j.material);
  34299. int alphaExists = 0;
  34300. if (m < 0)
  34301. {
  34302. auto& mData = internal.materialTexturesData[m];
  34303. auto albedoTextureIndex = internal.getTextureIndex(mData.albedoTexture);
  34304. if (albedoTextureIndex >= 0)
  34305. {
  34306. alphaExists = internal.loadedTextures[albedoTextureIndex].alphaExists();
  34307. }
  34308. }
  34309. if (!alphaExists)
  34310. {
  34311. glUniform1i(internal.lightShader.prePass.u_hasTexture, 0);
  34312. }
  34313. else
  34314. {
  34315. auto t = internal.materialTexturesData[m];
  34316. auto tId = internal.getTextureIndex(t.albedoTexture);
  34317. if (tId < 0)
  34318. {
  34319. glUniform1i(internal.lightShader.prePass.u_hasTexture, 0);
  34320. }
  34321. else
  34322. {
  34323. auto texture = internal.loadedTextures[tId];
  34324. glUniform1i(internal.lightShader.prePass.u_hasTexture, 1);
  34325. glUniform1i(internal.lightShader.prePass.u_albedoSampler, 0);
  34326. glActiveTexture(GL_TEXTURE0);
  34327. glBindTexture(GL_TEXTURE_2D, texture.texture.id);
  34328. }
  34329. }
  34330. glBindVertexArray(j.vertexArray);
  34331. if (j.indexBuffer)
  34332. {
  34333. glDrawElements(GL_TRIANGLES, j.primitiveCount, GL_UNSIGNED_INT, 0);
  34334. }
  34335. else
  34336. {
  34337. glDrawArrays(GL_TRIANGLES, 0, j.primitiveCount);
  34338. }
  34339. }
  34340. }
  34341. };
  34342. auto renderModelsPointShadows = [&](int lightIndex, int shadowCastIndex, bool filter = 0, bool onlyStatic = 0)
  34343. {
  34344. glUniform1i(internal.lightShader.pointShadowShader.u_lightIndex, shadowCastIndex);
  34345. glm::mat4 shadowProj = glm::perspective(glm::radians(90.f), 1.f, 0.1f,
  34346. internal.pointLights[lightIndex].dist);
  34347. glm::vec3 lightPos = internal.pointLights[lightIndex].position;
  34348. std::vector<glm::mat4> shadowTransforms;
  34349. shadowTransforms.reserve(6);
  34350. shadowTransforms.push_back(shadowProj *
  34351. glm::lookAt(lightPos, lightPos + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
  34352. shadowTransforms.push_back(shadowProj *
  34353. glm::lookAt(lightPos, lightPos + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
  34354. shadowTransforms.push_back(shadowProj *
  34355. glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
  34356. shadowTransforms.push_back(shadowProj *
  34357. glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
  34358. shadowTransforms.push_back(shadowProj *
  34359. glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
  34360. shadowTransforms.push_back(shadowProj *
  34361. glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
  34362. glUniformMatrix4fv(internal.lightShader.pointShadowShader.u_shadowMatrices, 6, GL_FALSE,
  34363. &(*shadowTransforms.data())[0][0]);
  34364. glUniform3fv(internal.lightShader.pointShadowShader.u_lightPos, 1,
  34365. &lightPos[0]);
  34366. glUniform1f(internal.lightShader.pointShadowShader.u_farPlane,
  34367. internal.pointLights[lightIndex].dist);
  34368. //render shadow of the models
  34369. for (auto& i : internal.cpuEntities)
  34370. {
  34371. if (!i.isVisible() || !i.castShadows())
  34372. {
  34373. continue;
  34374. }
  34375. if (filter)
  34376. {
  34377. if (onlyStatic != i.isStatic())
  34378. {
  34379. continue;
  34380. }
  34381. }
  34382. auto transformMat = i.transform.getTransformMatrix();
  34383. glUniformMatrix4fv(internal.lightShader.pointShadowShader.u_transform, 1, GL_FALSE,
  34384. &transformMat[0][0]);
  34385. if (!i.canBeAnimated() || !i.animate())
  34386. {
  34387. glUniform1i(internal.lightShader.pointShadowShader.u_hasAnimations, false);
  34388. }
  34389. else
  34390. {
  34391. //send animation data
  34392. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::JointsTransformBlockBinding,
  34393. i.appliedSkinningMatricesBuffer);
  34394. }
  34395. for (auto& j : i.models)
  34396. {
  34397. if (i.canBeAnimated() && i.animate())
  34398. {
  34399. if (j.hasBones)
  34400. {
  34401. glUniform1i(internal.lightShader.pointShadowShader.u_hasAnimations, true);
  34402. }
  34403. else
  34404. {
  34405. glUniform1i(internal.lightShader.pointShadowShader.u_hasAnimations, false);
  34406. }
  34407. }
  34408. auto m = internal.getMaterialIndex(j.material);
  34409. int alphaExists = 0;
  34410. if (m >= 0)
  34411. {
  34412. auto& mData = internal.materialTexturesData[m];
  34413. auto albedoTextureIndex = internal.getTextureIndex(mData.albedoTexture);
  34414. if (albedoTextureIndex >= 0)
  34415. {
  34416. alphaExists = internal.loadedTextures[albedoTextureIndex].alphaExists();
  34417. }
  34418. }
  34419. if (!alphaExists)
  34420. {
  34421. glUniform1i(internal.lightShader.pointShadowShader.u_hasTexture, 0);
  34422. }
  34423. else
  34424. {
  34425. auto t = internal.materialTexturesData[m];
  34426. auto tId = internal.getTextureIndex(t.albedoTexture);
  34427. if (tId < 0)
  34428. {
  34429. glUniform1i(internal.lightShader.pointShadowShader.u_hasTexture, 0);
  34430. }
  34431. else
  34432. {
  34433. auto texture = internal.loadedTextures[tId];
  34434. glUniform1i(internal.lightShader.pointShadowShader.u_hasTexture, 1);
  34435. glUniform1i(internal.lightShader.pointShadowShader.u_albedoSampler, 0);
  34436. glActiveTexture(GL_TEXTURE0);
  34437. glBindTexture(GL_TEXTURE_2D, texture.texture.id);
  34438. }
  34439. }
  34440. glBindVertexArray(j.vertexArray);
  34441. if (j.indexBuffer)
  34442. {
  34443. glDrawElements(GL_TRIANGLES, j.primitiveCount, GL_UNSIGNED_INT, 0);
  34444. }
  34445. else
  34446. {
  34447. glDrawArrays(GL_TRIANGLES, 0, j.primitiveCount);
  34448. }
  34449. }
  34450. }
  34451. };
  34452. if (internal.pointLights.size())
  34453. {
  34454. int shouldUpdateAllPointShadows = internal.perFrameFlags.staticGeometryChanged
  34455. || internal.perFrameFlags.shouldUpdatePointShadows;
  34456. int pointLightsShadowsCount = 0;
  34457. for (auto& i :internal.pointLights)
  34458. {
  34459. if (i.castShadows != 0)
  34460. {
  34461. i.castShadowsIndex = pointLightsShadowsCount;
  34462. pointLightsShadowsCount++;
  34463. }
  34464. }
  34465. if (pointLightsShadowsCount)
  34466. {
  34467. if (pointLightsShadowsCount != pointShadows.textureCount
  34468. || pointShadows.currentShadowSize != pointShadows.shadowSize
  34469. )
  34470. {
  34471. pointShadows.allocateTextures(pointLightsShadowsCount);
  34472. shouldUpdateAllPointShadows = true;
  34473. }
  34474. internal.lightShader.pointShadowShader.shader.bind();
  34475. glViewport(0, 0, pointShadows.shadowSize, pointShadows.shadowSize);
  34476. //static geometry
  34477. glBindFramebuffer(GL_FRAMEBUFFER, pointShadows.staticGeometryFbo);
  34478. for (int lightIndex = 0; lightIndex < internal.pointLights.size(); lightIndex++)
  34479. {
  34480. if (internal.pointLights[lightIndex].castShadows == 0)
  34481. {
  34482. continue;
  34483. }
  34484. if (internal.pointLights[lightIndex].changedThisFrame
  34485. || shouldUpdateAllPointShadows
  34486. )
  34487. {
  34488. internal.pointLights[lightIndex].changedThisFrame = false;
  34489. for (int i = 0; i < 6; i++)
  34490. {
  34491. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34492. pointShadows.staticGeometryTextures, 0,
  34493. internal.pointLights[lightIndex].castShadowsIndex * 6 + i);
  34494. glClear(GL_DEPTH_BUFFER_BIT);
  34495. }
  34496. glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34497. pointShadows.staticGeometryTextures, 0);
  34498. renderModelsPointShadows(lightIndex,
  34499. internal.pointLights[lightIndex].castShadowsIndex, true, true);
  34500. }
  34501. }
  34502. //copy static geometry
  34503. glCopyImageSubData(pointShadows.staticGeometryTextures, GL_TEXTURE_CUBE_MAP_ARRAY, 0,
  34504. 0, 0, 0,
  34505. pointShadows.shadowTextures, GL_TEXTURE_CUBE_MAP_ARRAY, 0,
  34506. 0, 0, 0,
  34507. pointShadows.shadowSize, pointShadows.shadowSize, pointShadows.textureCount * 6
  34508. );
  34509. //dynamic geometry
  34510. glBindFramebuffer(GL_FRAMEBUFFER, pointShadows.fbo);
  34511. glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, pointShadows.shadowTextures, 0);
  34512. //glClear(GL_DEPTH_BUFFER_BIT);
  34513. for (int lightIndex = 0; lightIndex < internal.pointLights.size(); lightIndex++)
  34514. {
  34515. if (internal.pointLights[lightIndex].castShadows == 0)
  34516. {
  34517. continue;
  34518. }
  34519. renderModelsPointShadows(lightIndex,
  34520. internal.pointLights[lightIndex].castShadowsIndex, true, false);
  34521. }
  34522. }
  34523. }
  34524. internal.lightShader.prePass.shader.bind();
  34525. if (internal.directionalLights.size())
  34526. {
  34527. bool shouldRenderStaticGeometryAllLights = internal.perFrameFlags.staticGeometryChanged
  34528. || internal.perFrameFlags.shouldUpdateDirectionalShadows
  34529. || cameraChanged;
  34530. int directionalLightsShadows = 0;
  34531. for (int i=0; i< internal.directionalLights.size(); i++)
  34532. {
  34533. if (internal.directionalLights[i].castShadows != 0)
  34534. {
  34535. internal.directionalLights[i].castShadowsIndex = directionalLightsShadows;
  34536. directionalLightsShadows++;
  34537. }
  34538. }
  34539. if (directionalLightsShadows != directionalShadows.textureCount
  34540. || directionalShadows.shadowSize != directionalShadows.currentShadowSize
  34541. )
  34542. {
  34543. directionalShadows.allocateTextures(directionalLightsShadows);
  34544. shouldRenderStaticGeometryAllLights = true;
  34545. }
  34546. auto calculateLightProjectionMatrix = [&](glm::vec3 lightDir, glm::mat4 lightView,
  34547. float nearPlane, float farPlane,
  34548. float zOffset)
  34549. {
  34550. glm::vec3 rVector = {};
  34551. glm::vec3 upVectpr = {};
  34552. generateTangentSpace(lightDir, upVectpr, rVector);
  34553. glm::vec2 nearDimensions{};
  34554. glm::vec2 farDimensions{};
  34555. glm::vec3 centerNear{};
  34556. glm::vec3 centerFar{};
  34557. computeFrustumDimensions(camera.position, camera.viewDirection, camera.fovRadians, camera.aspectRatio,
  34558. nearPlane, farPlane, nearDimensions, farDimensions, centerNear, centerFar);
  34559. glm::vec3 nearTopLeft{};
  34560. glm::vec3 nearTopRight{};
  34561. glm::vec3 nearBottomLeft{};
  34562. glm::vec3 nearBottomRight{};
  34563. glm::vec3 farTopLeft{};
  34564. glm::vec3 farTopRight{};
  34565. glm::vec3 farBottomLeft{};
  34566. glm::vec3 farBottomRight{};
  34567. computeFrustumSplitCorners(camera.viewDirection, nearDimensions, farDimensions, centerNear, centerFar,
  34568. nearTopLeft,
  34569. nearTopRight,
  34570. nearBottomLeft,
  34571. nearBottomRight,
  34572. farTopLeft,
  34573. farTopRight,
  34574. farBottomLeft,
  34575. farBottomRight
  34576. );
  34577. glm::vec3 corners[] =
  34578. {
  34579. nearTopLeft,
  34580. nearTopRight,
  34581. nearBottomLeft,
  34582. nearBottomRight,
  34583. farTopLeft,
  34584. farTopRight,
  34585. farBottomLeft,
  34586. farBottomRight,
  34587. };
  34588. float longestDiagonal = glm::distance(nearTopLeft, farBottomRight);
  34589. glm::vec3 minVal{};
  34590. glm::vec3 maxVal{};
  34591. for (int i = 0; i < 8; i++)
  34592. {
  34593. glm::vec4 corner(corners[i], 1);
  34594. glm::vec4 lightViewCorner = lightView * corner;
  34595. if (i == 0)
  34596. {
  34597. minVal = lightViewCorner;
  34598. maxVal = lightViewCorner;
  34599. }
  34600. else
  34601. {
  34602. if (lightViewCorner.x < minVal.x) { minVal.x = lightViewCorner.x; }
  34603. if (lightViewCorner.y < minVal.y) { minVal.y = lightViewCorner.y; }
  34604. if (lightViewCorner.z < minVal.z) { minVal.z = lightViewCorner.z; }
  34605. if (lightViewCorner.x > maxVal.x) { maxVal.x = lightViewCorner.x; }
  34606. if (lightViewCorner.y > maxVal.y) { maxVal.y = lightViewCorner.y; }
  34607. if (lightViewCorner.z > maxVal.z) { maxVal.z = lightViewCorner.z; }
  34608. }
  34609. }
  34610. //keep them square and the same size:
  34611. //https://www.youtube.com/watch?v=u0pk1LyLKYQ&t=99s&ab_channel=WesleyLaFerriere
  34612. if (1)
  34613. {
  34614. float firstSize = maxVal.x - minVal.x;
  34615. float secondSize = maxVal.y - minVal.y;
  34616. float thirdSize = maxVal.z - minVal.z;
  34617. {
  34618. float ratio = longestDiagonal / firstSize;
  34619. glm::vec2 newVecValues = { minVal.x, maxVal.x };
  34620. float dimension = firstSize;
  34621. float dimensionOver2 = dimension / 2.f;
  34622. newVecValues -= glm::vec2(minVal.x + dimensionOver2, minVal.x + dimensionOver2);
  34623. newVecValues *= ratio;
  34624. newVecValues += glm::vec2(minVal.x + dimensionOver2, minVal.x + dimensionOver2);
  34625. minVal.x = newVecValues.x;
  34626. maxVal.x = newVecValues.y;
  34627. }
  34628. {
  34629. float ratio = longestDiagonal / secondSize;
  34630. glm::vec2 newVecValues = { minVal.y, maxVal.y };
  34631. float dimension = secondSize;
  34632. float dimensionOver2 = dimension / 2.f;
  34633. newVecValues -= glm::vec2(minVal.y + dimensionOver2, minVal.y + dimensionOver2);
  34634. newVecValues *= ratio;
  34635. newVecValues += glm::vec2(minVal.y + dimensionOver2, minVal.y + dimensionOver2);
  34636. minVal.y = newVecValues.x;
  34637. maxVal.y = newVecValues.y;
  34638. }
  34639. {//todo this size probably can be far-close
  34640. float ratio = longestDiagonal / thirdSize;
  34641. glm::vec2 newVecValues = { minVal.z, maxVal.z };
  34642. float dimension = thirdSize;
  34643. float dimensionOver2 = dimension / 2.f;
  34644. newVecValues -= glm::vec2(minVal.z + dimensionOver2, minVal.z + dimensionOver2);
  34645. newVecValues *= ratio;
  34646. newVecValues += glm::vec2(minVal.z + dimensionOver2, minVal.z + dimensionOver2);
  34647. minVal.z = newVecValues.x;
  34648. maxVal.z = newVecValues.y;
  34649. }
  34650. }
  34651. float near_plane = minVal.z - zOffset;
  34652. float far_plane = maxVal.z;
  34653. glm::vec2 ortoMin = { minVal.x, minVal.y };
  34654. glm::vec2 ortoMax = { maxVal.x, maxVal.y };
  34655. //remove shadow flicker
  34656. if (1)
  34657. {
  34658. glm::vec2 shadowMapSize(directionalShadows.shadowSize, directionalShadows.shadowSize);
  34659. glm::vec2 worldUnitsPerTexel = (ortoMax - ortoMin) / shadowMapSize;
  34660. ortoMin /= worldUnitsPerTexel;
  34661. ortoMin = glm::floor(ortoMin);
  34662. ortoMin *= worldUnitsPerTexel;
  34663. ortoMax /= worldUnitsPerTexel;
  34664. ortoMax = glm::floor(ortoMax);
  34665. ortoMax *= worldUnitsPerTexel;
  34666. float zWorldUnitsPerTexel = (far_plane - near_plane) / directionalShadows.shadowSize;
  34667. near_plane /= zWorldUnitsPerTexel;
  34668. far_plane /= zWorldUnitsPerTexel;
  34669. near_plane = glm::floor(near_plane);
  34670. far_plane = glm::floor(far_plane);
  34671. near_plane *= zWorldUnitsPerTexel;
  34672. far_plane *= zWorldUnitsPerTexel;
  34673. }
  34674. glm::mat4 lightProjection = glm::ortho(ortoMin.x, ortoMax.x, ortoMin.y, ortoMax.y, near_plane, far_plane);
  34675. return lightProjection;
  34676. };
  34677. if (directionalLightsShadows)
  34678. {
  34679. glBindFramebuffer(GL_FRAMEBUFFER, directionalShadows.staticGeometryFbo);
  34680. for (int lightIndex = 0; lightIndex < internal.directionalLights.size(); lightIndex++)
  34681. {
  34682. if (internal.directionalLights[lightIndex].castShadows != 0
  34683. && (internal.directionalLights[lightIndex].changedThisFrame
  34684. || shouldRenderStaticGeometryAllLights)
  34685. )
  34686. {
  34687. internal.directionalLights[lightIndex].changedThisFrame = false;
  34688. glm::vec3 lightDir = internal.directionalLights[lightIndex].direction;
  34689. glm::vec3 direction = lightDir;
  34690. glm::vec3 eye = camera.position - (direction);
  34691. glm::vec3 center = eye + direction;
  34692. glm::mat4 lightView = lookAtSafe(eye, center, {0.f,1.f,0.f});//todo option to add a custom vector direction
  34693. //zoffset is used to move the light further
  34694. float zOffsets[] = { 15 / 200.f,0,0 };
  34695. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34696. directionalShadows.staticGeometryTexture, 0,
  34697. internal.directionalLights[lightIndex].castShadowsIndex); //last is layer
  34698. glClear(GL_DEPTH_BUFFER_BIT);
  34699. float lastNearPlane = 0.0001;
  34700. for (int i = 0; i < DirectionalShadows::CASCADES; i++)
  34701. {
  34702. glViewport(0, directionalShadows.shadowSize * i,
  34703. directionalShadows.shadowSize, directionalShadows.shadowSize);
  34704. auto projection = calculateLightProjectionMatrix(lightDir, lightView,
  34705. lastNearPlane,
  34706. directionalShadows.frustumSplits[i] * camera.farPlane,
  34707. zOffsets[i] * camera.farPlane);
  34708. //this will add some precision but add artefacts todo?
  34709. //lastNearPlane = zOffsets[i] * camera.farPlane;
  34710. internal.directionalLights[lightIndex].lightSpaceMatrix[i] = projection * lightView;
  34711. renderModelsShadows(internal.directionalLights[lightIndex].lightSpaceMatrix[i],
  34712. true, true);
  34713. }
  34714. }
  34715. }
  34716. //copy static geometry
  34717. glCopyImageSubData(directionalShadows.staticGeometryTexture, GL_TEXTURE_2D_ARRAY, 0,
  34718. 0, 0, 0,
  34719. directionalShadows.cascadesTexture, GL_TEXTURE_2D_ARRAY, 0,
  34720. 0, 0, 0,
  34721. directionalShadows.shadowSize, directionalShadows.shadowSize * directionalShadows.CASCADES,
  34722. directionalLightsShadows
  34723. );
  34724. glBindFramebuffer(GL_FRAMEBUFFER, directionalShadows.cascadesFbo);
  34725. for (int lightIndex = 0; lightIndex < internal.directionalLights.size(); lightIndex++)
  34726. {
  34727. if (internal.directionalLights[lightIndex].castShadows != 0)
  34728. {
  34729. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34730. directionalShadows.cascadesTexture, 0,
  34731. internal.directionalLights[lightIndex].castShadowsIndex); //last is layer
  34732. //glClear(GL_DEPTH_BUFFER_BIT);
  34733. for (int i = 0; i < DirectionalShadows::CASCADES; i++)
  34734. {
  34735. glViewport(0, directionalShadows.shadowSize * i,
  34736. directionalShadows.shadowSize, directionalShadows.shadowSize);
  34737. renderModelsShadows(internal.directionalLights[lightIndex].lightSpaceMatrix[i],
  34738. true, false);
  34739. }
  34740. }
  34741. }
  34742. }
  34743. }
  34744. if (internal.spotLights.size())
  34745. {
  34746. bool shouldRenderStaticGeometryAllLights = internal.perFrameFlags.staticGeometryChanged
  34747. || internal.perFrameFlags.shouldUpdateSpotShadows;
  34748. int spotLightsShadowsCount = 0;
  34749. for (const auto& i : internal.spotLights)
  34750. {
  34751. if (i.castShadows) { spotLightsShadowsCount++; }
  34752. }
  34753. if (spotLightsShadowsCount != spotShadows.textureCount
  34754. || spotShadows.shadowSize != spotShadows.currentShadowSize
  34755. )
  34756. {
  34757. spotShadows.allocateTextures(spotLightsShadowsCount);
  34758. shouldRenderStaticGeometryAllLights = true;
  34759. }
  34760. if (spotLightsShadowsCount)
  34761. {
  34762. glViewport(0, 0, spotShadows.shadowSize, spotShadows.shadowSize);
  34763. glBindFramebuffer(GL_FRAMEBUFFER, spotShadows.staticGeometryfbo);
  34764. int shadowCastCount = 0;
  34765. for (int lightIndex = 0; lightIndex < internal.spotLights.size(); lightIndex++)
  34766. {
  34767. if (internal.spotLights[lightIndex].castShadows)
  34768. {
  34769. if (shouldRenderStaticGeometryAllLights || internal.spotLights[lightIndex].changedThisFrame)
  34770. {
  34771. glm::vec3 lightDir = internal.spotLights[lightIndex].direction;
  34772. glm::vec3 lightPos = internal.spotLights[lightIndex].position;
  34773. glm::mat4 lightView = lookAtSafe(lightPos, lightPos + lightDir, { 0.f,1.f,0.f });
  34774. float fov = internal.spotLights[lightIndex].cosHalfAngle;
  34775. fov = std::acos(fov);
  34776. fov *= 2;
  34777. float nearPlane = 0.01f;
  34778. float farPlane = internal.spotLights[lightIndex].dist;
  34779. auto projection = glm::perspective(fov, 1.f, nearPlane, farPlane);
  34780. internal.spotLights[lightIndex].lightSpaceMatrix = projection * lightView;
  34781. internal.spotLights[lightIndex].shadowIndex = shadowCastCount;
  34782. internal.spotLights[lightIndex].nearPlane = nearPlane;
  34783. internal.spotLights[lightIndex].farPlane = farPlane;
  34784. internal.spotLights[lightIndex].changedThisFrame = false;
  34785. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34786. spotShadows.staticGeometryTextures, 0, shadowCastCount);
  34787. glClear(GL_DEPTH_BUFFER_BIT);
  34788. //render only static geometry first
  34789. renderModelsShadows(internal.spotLights[lightIndex].lightSpaceMatrix, true, true);
  34790. }
  34791. shadowCastCount++;
  34792. }
  34793. }
  34794. //copy static geometry
  34795. glCopyImageSubData(spotShadows.staticGeometryTextures, GL_TEXTURE_2D_ARRAY, 0,
  34796. 0, 0, 0,
  34797. spotShadows.shadowTextures, GL_TEXTURE_2D_ARRAY, 0,
  34798. 0, 0, 0,
  34799. spotShadows.shadowSize, spotShadows.shadowSize, spotLightsShadowsCount
  34800. );
  34801. //render dynamic geometry on top
  34802. glBindFramebuffer(GL_FRAMEBUFFER, spotShadows.fbo);
  34803. shadowCastCount = 0; //todo remove !!! bug here
  34804. for (int lightIndex = 0; lightIndex < internal.spotLights.size(); lightIndex++)
  34805. {
  34806. if (internal.spotLights[lightIndex].castShadows)
  34807. {
  34808. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  34809. spotShadows.shadowTextures, 0, shadowCastCount);
  34810. renderModelsShadows(internal.spotLights[lightIndex].lightSpaceMatrix, true, false);
  34811. shadowCastCount++;
  34812. }
  34813. }
  34814. }
  34815. }
  34816. #pragma endregion
  34817. #pragma region clear gbuffer
  34818. {
  34819. glBindFramebuffer(GL_FRAMEBUFFER, internal.gBuffer.gBuffer);
  34820. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  34821. float clearPositionColor[4] = {0,0,-INFINITY, 0};
  34822. glClearBufferfv(GL_COLOR, internal.gBuffer.positionViewSpace, clearPositionColor);
  34823. }
  34824. #pragma endregion
  34825. glViewport(0, 0, internal.adaptiveW, internal.adaptiveH);
  34826. #pragma region z pre pass and frustum culling
  34827. if (zPrePass || frustumCulling)
  34828. {
  34829. if (zPrePass)
  34830. {
  34831. internal.lightShader.prePass.shader.bind();
  34832. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  34833. }
  34834. for (auto& i : internal.cpuEntities)
  34835. {
  34836. if (!i.isVisible())
  34837. {
  34838. continue;
  34839. }
  34840. bool potentialAnimations = 0;
  34841. if (!i.canBeAnimated() || !i.animate())
  34842. {
  34843. glUniform1i(internal.lightShader.prePass.u_hasAnimations, false);
  34844. }
  34845. else
  34846. {
  34847. //send animation data
  34848. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::JointsTransformBlockBinding,
  34849. i.appliedSkinningMatricesBuffer);
  34850. potentialAnimations = true;
  34851. }
  34852. auto transformMat = i.transform.getTransformMatrix();
  34853. auto modelViewProjMat = worldProjectionMatrix * transformMat;
  34854. if (zPrePass)
  34855. {
  34856. glUniformMatrix4fv(internal.lightShader.prePass.u_transform, 1, GL_FALSE, &modelViewProjMat[0][0]);
  34857. }
  34858. for (auto& j : i.models)
  34859. {
  34860. //frustum culling
  34861. if (frustumCulling && !potentialAnimations && !j.hasBones)
  34862. {
  34863. if (shouldCullObject(j.minBoundary, j.maxBoundary, modelViewProjMat))
  34864. {
  34865. j.culledThisFrame = true;
  34866. continue;
  34867. }
  34868. }
  34869. j.culledThisFrame = false;
  34870. if (zPrePass)
  34871. {
  34872. if (i.canBeAnimated() && i.animate())
  34873. {
  34874. if (j.hasBones)
  34875. {
  34876. glUniform1i(internal.lightShader.prePass.u_hasAnimations, true);
  34877. }
  34878. else
  34879. {
  34880. glUniform1i(internal.lightShader.prePass.u_hasAnimations, false);
  34881. }
  34882. }
  34883. auto m = internal.getMaterialIndex(j.material);
  34884. if (m < 0)
  34885. {
  34886. glUniform1i(internal.lightShader.prePass.u_hasTexture, 0);
  34887. }
  34888. else
  34889. {
  34890. auto t = internal.materialTexturesData[m];
  34891. auto tId = internal.getTextureIndex(t.albedoTexture);
  34892. if (tId < 0)
  34893. {
  34894. glUniform1i(internal.lightShader.prePass.u_hasTexture, 0);
  34895. }
  34896. else
  34897. {
  34898. auto texture = internal.loadedTextures[tId];
  34899. glUniform1i(internal.lightShader.prePass.u_hasTexture, 1);
  34900. glUniform1i(internal.lightShader.prePass.u_albedoSampler, 0);
  34901. glActiveTexture(GL_TEXTURE0);
  34902. glBindTexture(GL_TEXTURE_2D, texture.texture.id);
  34903. }
  34904. }
  34905. glBindVertexArray(j.vertexArray);
  34906. if (j.indexBuffer)
  34907. {
  34908. glDrawElements(GL_TRIANGLES, j.primitiveCount, GL_UNSIGNED_INT, 0);
  34909. }
  34910. else
  34911. {
  34912. glDrawArrays(GL_TRIANGLES, 0, j.primitiveCount);
  34913. }
  34914. }
  34915. }
  34916. }
  34917. if (zPrePass)
  34918. {
  34919. //undo some settings set by zPrePass
  34920. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  34921. }
  34922. }
  34923. #pragma endregion
  34924. //todo check if all shaders are loaded of not return 0 on init func
  34925. auto gBufferRender = [&](bool transparentPhaze)
  34926. {
  34927. #pragma region stuff to be bound for rendering the geometry
  34928. glBindVertexArray(0);
  34929. glBindFramebuffer(GL_FRAMEBUFFER, internal.gBuffer.gBuffer);
  34930. GLsizei n;
  34931. glGetProgramStageiv(internal.lightShader.geometryPassShader.id,
  34932. GL_FRAGMENT_SHADER,
  34933. GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS,
  34934. &n);
  34935. GLuint* indices = new GLuint[n]{0};
  34936. if (zPrePass)
  34937. {
  34938. glDepthFunc(GL_EQUAL);
  34939. }
  34940. else
  34941. {
  34942. glDepthFunc(GL_LESS);
  34943. }
  34944. internal.lightShader.geometryPassShader.bind();
  34945. internal.lightShader.getSubroutines(errorReporter);
  34946. glUniform1i(internal.lightShader.normalMapSamplerLocation, 1);
  34947. #pragma endregion
  34948. //first we render the entities in the gbuffer
  34949. for (auto& entity : internal.cpuEntities)
  34950. {
  34951. if (!entity.isVisible())
  34952. {
  34953. continue;
  34954. }
  34955. if (entity.models.empty())
  34956. {
  34957. continue;
  34958. }
  34959. auto transformMat = entity.transform.getTransformMatrix();
  34960. auto modelViewProjMat = worldProjectionMatrix * transformMat;
  34961. glUniformMatrix4fv(internal.lightShader.u_transform, 1, GL_FALSE, &modelViewProjMat[0][0]);
  34962. glUniformMatrix4fv(internal.lightShader.u_modelTransform, 1, GL_FALSE, &transformMat[0][0]);
  34963. glUniformMatrix4fv(internal.lightShader.u_motelViewTransform, 1, GL_FALSE, &(worldToViewMatrix * transformMat)[0][0]);
  34964. #pragma region send animation data
  34965. if (entity.animate())
  34966. {
  34967. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::JointsTransformBlockBinding,
  34968. entity.appliedSkinningMatricesBuffer);
  34969. }
  34970. else
  34971. {
  34972. glUniform1i(internal.lightShader.u_hasAnimations, false);
  34973. }
  34974. #pragma endregion
  34975. bool changed = 1;
  34976. for (auto& i : entity.models)
  34977. {
  34978. if (frustumCulling && i.culledThisFrame) //todo data oriented design, move not culled objects to a new buffer
  34979. {
  34980. continue;
  34981. }
  34982. int materialId = internal.getMaterialIndex(i.material);
  34983. if (materialId == -1)
  34984. {
  34985. continue;
  34986. }
  34987. TextureDataForMaterial textureData = internal.materialTexturesData[materialId];
  34988. auto albedoTextureIndex = internal.getTextureIndex(textureData.albedoTexture);
  34989. bool alphaExists = 0;
  34990. bool alphaHasData = internal.materials[materialId].kd.w < 1.f;
  34991. GLuint diffuseTextureId = 0;
  34992. if (albedoTextureIndex >= 0)
  34993. {
  34994. auto &diffuseTexture = internal.loadedTextures[albedoTextureIndex];
  34995. diffuseTextureId = diffuseTexture.texture.id;
  34996. alphaExists = diffuseTexture.alphaExists();
  34997. alphaHasData |= diffuseTexture.alphaWithData();
  34998. if (internal.materials[materialId].kd.w == 0.f) { continue; } //todo ??
  34999. }
  35000. if (transparentPhaze)
  35001. {
  35002. if (!alphaHasData)
  35003. {
  35004. continue;
  35005. }
  35006. }
  35007. else
  35008. {
  35009. if (alphaHasData)
  35010. {
  35011. continue;
  35012. }
  35013. }
  35014. glUniform1i(internal.lightShader.materialIndexLocation, materialId);
  35015. #pragma region animations
  35016. if (entity.animate()) //if animations are off we set the uniform up
  35017. {
  35018. if (i.hasBones) //if the sub mesh has bones
  35019. {
  35020. glUniform1i(internal.lightShader.u_hasAnimations, true);
  35021. }
  35022. else
  35023. {
  35024. glUniform1i(internal.lightShader.u_hasAnimations, false);
  35025. }
  35026. }
  35027. #pragma endregion
  35028. int normalLoaded = 0;
  35029. GpuTexture* normalMapTextureData = this->getTextureData(textureData.normalMapTexture);
  35030. if (normalMapTextureData != nullptr && normalMapTextureData->id != 0)
  35031. {
  35032. normalLoaded = 1;
  35033. glActiveTexture(GL_TEXTURE1);
  35034. glBindTexture(GL_TEXTURE_2D, normalMapTextureData->id);
  35035. }
  35036. if (normalLoaded && internal.lightShader.normalMap)
  35037. {
  35038. if (indices[internal.lightShader.normalSubroutineLocation] !=
  35039. internal.lightShader.normalSubroutine_normalMap)
  35040. {
  35041. indices[internal.lightShader.normalSubroutineLocation] =
  35042. internal.lightShader.normalSubroutine_normalMap;
  35043. changed = 1;
  35044. }
  35045. }
  35046. else
  35047. {
  35048. if (indices[internal.lightShader.normalSubroutineLocation] !=
  35049. internal.lightShader.normalSubroutine_noMap)
  35050. {
  35051. indices[internal.lightShader.normalSubroutineLocation] =
  35052. internal.lightShader.normalSubroutine_noMap;
  35053. changed = 1;
  35054. }
  35055. }
  35056. if (changed)
  35057. {
  35058. glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);
  35059. }
  35060. changed = 0;
  35061. {
  35062. glBindVertexArray(i.vertexArray);
  35063. if (i.indexBuffer)
  35064. {
  35065. glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
  35066. }
  35067. else
  35068. {
  35069. glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
  35070. }
  35071. }
  35072. }
  35073. }
  35074. delete[] indices;
  35075. };
  35076. gBufferRender(false);
  35077. glBindVertexArray(0);
  35078. if (zPrePass)
  35079. {
  35080. glDepthFunc(GL_LESS);
  35081. }
  35082. auto lightingPass = [&](bool transparentPhaze)
  35083. {
  35084. glBindVertexArray(internal.lightShader.quadDrawer.quadVAO);
  35085. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.fbo);
  35086. glUseProgram(internal.lightShader.lightingPassShader.id);
  35087. glUniform1i(internal.lightShader.light_u_transparentPass, transparentPhaze);
  35088. glUniform1i(internal.lightShader.light_u_normals, 0);
  35089. glActiveTexture(GL_TEXTURE0);
  35090. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.normal]);
  35091. glUniform1i(internal.lightShader.light_u_skyboxFiltered, 1);
  35092. glActiveTexture(GL_TEXTURE1);
  35093. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.preFilteredMap);
  35094. glUniform1i(internal.lightShader.light_u_skyboxIradiance, 2);
  35095. glActiveTexture(GL_TEXTURE2);
  35096. glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.convolutedTexture);
  35097. glUniform1i(internal.lightShader.light_u_brdfTexture, 3);
  35098. glActiveTexture(GL_TEXTURE3);
  35099. glBindTexture(GL_TEXTURE_2D, internal.lightShader.brdfTexture.id);
  35100. glUniform1i(internal.lightShader.light_u_cascades, 4);
  35101. glActiveTexture(GL_TEXTURE4);
  35102. glBindTexture(GL_TEXTURE_2D_ARRAY, directionalShadows.cascadesTexture);
  35103. glUniform1i(internal.lightShader.light_u_spotShadows, 5);
  35104. glActiveTexture(GL_TEXTURE5);
  35105. glBindTexture(GL_TEXTURE_2D_ARRAY, spotShadows.shadowTextures);
  35106. glUniform1i(internal.lightShader.light_u_pointShadows, 6);
  35107. glActiveTexture(GL_TEXTURE6);
  35108. glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, pointShadows.shadowTextures);
  35109. glUniform1i(internal.lightShader.light_u_materialIndex, 7);
  35110. glActiveTexture(GL_TEXTURE7);
  35111. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.materialIndex]);
  35112. glUniform1i(internal.lightShader.light_u_textureUV, 8);
  35113. glActiveTexture(GL_TEXTURE8);
  35114. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.textureUV]);
  35115. glUniform1i(internal.lightShader.light_u_textureDerivates, 9);
  35116. glActiveTexture(GL_TEXTURE9);
  35117. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.textureDerivates]);
  35118. glUniform1i(internal.lightShader.light_u_lastTexture, 10);
  35119. glActiveTexture(GL_TEXTURE10);
  35120. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[2]);
  35121. glUniform1i(internal.lightShader.light_u_positionViewSpace, 11);
  35122. glActiveTexture(GL_TEXTURE11);
  35123. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.positionViewSpace]);
  35124. glUniform1i(internal.lightShader.light_u_hasLastFrameTexture, internal.hasLastFrameTexture);
  35125. glUniform3f(internal.lightShader.light_u_eyePosition, camera.position.x, camera.position.y, camera.position.z);
  35126. glUniformMatrix4fv(internal.lightShader.light_u_cameraProjection, 1, GL_FALSE, &camera.getProjectionMatrix()[0][0]);
  35127. glUniformMatrix4fv(internal.lightShader.light_u_view, 1, GL_FALSE, &camera.getWorldToViewMatrix()[0][0]);
  35128. glUniformMatrix4fv(internal.lightShader.light_u_inverseView, 1, GL_FALSE, &glm::inverse(camera.getWorldToViewMatrix())[0][0]);
  35129. if (internal.pointLights.size())
  35130. {//todo laziness if lights don't change and stuff
  35131. glBindBuffer(GL_SHADER_STORAGE_BUFFER, internal.lightShader.pointLightsBlockBuffer);
  35132. glBufferData(GL_SHADER_STORAGE_BUFFER, internal.pointLights.size() * sizeof(internal::GpuPointLight)
  35133. , &internal.pointLights[0], GL_STREAM_DRAW);
  35134. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::PointLightsBlockBinding,
  35135. internal.lightShader.pointLightsBlockBuffer);
  35136. }
  35137. glUniform1i(internal.lightShader.light_u_pointLightCount, internal.pointLights.size());
  35138. if (internal.directionalLights.size())
  35139. {//todo laziness if lights don't change and stuff
  35140. glBindBuffer(GL_SHADER_STORAGE_BUFFER, internal.lightShader.directionalLightsBlockBuffer);
  35141. glBufferData(GL_SHADER_STORAGE_BUFFER, internal.directionalLights.size() * sizeof(internal::GpuDirectionalLight)
  35142. , &internal.directionalLights[0], GL_STREAM_DRAW);
  35143. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::DirectionalLightsBlockBinding,
  35144. internal.lightShader.directionalLightsBlockBuffer);
  35145. }
  35146. glUniform1i(internal.lightShader.light_u_directionalLightCount, internal.directionalLights.size());
  35147. if (internal.spotLights.size())
  35148. {//todo laziness if lights don't change and stuff
  35149. glBindBuffer(GL_SHADER_STORAGE_BUFFER, internal.lightShader.spotLightsBlockBuffer);
  35150. glBufferData(GL_SHADER_STORAGE_BUFFER, internal.spotLights.size() * sizeof(internal::GpuSpotLight),
  35151. internal.spotLights.data(), GL_STREAM_DRAW);
  35152. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, internal::SpotLightsBlockBinding,
  35153. internal.lightShader.spotLightsBlockBuffer);
  35154. }
  35155. glUniform1i(internal.lightShader.light_u_spotLightCount, internal.spotLights.size());
  35156. //update the uniform block with data for the light shader
  35157. internal.lightShader.lightPassUniformBlockCpuData.ambientLight = glm::vec4(skyBox.color, 0.f);
  35158. if (skyBox.texture != 0
  35159. && skyBox.convolutedTexture != 0
  35160. && skyBox.preFilteredMap != 0
  35161. )
  35162. {
  35163. internal.lightShader.lightPassUniformBlockCpuData.skyBoxPresent = true;
  35164. }
  35165. else
  35166. {
  35167. internal.lightShader.lightPassUniformBlockCpuData.skyBoxPresent = false;
  35168. }
  35169. glBindBuffer(GL_UNIFORM_BUFFER, internal.lightShader.lightPassShaderData.lightPassDataBlockBuffer);
  35170. glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightShader::LightPassData),
  35171. &internal.lightShader.lightPassUniformBlockCpuData);
  35172. glEnable(GL_BLEND);
  35173. if (transparentPhaze)
  35174. {
  35175. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  35176. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  35177. }
  35178. else
  35179. {
  35180. //blend with skybox
  35181. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  35182. }
  35183. glDisable(GL_DEPTH_TEST);
  35184. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35185. glEnable(GL_DEPTH_TEST);
  35186. glDisable(GL_BLEND);
  35187. };
  35188. //do the lighting pass
  35189. lightingPass(false);
  35190. glClearTexImage(internal.gBuffer.buffers[internal.gBuffer.materialIndex], 0, GL_RED_INTEGER, GL_INT, 0);
  35191. gBufferRender(true);
  35192. //blend geometry
  35193. lightingPass(true);
  35194. //copy current texture to last texture
  35195. glReadBuffer(GL_COLOR_ATTACHMENT0);
  35196. glCopyTextureSubImage2D(postProcess.colorBuffers[2], 0, 0, 0, 0, 0,
  35197. postProcess.currentDimensions.x, postProcess.currentDimensions.y);
  35198. //internal.hasLastFrameTexture = true;
  35199. //we draw a rect several times so we keep this vao binded
  35200. glBindVertexArray(internal.lightShader.quadDrawer.quadVAO);
  35201. #pragma region ssao
  35202. if (internal.lightShader.useSSAO)
  35203. {
  35204. if (internal.lightShader.useTheHbaoImplementation)
  35205. {
  35206. //ssao
  35207. glViewport(0, 0, internal.adaptiveW / 2, internal.adaptiveH / 2);
  35208. glUseProgram(internal.ssao.shader.id);
  35209. //todo lazyness
  35210. glBindBuffer(GL_UNIFORM_BUFFER, internal.ssao.ssaoUniformBlockBuffer);
  35211. glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(InternalStruct::SSAO::SsaoShaderUniformBlockData),
  35212. &internal.ssao.ssaoShaderUniformBlockData);
  35213. glUniformMatrix4fv(internal.ssao.u_projection, 1, GL_FALSE,
  35214. &(camera.getProjectionMatrix())[0][0]);
  35215. glUniformMatrix4fv(internal.ssao.u_view, 1, GL_FALSE,
  35216. &(camera.getWorldToViewMatrix())[0][0]);
  35217. glUniform3fv(internal.ssao.u_samples, 64, &(internal.ssao.ssaoKernel[0][0])); //todo send to the gpu only once wtf
  35218. glBindFramebuffer(GL_FRAMEBUFFER, internal.ssao.ssaoFBO);
  35219. glClear(GL_COLOR_BUFFER_BIT);
  35220. glActiveTexture(GL_TEXTURE0);
  35221. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.positionViewSpace]);
  35222. glUniform1i(internal.ssao.u_gPosition, 0);
  35223. glActiveTexture(GL_TEXTURE1);
  35224. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.normal]);
  35225. glUniform1i(internal.ssao.u_gNormal, 1);
  35226. glActiveTexture(GL_TEXTURE2);
  35227. glBindTexture(GL_TEXTURE_2D, internal.ssao.noiseTexture);
  35228. glUniform1i(internal.ssao.u_texNoise, 2);
  35229. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35230. }
  35231. else
  35232. {
  35233. //hbao
  35234. glViewport(0, 0, internal.adaptiveW / 2, internal.adaptiveH / 2);
  35235. glUseProgram(internal.hbao.shader.id);
  35236. glUniformMatrix4fv(internal.hbao.u_projection, 1, GL_FALSE,
  35237. &(camera.getProjectionMatrix())[0][0]);
  35238. glUniformMatrix4fv(internal.hbao.u_view, 1, GL_FALSE,
  35239. &(camera.getWorldToViewMatrix())[0][0]);
  35240. glBindFramebuffer(GL_FRAMEBUFFER, internal.ssao.ssaoFBO);
  35241. glClear(GL_COLOR_BUFFER_BIT);
  35242. glActiveTexture(GL_TEXTURE0);
  35243. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.positionViewSpace]);
  35244. glUniform1i(internal.hbao.u_gPosition, 0);
  35245. glActiveTexture(GL_TEXTURE1);
  35246. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.buffers[internal.gBuffer.normal]);
  35247. glUniform1i(internal.hbao.u_gNormal, 1);
  35248. glActiveTexture(GL_TEXTURE2);
  35249. glBindTexture(GL_TEXTURE_2D, internal.ssao.noiseTexture);
  35250. glUniform1i(internal.hbao.u_texNoise, 2);
  35251. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35252. }
  35253. #pragma region ssao/hbao "blur" (more like average blur)
  35254. glViewport(0, 0, internal.adaptiveW / 4, internal.adaptiveH / 4);
  35255. glBindFramebuffer(GL_FRAMEBUFFER, internal.ssao.blurBuffer);
  35256. internal.ssao.blurShader.bind();
  35257. glClear(GL_COLOR_BUFFER_BIT);
  35258. glActiveTexture(GL_TEXTURE0);
  35259. glBindTexture(GL_TEXTURE_2D, internal.ssao.ssaoColorBuffer);
  35260. glUniform1i(internal.ssao.u_ssaoInput, 0);
  35261. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35262. #pragma endregion
  35263. glViewport(0, 0, internal.adaptiveW, internal.adaptiveH);
  35264. }
  35265. #pragma endregion
  35266. #pragma region filter bloom data
  35267. if (internal.lightShader.bloom)
  35268. {
  35269. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.filterFbo);
  35270. //blend with emmisive data
  35271. glEnable(GL_BLEND);
  35272. glBlendFunc(GL_ONE, GL_ONE);
  35273. postProcess.filterShader.shader.bind();
  35274. glUniform1f(postProcess.filterShader.u_exposure,
  35275. internal.lightShader.lightPassUniformBlockCpuData.exposure);
  35276. glUniform1f(postProcess.filterShader.u_tresshold,
  35277. internal.lightShader.lightPassUniformBlockCpuData.bloomTresshold);
  35278. glUniform1i(postProcess.filterShader.u_texture, 0);
  35279. glActiveTexture(GL_TEXTURE0);
  35280. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[0]);
  35281. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35282. glDisable(GL_BLEND);
  35283. //fxaa on bloom data
  35284. //antiAlias.shader.bind();
  35285. //glUniform1i(antiAlias.u_texture, 0);
  35286. //glActiveTexture(GL_TEXTURE0);
  35287. //glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[1]);
  35288. //glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35289. }
  35290. #pragma endregion
  35291. #pragma region bloom blur
  35292. bool lastBloomChannel = 0;
  35293. if(internal.lightShader.bloom)
  35294. {
  35295. int finalMip = postProcess.currentMips;
  35296. if (postProcess.highQualityDownSample)
  35297. {
  35298. bool horizontal = 0; bool firstTime = 1;
  35299. int mipW = internal.adaptiveW;
  35300. int mipH = internal.adaptiveH;
  35301. lastBloomChannel = !horizontal;
  35302. for (int i = 0; i < postProcess.currentMips + 1; i++)
  35303. {
  35304. #pragma region scale down
  35305. mipW /= 2;
  35306. mipH /= 2;
  35307. glViewport(0, 0, mipW, mipH);
  35308. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[horizontal]);
  35309. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35310. postProcess.bluredColorBuffer[horizontal], i);
  35311. postProcess.filterDown.shader.bind();
  35312. glActiveTexture(GL_TEXTURE0);
  35313. glUniform1i(postProcess.filterDown.u_texture, 0);
  35314. glUniform1i(postProcess.filterDown.u_mip, firstTime ? 0 : i - 1);
  35315. glBindTexture(GL_TEXTURE_2D,
  35316. firstTime ? postProcess.colorBuffers[1] : postProcess.bluredColorBuffer[lastBloomChannel]);
  35317. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35318. lastBloomChannel = horizontal;
  35319. #pragma endregion
  35320. #pragma region copy data
  35321. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[!horizontal]);
  35322. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35323. postProcess.bluredColorBuffer[!horizontal], i);
  35324. postProcess.addMips.shader.bind();
  35325. glActiveTexture(GL_TEXTURE0);
  35326. glUniform1i(postProcess.addMips.u_texture, 0);
  35327. glUniform1i(postProcess.addMips.u_mip, i);
  35328. glBindTexture(GL_TEXTURE_2D,
  35329. postProcess.bluredColorBuffer[lastBloomChannel]);
  35330. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35331. lastBloomChannel = !horizontal;
  35332. #pragma endregion
  35333. #pragma region blur
  35334. postProcess.gausianBLurShader.bind();
  35335. glActiveTexture(GL_TEXTURE0);
  35336. glUniform1i(postProcess.u_toBlurcolorInput, 0);
  35337. glUniform2f(postProcess.u_texel, 1.f / mipW, 1.f / mipH);
  35338. glUniform1i(postProcess.u_mip, i);
  35339. //horizontal = !horizontal;
  35340. for (int j = 0; j < 2; j++)
  35341. {
  35342. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[horizontal]);
  35343. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35344. postProcess.bluredColorBuffer[horizontal], i);
  35345. glClear(GL_COLOR_BUFFER_BIT);
  35346. glUniform1i(postProcess.u_horizontal, horizontal);
  35347. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[lastBloomChannel]);
  35348. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35349. lastBloomChannel = horizontal;
  35350. horizontal = !horizontal;
  35351. firstTime = false;
  35352. }
  35353. horizontal = !horizontal;
  35354. #pragma endregion
  35355. }
  35356. }
  35357. else
  35358. {
  35359. bool horizontal = 0; bool firstTime = 1;
  35360. postProcess.gausianBLurShader.bind();
  35361. glActiveTexture(GL_TEXTURE0);
  35362. glUniform1i(postProcess.u_toBlurcolorInput, 0);
  35363. int mipW = internal.adaptiveW;
  35364. int mipH = internal.adaptiveH;
  35365. for (int i = 0; i < (postProcess.currentMips + 1) * 2; i++)
  35366. {
  35367. if (i % 2 == 0)
  35368. {
  35369. mipW /= 2;
  35370. mipH /= 2;
  35371. glViewport(0, 0, mipW, mipH);
  35372. glUniform2f(postProcess.u_texel, 1.f / mipW, 1.f / mipH);
  35373. horizontal = !horizontal;
  35374. }
  35375. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[horizontal]);
  35376. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35377. postProcess.bluredColorBuffer[horizontal], i / 2);
  35378. //glClear(GL_COLOR_BUFFER_BIT);
  35379. glUniform1i(postProcess.u_horizontal, horizontal);
  35380. glUniform1i(postProcess.u_mip, (i - 1) / 2);
  35381. glBindTexture(GL_TEXTURE_2D,
  35382. firstTime ? postProcess.colorBuffers[1] : postProcess.bluredColorBuffer[lastBloomChannel]);
  35383. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35384. lastBloomChannel = horizontal;
  35385. horizontal = !horizontal;
  35386. firstTime = false;
  35387. }
  35388. }
  35389. if (postProcess.highQualityUpSample)
  35390. {
  35391. glEnable(GL_BLEND);
  35392. glBlendFunc(GL_ONE, GL_ONE);
  35393. postProcess.addMipsBlur.shader.bind();
  35394. glActiveTexture(GL_TEXTURE0);
  35395. glUniform1i(postProcess.addMipsBlur.u_texture, 0);
  35396. for (; finalMip > 0; finalMip--)
  35397. {
  35398. int mipW = internal.adaptiveW;
  35399. int mipH = internal.adaptiveH;
  35400. for (int i = 0; i < finalMip; i++)
  35401. {
  35402. mipW /= 2;
  35403. mipH /= 2;
  35404. }
  35405. glViewport(0, 0, mipW, mipH);
  35406. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[!lastBloomChannel]);
  35407. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35408. postProcess.bluredColorBuffer[!lastBloomChannel], finalMip - 1);
  35409. glUniform1i(postProcess.addMipsBlur.u_mip, finalMip);
  35410. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[lastBloomChannel]);
  35411. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35412. lastBloomChannel = !lastBloomChannel;
  35413. }
  35414. glDisable(GL_BLEND);
  35415. glViewport(0, 0, internal.adaptiveW, internal.adaptiveH);
  35416. }
  35417. else
  35418. {
  35419. glEnable(GL_BLEND);
  35420. glBlendFunc(GL_ONE, GL_ONE);
  35421. postProcess.addMips.shader.bind();
  35422. glActiveTexture(GL_TEXTURE0);
  35423. glUniform1i(postProcess.addMips.u_texture, 0);
  35424. for (; finalMip > 0; finalMip--)
  35425. {
  35426. int mipW = internal.adaptiveW;
  35427. int mipH = internal.adaptiveH;
  35428. for (int i = 0; i < finalMip; i++)
  35429. {
  35430. mipW /= 2;
  35431. mipH /= 2;
  35432. }
  35433. glViewport(0, 0, mipW, mipH);
  35434. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[!lastBloomChannel]);
  35435. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  35436. postProcess.bluredColorBuffer[!lastBloomChannel], finalMip - 1);
  35437. glUniform1i(postProcess.addMips.u_mip, finalMip);
  35438. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[lastBloomChannel]);
  35439. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35440. lastBloomChannel = !lastBloomChannel;
  35441. }
  35442. glDisable(GL_BLEND);
  35443. glViewport(0, 0, internal.adaptiveW, internal.adaptiveH);
  35444. }
  35445. }
  35446. #pragma endregion
  35447. #pragma region do the post process stuff and draw to the screen
  35448. if (antiAlias.usingFXAA || adaptiveResolution.useAdaptiveResolution || postProcess.chromaticAberationOn)
  35449. {
  35450. glBindFramebuffer(GL_FRAMEBUFFER, adaptiveResolution.fbo);
  35451. }
  35452. else
  35453. {
  35454. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35455. }
  35456. glUseProgram(postProcess.postProcessShader.id);
  35457. //color data
  35458. glUniform1i(postProcess.u_colorTexture, 0);
  35459. glActiveTexture(GL_TEXTURE0);
  35460. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[0]);
  35461. //bloom data
  35462. glUniform1i(postProcess.u_bloomTexture, 1);
  35463. glActiveTexture(GL_TEXTURE1);
  35464. if(internal.lightShader.bloom)
  35465. {
  35466. if (postProcess.currentMips <= 0)//remove?
  35467. {
  35468. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[1]);
  35469. }
  35470. else
  35471. {
  35472. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[lastBloomChannel]);
  35473. }
  35474. glUniform1f(postProcess.u_bloomIntensity, postProcess.bloomIntensty);
  35475. }else
  35476. {
  35477. glUniform1f(postProcess.u_bloomIntensity, 0);
  35478. //todo uniform block for this and also probably boolean to check if using bloom or not
  35479. glBindTexture(GL_TEXTURE_2D, 0);
  35480. }
  35481. if (internal.lightShader.useSSAO)
  35482. {
  35483. glUniform1i(postProcess.u_useSSAO, 1);
  35484. //todo change ssao_finalColor_exponent
  35485. glUniform1f(postProcess.u_ssaoExponent, internal.ssao.ssao_finalColor_exponent);
  35486. glUniform1i(postProcess.u_ssao, 3);
  35487. glActiveTexture(GL_TEXTURE3);
  35488. glBindTexture(GL_TEXTURE_2D, internal.ssao.blurColorBuffer);
  35489. }else
  35490. {
  35491. glUniform1i(postProcess.u_useSSAO, 0);
  35492. }
  35493. glUniform1i(postProcess.u_bloomNotBluredTexture, 2);
  35494. glActiveTexture(GL_TEXTURE2);
  35495. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[1]);
  35496. glUniform1f(postProcess.u_exposure, internal.lightShader.lightPassUniformBlockCpuData.exposure);
  35497. //blend with skybox
  35498. //glEnable(GL_BLEND);
  35499. //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  35500. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35501. //glDisable(GL_BLEND);
  35502. #pragma endregion
  35503. #pragma region chromatic aberation
  35504. GLuint currentTexture = adaptiveResolution.texture;
  35505. if (postProcess.chromaticAberationOn)
  35506. {
  35507. glBindFramebuffer(GL_FRAMEBUFFER, adaptiveResolution.fbo2);
  35508. postProcess.chromaticAberation.shader.bind();
  35509. glUniform1i(postProcess.chromaticAberation.u_finalColorTexture, 0);
  35510. glUniform1i(postProcess.chromaticAberation.u_DepthTexture, 1);
  35511. glUniform2i(postProcess.chromaticAberation.u_windowSize, adaptiveResolution.currentDimensions.x,
  35512. adaptiveResolution.currentDimensions.y);
  35513. glUniform1f(postProcess.chromaticAberation.u_strength, postProcess.chromaticAberationStrength);
  35514. glUniform1f(postProcess.chromaticAberation.u_near, camera.closePlane);
  35515. glUniform1f(postProcess.chromaticAberation.u_far, camera.farPlane);
  35516. glUniform1f(postProcess.chromaticAberation.u_unfocusDistance, postProcess.unfocusDistance);
  35517. glActiveTexture(GL_TEXTURE0);
  35518. glBindTexture(GL_TEXTURE_2D, adaptiveResolution.texture);
  35519. glActiveTexture(GL_TEXTURE1);
  35520. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.depthBuffer);
  35521. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35522. currentTexture = adaptiveResolution.texture2;
  35523. }
  35524. #pragma endregion
  35525. #pragma region draw to screen and fxaa
  35526. glViewport(0, 0, internal.w, internal.h);
  35527. if (colorCorrection())
  35528. {
  35529. glBindFramebuffer(GL_FRAMEBUFFER, internal.colorCorrection.fbo);
  35530. }
  35531. else
  35532. {
  35533. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35534. }
  35535. if (antiAlias.usingFXAA || adaptiveResolution.useAdaptiveResolution)
  35536. {
  35537. if (antiAlias.usingFXAA)
  35538. {
  35539. //todo if adaptive rez is on mabe resample first and then fxaa?
  35540. antiAlias.shader.bind();
  35541. glUniform1i(antiAlias.u_texture, 0);
  35542. glActiveTexture(GL_TEXTURE0);
  35543. glBindTexture(GL_TEXTURE_2D, currentTexture);
  35544. //send data.
  35545. //todo lazyness
  35546. glBindBuffer(GL_UNIFORM_BUFFER, antiAlias.fxaaDataBuffer);
  35547. glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(antiAlias.fxaaData), &antiAlias.fxaaData);
  35548. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35549. }
  35550. else if(adaptiveResolution.useAdaptiveResolution)
  35551. {
  35552. antiAlias.noAAshader.bind();
  35553. glUniform1i(antiAlias.noAAu_texture, 0);
  35554. glActiveTexture(GL_TEXTURE0);
  35555. glBindTexture(GL_TEXTURE_2D, currentTexture);
  35556. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35557. }
  35558. }
  35559. #pragma endregion
  35560. #pragma region color corection
  35561. if (colorCorrection())
  35562. {
  35563. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35564. internal.colorCorrection.shader.bind();
  35565. glUniform1i(internal.colorCorrection.u_texture, 0);
  35566. glActiveTexture(GL_TEXTURE0);
  35567. glBindTexture(GL_TEXTURE_2D, internal.colorCorrection.texture);
  35568. glUniform1i(internal.colorCorrection.u_lookup, 1);
  35569. glActiveTexture(GL_TEXTURE1);
  35570. glBindTexture(GL_TEXTURE_2D, internal.colorCorrection.currentTexture.t.id);
  35571. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35572. }
  35573. #pragma endregion
  35574. //todo implement
  35575. #pragma region copy depth buffer for later forward rendering
  35576. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35577. if (copyDepthForLaterForwardRendering)
  35578. {
  35579. if ((internal.adaptiveW == internal.w &&
  35580. internal.adaptiveH == internal.h) || !adaptiveResolution.useAdaptiveResolution
  35581. )
  35582. {
  35583. glBindFramebuffer(GL_READ_FRAMEBUFFER, internal.gBuffer.gBuffer);
  35584. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer); // write to default framebuffer
  35585. glBlitFramebuffer(
  35586. 0, 0, internal.adaptiveW, internal.adaptiveH, 0, 0, internal.w, internal.h, GL_DEPTH_BUFFER_BIT, GL_NEAREST
  35587. );
  35588. }
  35589. else
  35590. {
  35591. copyDepth.shader.bind();
  35592. glUniform1i(copyDepth.u_depth, 0);
  35593. glActiveTexture(GL_TEXTURE0);
  35594. glBindTexture(GL_TEXTURE_2D, internal.gBuffer.depthBuffer);
  35595. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  35596. }
  35597. }
  35598. #pragma endregion
  35599. glBindVertexArray(0);
  35600. //reset per frame flags
  35601. internal.perFrameFlags = {};
  35602. }
  35603. void Renderer3D::updateWindowMetrics(int x, int y)
  35604. {
  35605. internal.w = x; internal.h = y;
  35606. if (adaptiveResolution.useAdaptiveResolution &&
  35607. adaptiveResolution.shouldUseAdaptiveResolution)
  35608. {
  35609. internal.adaptiveW = internal.w * adaptiveResolution.rezRatio;
  35610. internal.adaptiveH = internal.h * adaptiveResolution.rezRatio;
  35611. }
  35612. else
  35613. {
  35614. internal.adaptiveW = internal.w;
  35615. internal.adaptiveH = internal.h;
  35616. }
  35617. //gbuffer
  35618. internal.gBuffer.resize(internal.adaptiveW, internal.adaptiveH);
  35619. //ssao and hbao
  35620. internal.ssao.resize(internal.adaptiveW, internal.adaptiveH);
  35621. //bloom buffer and color buffer
  35622. postProcess.resize(internal.adaptiveW, internal.adaptiveH);
  35623. adaptiveResolution.resize(internal.adaptiveW, internal.adaptiveH);
  35624. internal.colorCorrection.resize(x, y);
  35625. }
  35626. void Renderer3D::clearAllLoadedResource()
  35627. {
  35628. #pragma region skyboxes
  35629. skyBox.clearTextures();
  35630. #pragma endregion
  35631. #pragma region materials
  35632. internal.materialIndexes.clear();
  35633. internal.materials.clear();
  35634. internal.materialNames.clear();
  35635. internal.materialTexturesData.clear();
  35636. #pragma endregion
  35637. #pragma region textures
  35638. for (auto &t : internal.loadedTextures)
  35639. {
  35640. glDeleteTextures(1, &t.texture.id);
  35641. }
  35642. internal.loadedTexturesIndexes.clear();
  35643. internal.loadedTextures.clear();
  35644. internal.loadedTexturesBindlessHandle.clear();
  35645. internal.loadedTexturesNames.clear();
  35646. #pragma endregion
  35647. #pragma region models
  35648. for (auto &m : internal.graphicModels)
  35649. {
  35650. m.internalClear();
  35651. }
  35652. internal.graphicModels.clear();
  35653. internal.graphicModelsIndexes.clear();
  35654. #pragma endregion
  35655. #pragma region cpuEntities
  35656. for (auto &e : internal.cpuEntities)
  35657. {
  35658. e.clear();
  35659. }
  35660. internal.cpuEntities.clear();
  35661. internal.entitiesIndexes.clear();;
  35662. #pragma endregion
  35663. #pragma region lights
  35664. internal.spotLights.clear();
  35665. internal.spotLightIndexes.clear();
  35666. internal.pointLights.clear();
  35667. internal.pointLightIndexes.clear();
  35668. internal.directionalLights.clear();
  35669. internal.directionalLightIndexes.clear();
  35670. spotShadows.clear();
  35671. pointShadows.clear();
  35672. directionalShadows.clear();
  35673. #pragma endregion
  35674. }
  35675. void Renderer3D::clearAllRendererResources()
  35676. {
  35677. clearAllLoadedResource();
  35678. internal.lightShader.clear();
  35679. internal.skyBoxLoaderAndDrawer.clear();
  35680. internal.showNormalsProgram.shader.clear();
  35681. internal.gBuffer.clear();
  35682. internal.ssao.clear();
  35683. internal.hbao.clear();
  35684. postProcess.clear();
  35685. directionalShadows.clear();
  35686. spotShadows.clear();
  35687. pointShadows.clear();
  35688. antiAlias.clear();
  35689. adaptiveResolution.clear();
  35690. internal.pBRtextureMaker.clear();
  35691. copyDepth.clear();
  35692. internal.colorCorrection.clear();
  35693. }
  35694. SkyBox Renderer3D::loadSkyBox(const char *names[6])
  35695. {
  35696. SkyBox skyBox = {};
  35697. internal.skyBoxLoaderAndDrawer.loadTexture(names, skyBox, errorReporter, fileOpener, frameBuffer);
  35698. return skyBox;
  35699. }
  35700. SkyBox Renderer3D::loadSkyBox(const char *name, int format)
  35701. {
  35702. SkyBox skyBox = {};
  35703. internal.skyBoxLoaderAndDrawer.loadTexture(name, skyBox, errorReporter, fileOpener, format);
  35704. return skyBox;
  35705. }
  35706. SkyBox Renderer3D::loadHDRSkyBox(const char *name)
  35707. {
  35708. SkyBox skyBox = {};
  35709. internal.skyBoxLoaderAndDrawer.loadHDRtexture(name, errorReporter, fileOpener, skyBox, frameBuffer);
  35710. return skyBox;
  35711. }
  35712. void Renderer3D::deleteSkyBoxTextures(SkyBox& skyBox)
  35713. {
  35714. skyBox.clearTextures();
  35715. }
  35716. SkyBox Renderer3D::atmosfericScattering(glm::vec3 sun, glm::vec3 color1, glm::vec3 color2,
  35717. glm::vec3 groundColor, bool useGroundColor, float g)
  35718. {
  35719. SkyBox skyBox = {};
  35720. internal.skyBoxLoaderAndDrawer.atmosphericScattering(sun, color1, color2, groundColor,
  35721. useGroundColor, g, skyBox, frameBuffer);
  35722. return skyBox;
  35723. }
  35724. SkyBox Renderer3D::atmosfericScattering(AtmosfericScatteringSettings settings)
  35725. {
  35726. return atmosfericScattering(settings.sun, settings.color1, settings.color2, settings.ground,
  35727. settings.useGroundColor, settings.g);
  35728. }
  35729. float lerp(float a, float b, float f)
  35730. {
  35731. return a + f * (b - a);
  35732. }
  35733. void Renderer3D::InternalStruct::SSAO::create(int w, int h, ErrorReporter &errorReporter,
  35734. FileOpener &fileOpener, GLuint frameBuffer)
  35735. {
  35736. std::uniform_real_distribution<float> randomFloats(0.0f, 1.0f);
  35737. std::uniform_real_distribution<float> randomFloatsSmaller(0.1f, 0.9f); //avoid ssao artefacts
  35738. std::default_random_engine generator;
  35739. ssaoKernel.reserve(64);
  35740. for (unsigned int i = 0; i < 64; ++i)
  35741. {
  35742. glm::vec3 sample(
  35743. randomFloats(generator) * 2.0 - 1.0,
  35744. randomFloats(generator) * 2.0 - 1.0,
  35745. randomFloats(generator) // z component is always positive
  35746. );
  35747. sample = glm::normalize(sample);
  35748. float scale = (float)i / 64.0;
  35749. scale = lerp(0.1f, 1.0f, scale * scale);
  35750. sample *= scale;
  35751. ssaoKernel.push_back(sample);
  35752. }
  35753. //std::shuffle(ssaoKernel.begin(), ssaoKernel.end(), generator);
  35754. std::vector<glm::vec3> ssaoNoise;
  35755. for (unsigned int i = 0; i < 16; i++)
  35756. {
  35757. glm::vec3 noise(
  35758. randomFloats(generator) * 2.0 - 1.0,
  35759. randomFloats(generator) * 2.0 - 1.0,
  35760. 0.0f);
  35761. ssaoNoise.push_back(noise);
  35762. }
  35763. glGenTextures(1, &noiseTexture);
  35764. glBindTexture(GL_TEXTURE_2D, noiseTexture);
  35765. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0][0]);
  35766. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  35767. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  35768. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  35769. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  35770. glGenFramebuffers(1, &ssaoFBO);
  35771. glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
  35772. glGenTextures(1, &ssaoColorBuffer);
  35773. glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
  35774. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
  35775. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  35776. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  35777. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  35778. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  35779. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
  35780. shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/ssao/ssao.frag", errorReporter, fileOpener);
  35781. u_projection = getUniform(shader.id, "u_projection", errorReporter);
  35782. u_view = getUniform(shader.id, "u_view", errorReporter);
  35783. u_gPosition = getUniform(shader.id, "u_gPosition", errorReporter);
  35784. u_gNormal = getUniform(shader.id, "u_gNormal", errorReporter);
  35785. u_texNoise = getUniform(shader.id, "u_texNoise", errorReporter);
  35786. u_samples = getUniform(shader.id, "samples[0]", errorReporter);
  35787. glGenBuffers(1, &ssaoUniformBlockBuffer);
  35788. glBindBuffer(GL_UNIFORM_BUFFER, ssaoUniformBlockBuffer);
  35789. glBufferData(GL_UNIFORM_BUFFER, sizeof(SsaoShaderUniformBlockData),
  35790. &ssaoShaderUniformBlockData, GL_DYNAMIC_DRAW);
  35791. glBindBufferBase(GL_UNIFORM_BUFFER, internal::SSAODataBlockBinding, ssaoUniformBlockBuffer);
  35792. u_SSAODATA = glGetUniformBlockIndex(shader.id, "u_SSAODATA");
  35793. glUniformBlockBinding(shader.id, u_SSAODATA, internal::SSAODataBlockBinding);
  35794. //blur
  35795. blurShader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/ssao/blur.frag", errorReporter, fileOpener);
  35796. glGenFramebuffers(1, &blurBuffer);
  35797. glBindFramebuffer(GL_FRAMEBUFFER, blurBuffer);
  35798. glGenTextures(1, &blurColorBuffer);
  35799. glBindTexture(GL_TEXTURE_2D, blurColorBuffer);
  35800. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
  35801. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  35802. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  35803. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  35804. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  35805. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurColorBuffer, 0);
  35806. u_ssaoInput = getUniform(blurShader.id, "u_ssaoInput", errorReporter);
  35807. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35808. resize(w, h);
  35809. }
  35810. void Renderer3D::InternalStruct::SSAO::resize(int w, int h)
  35811. {
  35812. if (currentDimensions.x != w || currentDimensions.y != h)
  35813. {
  35814. glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
  35815. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w / 2, h / 2, 0, GL_RED, GL_FLOAT, NULL);
  35816. glBindTexture(GL_TEXTURE_2D, blurColorBuffer);
  35817. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w / 4, h / 4, 0, GL_RED, GL_FLOAT, NULL);
  35818. currentDimensions = glm::ivec2(w, h);
  35819. }
  35820. }
  35821. void Renderer3D::InternalStruct::SSAO::clear()
  35822. {
  35823. ssaoKernel.clear();
  35824. glDeleteTextures(1, &noiseTexture);
  35825. glDeleteFramebuffers(1, &ssaoFBO);
  35826. glDeleteTextures(1, &ssaoColorBuffer);
  35827. shader.clear();
  35828. glDeleteBuffers(1, &ssaoUniformBlockBuffer);
  35829. blurShader.clear();
  35830. glDeleteFramebuffers(1, &blurBuffer);
  35831. glDeleteTextures(1, &blurColorBuffer);
  35832. }
  35833. void Renderer3D::PostProcess::create(int w, int h, ErrorReporter &errorReporter, FileOpener &fileOpener, GLuint frameBuffer)
  35834. {
  35835. glGenFramebuffers(1, &fbo);
  35836. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  35837. //one for colors the other for things to be bloomed
  35838. glGenTextures(3, colorBuffers);
  35839. for (int i = 0; i < 3; i++)
  35840. {
  35841. glBindTexture(GL_TEXTURE_2D, colorBuffers[i]);
  35842. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
  35843. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  35844. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  35845. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  35846. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  35847. // attach texture to framebuffer
  35848. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorBuffers[i], 0);
  35849. }
  35850. unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
  35851. glDrawBuffers(2, attachments);
  35852. //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffers[0], 0);
  35853. glGenFramebuffers(1, &filterFbo);
  35854. glBindFramebuffer(GL_FRAMEBUFFER, filterFbo);
  35855. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffers[1], 0);
  35856. postProcessShader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/postProcess.frag",
  35857. errorReporter, fileOpener);
  35858. u_colorTexture = getUniform(postProcessShader.id, "u_colorTexture", errorReporter);
  35859. u_bloomTexture = getUniform(postProcessShader.id, "u_bloomTexture", errorReporter);
  35860. u_bloomNotBluredTexture = getUniform(postProcessShader.id, "u_bloomNotBluredTexture", errorReporter);
  35861. u_bloomIntensity = getUniform(postProcessShader.id, "u_bloomIntensity", errorReporter);
  35862. u_exposure = getUniform(postProcessShader.id, "u_exposure", errorReporter);
  35863. u_useSSAO = getUniform(postProcessShader.id, "u_useSSAO", errorReporter);
  35864. u_ssaoExponent = getUniform(postProcessShader.id, "u_ssaoExponent", errorReporter);
  35865. u_ssao = getUniform(postProcessShader.id, "u_ssao", errorReporter);
  35866. gausianBLurShader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/gausianBlur.frag", errorReporter, fileOpener);
  35867. u_toBlurcolorInput = getUniform(gausianBLurShader.id, "u_toBlurcolorInput", errorReporter);
  35868. u_horizontal = getUniform(gausianBLurShader.id, "u_horizontal", errorReporter);
  35869. u_mip = getUniform(gausianBLurShader.id, "u_mip", errorReporter);
  35870. u_texel = getUniform(gausianBLurShader.id, "u_texel", errorReporter);
  35871. filterShader.shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/filter.frag", errorReporter, fileOpener);
  35872. filterShader.u_exposure = getUniform(filterShader.shader.id, "u_exposure", errorReporter);
  35873. filterShader.u_texture = getUniform(filterShader.shader.id, "u_texture", errorReporter);
  35874. filterShader.u_tresshold = getUniform(filterShader.shader.id, "u_tresshold", errorReporter);
  35875. addMips.shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/addMips.frag", errorReporter, fileOpener);
  35876. addMips.u_mip = getUniform(addMips.shader.id, "u_mip", errorReporter);
  35877. addMips.u_texture= getUniform(addMips.shader.id, "u_texture", errorReporter);
  35878. addMipsBlur.shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/addMipsBlur.frag", errorReporter, fileOpener);
  35879. addMipsBlur.u_mip = getUniform(addMipsBlur.shader.id, "u_mip", errorReporter);
  35880. addMipsBlur.u_texture = getUniform(addMipsBlur.shader.id, "u_texture", errorReporter);
  35881. filterDown.shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/filterDown.frag", errorReporter, fileOpener);
  35882. filterDown.u_mip = getUniform(filterDown.shader.id, "u_mip", errorReporter);
  35883. filterDown.u_texture = getUniform(filterDown.shader.id, "u_texture", errorReporter);
  35884. chromaticAberation.shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/chromaticAberation.frag", errorReporter, fileOpener);
  35885. chromaticAberation.u_finalColorTexture = getUniform(chromaticAberation.shader.id, "u_finalColorTexture", errorReporter);
  35886. chromaticAberation.u_windowSize = getUniform(chromaticAberation.shader.id, "u_windowSize", errorReporter);
  35887. chromaticAberation.u_strength = getUniform(chromaticAberation.shader.id, "u_strength", errorReporter);
  35888. chromaticAberation.u_DepthTexture = getUniform(chromaticAberation.shader.id, "u_DepthTexture", errorReporter);
  35889. chromaticAberation.u_near = getUniform(chromaticAberation.shader.id, "u_near", errorReporter);
  35890. chromaticAberation.u_far = getUniform(chromaticAberation.shader.id, "u_far", errorReporter);
  35891. chromaticAberation.u_unfocusDistance = getUniform(chromaticAberation.shader.id, "u_unfocusDistance", errorReporter);
  35892. glGenFramebuffers(2, blurFbo);
  35893. glGenTextures(2, bluredColorBuffer);
  35894. for(int i=0;i <2; i++)
  35895. {
  35896. glBindFramebuffer(GL_FRAMEBUFFER, blurFbo[i]);
  35897. float borderColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
  35898. glBindTexture(GL_TEXTURE_2D, bluredColorBuffer[i]);
  35899. glTexImage2D(GL_TEXTURE_2D, 0, GL_R11F_G11F_B10F, 1, 1, 0, GL_RGB, GL_FLOAT, NULL);
  35900. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  35901. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  35902. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  35903. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  35904. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
  35905. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bluredColorBuffer[i], 0);
  35906. }
  35907. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  35908. resize(w, h);
  35909. }
  35910. void Renderer3D::PostProcess::resize(int w, int h)
  35911. {
  35912. //16 = max mips
  35913. int mips = 0;
  35914. {
  35915. int mipW = w / 2;
  35916. int mipH = h / 2;
  35917. for (int i = 0; i < 16; i++)
  35918. {
  35919. if (mipW <= 4 || mipH <= 4 ||
  35920. (mipW < 12 && mipH < 12)
  35921. )
  35922. {
  35923. break;
  35924. }
  35925. mipW /= 2;
  35926. mipH /= 2;
  35927. mips = i;
  35928. }
  35929. }
  35930. //mips = 1;
  35931. if (currentDimensions.x != w || currentDimensions.y != h
  35932. || currentMips != mips)
  35933. {
  35934. currentMips = mips;
  35935. for (int i = 0; i < 2; i++)
  35936. {
  35937. glBindTexture(GL_TEXTURE_2D, bluredColorBuffer[i]);
  35938. int mipW = w / 2;
  35939. int mipH = h / 2;
  35940. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mips);
  35941. for (int m = 0; m <= mips; m++)
  35942. {
  35943. glTexImage2D(GL_TEXTURE_2D, m, GL_R11F_G11F_B10F, mipW, mipH, 0, GL_RGB, GL_FLOAT, NULL);
  35944. mipW = mipW /= 2;
  35945. mipH = mipH /= 2;
  35946. }
  35947. }
  35948. }
  35949. if (currentDimensions.x != w || currentDimensions.y != h)
  35950. {
  35951. currentDimensions = glm::ivec2(w, h);
  35952. for (int i = 0; i < 3; i++)
  35953. {
  35954. glBindTexture(GL_TEXTURE_2D, colorBuffers[i]);
  35955. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
  35956. }
  35957. }
  35958. }
  35959. void Renderer3D::PostProcess::clear()
  35960. {
  35961. glDeleteTextures(3, colorBuffers);
  35962. postProcessShader.clear();
  35963. glDeleteFramebuffers(1, &filterFbo);
  35964. glDeleteFramebuffers(1, &fbo);
  35965. gausianBLurShader.clear();
  35966. filterShader.shader.clear();
  35967. addMips.shader.clear();
  35968. addMipsBlur.shader.clear();
  35969. filterDown.shader.clear();
  35970. chromaticAberation.shader.clear();
  35971. glDeleteFramebuffers(2, blurFbo);
  35972. glDeleteTextures(2, bluredColorBuffer);
  35973. }
  35974. void Renderer3D::InternalStruct::PBRtextureMaker::init(ErrorReporter &errorReporter, FileOpener &fileOpener)
  35975. {
  35976. shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/modelLoader/mergePBRmat.frag", errorReporter, fileOpener);
  35977. glGenFramebuffers(1, &fbo);
  35978. }
  35979. void Renderer3D::InternalStruct::PBRtextureMaker::clear()
  35980. {
  35981. shader.clear();
  35982. glDeleteFramebuffers(1, &fbo);
  35983. }
  35984. void Renderer3D::InternalStruct::renderSkyBox(Camera& c, SkyBox& s)
  35985. {
  35986. auto projMat = c.getProjectionMatrix();
  35987. auto viewMat = c.getWorldToViewMatrix();
  35988. viewMat = glm::mat4(glm::mat3(viewMat));
  35989. auto viewProjMat = projMat * viewMat;
  35990. skyBoxLoaderAndDrawer.draw(viewProjMat, s,
  35991. lightShader.lightPassUniformBlockCpuData.exposure,
  35992. s.color);
  35993. }
  35994. void Renderer3D::InternalStruct::renderSkyBoxBefore(Camera& c, SkyBox& s)
  35995. {
  35996. auto projMat = c.getProjectionMatrix();
  35997. auto viewMat = c.getWorldToViewMatrix();
  35998. viewMat = glm::mat4(glm::mat3(viewMat));
  35999. auto viewProjMat = projMat * viewMat;
  36000. skyBoxLoaderAndDrawer.drawBefore(viewProjMat, s,
  36001. lightShader.lightPassUniformBlockCpuData.exposure,
  36002. s.color);
  36003. }
  36004. //todo use the max w h to create it
  36005. GLuint Renderer3D::InternalStruct::PBRtextureMaker::createRMAtexture(GpuTexture roughness,
  36006. GpuTexture metallic, GpuTexture ambientOcclusion, GLuint quadVAO, int &RMA_loadedTextures, GLuint frameBuffer, int quality)
  36007. {
  36008. bool roughnessLoaded = (roughness.id != 0);
  36009. bool metallicLoaded = (metallic.id != 0);
  36010. bool ambientLoaded = (ambientOcclusion.id != 0);
  36011. RMA_loadedTextures = 0;
  36012. //if (roughnessLoaded && metallicLoaded && ambientLoaded) { RMA_loadedTextures = 7; }
  36013. //else
  36014. //if (metallicLoaded && ambientLoaded) { RMA_loadedTextures = 6; }
  36015. //else
  36016. //if (roughnessLoaded && ambientLoaded) { RMA_loadedTextures = 5; }
  36017. //else
  36018. //if (roughnessLoaded && metallicLoaded) { RMA_loadedTextures = 4; }
  36019. //else
  36020. //if (ambientLoaded) { RMA_loadedTextures = 3; }
  36021. //else
  36022. //if (metallicLoaded) { RMA_loadedTextures = 2; }
  36023. //else
  36024. //if (roughnessLoaded) { RMA_loadedTextures = 1; }
  36025. //else { RMA_loadedTextures = 0; }
  36026. if (roughnessLoaded) { RMA_loadedTextures |= 0b100; }
  36027. if (metallicLoaded) { RMA_loadedTextures |= 0b010; }
  36028. if (ambientLoaded) { RMA_loadedTextures |= 0b001; }
  36029. if (RMA_loadedTextures == 0) { return 0; }
  36030. //set w and h to the biggest texture size
  36031. int w = 0, h = 0;
  36032. GpuTexture textures[3] = { roughness, metallic, ambientOcclusion};
  36033. for (int i = 0; i < 3; i++)
  36034. {
  36035. if (textures[i].id)
  36036. {
  36037. auto s = textures[i].getTextureSize();
  36038. if (s.x > w) { w = s.x; }
  36039. if (s.y > h) { h = s.y; }
  36040. }
  36041. }
  36042. glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
  36043. GLuint texture = 0;
  36044. glGenTextures(1, &texture);
  36045. glBindTexture(GL_TEXTURE_2D, texture);
  36046. GpuTexture{texture}.setTextureQuality(quality);
  36047. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  36048. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  36049. //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  36050. //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36051. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  36052. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
  36053. glBindVertexArray(quadVAO);
  36054. shader.bind();
  36055. glActiveTexture(GL_TEXTURE0);
  36056. glBindTexture(GL_TEXTURE_2D, roughness.id);
  36057. glActiveTexture(GL_TEXTURE1);
  36058. glBindTexture(GL_TEXTURE_2D, metallic.id);
  36059. glActiveTexture(GL_TEXTURE2);
  36060. glBindTexture(GL_TEXTURE_2D, ambientOcclusion.id);
  36061. glViewport(0, 0, w, h);
  36062. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  36063. glBindTexture(GL_TEXTURE_2D, texture);
  36064. glGenerateMipmap(GL_TEXTURE_2D);
  36065. glBindVertexArray(0);
  36066. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  36067. return texture;
  36068. }
  36069. void Renderer3D::DirectionalShadows::allocateTextures(int count)
  36070. {
  36071. textureCount = count;
  36072. currentShadowSize = shadowSize;
  36073. GLuint textures[2] = { cascadesTexture, staticGeometryTexture };
  36074. float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  36075. for (int i = 0; i < 2; i++)
  36076. {
  36077. glBindTexture(GL_TEXTURE_2D_ARRAY, textures[i]);
  36078. glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, shadowSize, shadowSize * CASCADES,
  36079. textureCount, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
  36080. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36081. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36082. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  36083. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  36084. glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, borderColor);
  36085. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36086. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36087. }
  36088. }
  36089. void Renderer3D::DirectionalShadows::clear()
  36090. {
  36091. glDeleteTextures(1, &cascadesTexture);
  36092. glDeleteTextures(1, &staticGeometryTexture);
  36093. glDeleteFramebuffers(1, &cascadesFbo);
  36094. glDeleteFramebuffers(1, &staticGeometryFbo);
  36095. }
  36096. void Renderer3D::DirectionalShadows::create(GLuint frameBuffer)
  36097. {
  36098. float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  36099. glGenTextures(1, &cascadesTexture);
  36100. glGenTextures(1, &staticGeometryTexture);
  36101. GLuint textures[2] = { cascadesTexture, staticGeometryTexture };
  36102. for(int i=0; i<2; i++)
  36103. {
  36104. glBindTexture(GL_TEXTURE_2D_ARRAY, textures[i]);
  36105. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36106. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36107. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  36108. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  36109. glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, borderColor);
  36110. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36111. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36112. }
  36113. glGenFramebuffers(1, &cascadesFbo);
  36114. glGenFramebuffers(1, &staticGeometryFbo);
  36115. GLuint fbos[2] = { cascadesFbo, staticGeometryFbo };
  36116. for (int i = 0; i < 2; i++)
  36117. {
  36118. glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
  36119. glDrawBuffer(GL_NONE); //why am i doing this tho? dont remember
  36120. glReadBuffer(GL_NONE);
  36121. }
  36122. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  36123. }
  36124. void Renderer3D::AdaptiveResolution::create(int w, int h)
  36125. {
  36126. if (useAdaptiveResolution)
  36127. {
  36128. currentDimensions = glm::ivec2(w*rezRatio, h*rezRatio);
  36129. }
  36130. else
  36131. {
  36132. currentDimensions = glm::ivec2(w, h);
  36133. }
  36134. glGenFramebuffers(1, &fbo);
  36135. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  36136. glGenTextures(1, &texture);
  36137. glBindTexture(GL_TEXTURE_2D, texture);
  36138. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, currentDimensions.x, currentDimensions.y
  36139. , 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  36140. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36141. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36142. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36143. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36144. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
  36145. glGenFramebuffers(1, &fbo2);
  36146. glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
  36147. glGenTextures(1, &texture2);
  36148. glBindTexture(GL_TEXTURE_2D, texture2);
  36149. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, currentDimensions.x, currentDimensions.y
  36150. , 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  36151. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36152. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36153. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36154. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36155. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
  36156. }
  36157. void Renderer3D::AdaptiveResolution::resize(int w, int h)
  36158. {
  36159. if (currentDimensions.x != w || currentDimensions.y != h)
  36160. {
  36161. glBindTexture(GL_TEXTURE_2D, texture2);
  36162. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h,
  36163. 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  36164. glBindTexture(GL_TEXTURE_2D, texture);
  36165. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h,
  36166. 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  36167. currentDimensions = glm::ivec2(w, h);
  36168. }
  36169. }
  36170. void Renderer3D::AdaptiveResolution::clear()
  36171. {
  36172. glDeleteFramebuffers(1, &fbo);
  36173. glDeleteTextures(1, &texture);
  36174. glDeleteFramebuffers(1, &fbo2);
  36175. glDeleteTextures(1, &texture2);
  36176. }
  36177. void Renderer3D::AntiAlias::create(ErrorReporter &errorReporter, FileOpener &fileOpener)
  36178. {
  36179. shader.loadShaderProgramFromFile("shaders/drawQuads.vert",
  36180. "shaders/aa/fxaa.frag", errorReporter, fileOpener);
  36181. u_texture = getUniform(shader.id, "u_texture", errorReporter);
  36182. u_FXAAData = glGetUniformBlockIndex(shader.id, "u_FXAAData");
  36183. glGenBuffers(1, &fxaaDataBuffer);
  36184. glBindBuffer(GL_UNIFORM_BUFFER, fxaaDataBuffer);
  36185. glBufferData(GL_UNIFORM_BUFFER, sizeof(fxaaData), &fxaaData, GL_DYNAMIC_DRAW);
  36186. glUniformBlockBinding(shader.id, u_FXAAData, internal::FXAADataBlockBinding);
  36187. glBindBufferBase(GL_UNIFORM_BUFFER, internal::FXAADataBlockBinding, fxaaDataBuffer);
  36188. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  36189. noAAshader.loadShaderProgramFromFile("shaders/drawQuads.vert",
  36190. "shaders/aa/noaa.frag", errorReporter, fileOpener);
  36191. noAAu_texture = getUniform(noAAshader.id, "u_texture", errorReporter);
  36192. }
  36193. void Renderer3D::AntiAlias::clear()
  36194. {
  36195. shader.clear();
  36196. noAAshader.clear();
  36197. glDeleteBuffers(1, &fxaaDataBuffer);
  36198. }
  36199. void Renderer3D::PointShadows::create(GLuint frameBuffer)
  36200. {
  36201. glGenTextures(1, &shadowTextures);
  36202. glGenTextures(1, &staticGeometryTextures);
  36203. GLuint textures[2] = { shadowTextures , staticGeometryTextures };
  36204. for (int i = 0; i < 2; i++)
  36205. {
  36206. glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[i]);
  36207. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36208. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36209. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36210. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36211. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  36212. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36213. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36214. }
  36215. glGenFramebuffers(1, &fbo);
  36216. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  36217. glDrawBuffer(GL_NONE);
  36218. glReadBuffer(GL_NONE);
  36219. glGenFramebuffers(1, &staticGeometryFbo);
  36220. glBindFramebuffer(GL_FRAMEBUFFER, staticGeometryFbo);
  36221. glDrawBuffer(GL_NONE);
  36222. glReadBuffer(GL_NONE);
  36223. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  36224. }
  36225. void Renderer3D::PointShadows::allocateTextures(int count)
  36226. {
  36227. textureCount = count;
  36228. currentShadowSize = shadowSize;
  36229. GLuint textures[2] = { shadowTextures , staticGeometryTextures };
  36230. for (int i = 0; i < 2; i++)
  36231. {
  36232. glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[i]);
  36233. glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0,
  36234. GL_DEPTH_COMPONENT32, shadowSize, shadowSize,
  36235. textureCount*6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
  36236. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36237. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36238. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36239. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36240. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  36241. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36242. glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36243. }
  36244. }
  36245. void Renderer3D::PointShadows::clear()
  36246. {
  36247. glDeleteTextures(1, &shadowTextures);
  36248. glDeleteTextures(1, &staticGeometryTextures);
  36249. glDeleteFramebuffers(1, &fbo);
  36250. glDeleteFramebuffers(1, &staticGeometryFbo);
  36251. }
  36252. void Renderer3D::SpotShadows::create(GLuint frameBuffer)
  36253. {
  36254. float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  36255. glGenTextures(1, &shadowTextures);
  36256. glGenTextures(1, &staticGeometryTextures);
  36257. glGenFramebuffers(1, &fbo);
  36258. glGenFramebuffers(1, &staticGeometryfbo);
  36259. GLuint textures[2] = { shadowTextures , staticGeometryTextures };
  36260. for (int i = 0; i < 2; i++)
  36261. {
  36262. glBindTexture(GL_TEXTURE_2D_ARRAY, textures[i]);
  36263. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36264. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36265. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  36266. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  36267. glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, borderColor);
  36268. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36269. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36270. }
  36271. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  36272. glDrawBuffer(GL_NONE);
  36273. glReadBuffer(GL_NONE);
  36274. glBindFramebuffer(GL_FRAMEBUFFER, staticGeometryfbo);
  36275. glDrawBuffer(GL_NONE);
  36276. glReadBuffer(GL_NONE);
  36277. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  36278. }
  36279. void Renderer3D::SpotShadows::allocateTextures(int count)
  36280. {
  36281. textureCount = count;
  36282. currentShadowSize = shadowSize;
  36283. float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  36284. GLuint textures[2] = { shadowTextures , staticGeometryTextures };
  36285. for (int i = 0; i < 2; i++)
  36286. {
  36287. glBindTexture(GL_TEXTURE_2D_ARRAY, textures[i]);
  36288. glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, shadowSize, shadowSize,
  36289. textureCount, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
  36290. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  36291. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  36292. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  36293. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  36294. glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, borderColor);
  36295. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  36296. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  36297. }
  36298. }
  36299. void Renderer3D::SpotShadows::clear()
  36300. {
  36301. glDeleteTextures(1, &shadowTextures);
  36302. glDeleteTextures(1, &staticGeometryTextures);
  36303. glDeleteFramebuffers(1, &fbo);
  36304. glDeleteFramebuffers(1, &staticGeometryfbo);
  36305. }
  36306. void Renderer3D::InternalStruct::GBuffer::create(int w, int h, ErrorReporter &errorReporter, GLuint frameBuffer)
  36307. {
  36308. glGenFramebuffers(1, &gBuffer);
  36309. glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
  36310. glGenTextures(bufferCount, buffers);
  36311. //todo refactor
  36312. //todo glGetInternalFormativ(GL_TEXTURE_2D, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &preferred_format).
  36313. //https://www.khronos.org/opengl/wiki/Common_Mistakes#Extensions_and_OpenGL_Versions
  36314. glBindTexture(GL_TEXTURE_2D, buffers[normal]);
  36315. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, NULL);
  36316. //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
  36317. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36318. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36319. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36320. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36321. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffers[normal], 0);
  36322. glBindTexture(GL_TEXTURE_2D, buffers[textureDerivates]);
  36323. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, NULL);
  36324. //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
  36325. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36326. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36327. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36328. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36329. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, buffers[textureDerivates], 0);
  36330. glBindTexture(GL_TEXTURE_2D, buffers[positionViewSpace]);
  36331. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
  36332. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36333. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36334. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36335. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36336. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, buffers[positionViewSpace], 0);
  36337. glBindTexture(GL_TEXTURE_2D, buffers[materialIndex]);
  36338. glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, 1, 1, 0, GL_RED_INTEGER, GL_SHORT, NULL);
  36339. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36340. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36341. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36342. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36343. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, buffers[materialIndex], 0);
  36344. glBindTexture(GL_TEXTURE_2D, buffers[textureUV]);
  36345. glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, 1, 1, 0, GL_RG, GL_FLOAT, NULL);
  36346. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36347. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36348. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36349. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36350. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, buffers[textureUV], 0);
  36351. unsigned int attachments[bufferCount] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
  36352. GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4};
  36353. glDrawBuffers(bufferCount, attachments);
  36354. //glGenRenderbuffers(1, &depthBuffer);
  36355. //glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
  36356. //glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1, 1);
  36357. //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
  36358. glGenTextures(1, &depthBuffer);
  36359. glBindTexture(GL_TEXTURE_2D, depthBuffer);
  36360. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  36361. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36362. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36363. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36364. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36365. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
  36366. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthBuffer, 0);
  36367. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  36368. {
  36369. errorReporter.callErrorCallback("Gbuffer failed");
  36370. }
  36371. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  36372. resize(w, h);
  36373. }
  36374. void Renderer3D::InternalStruct::GBuffer::resize(int w, int h)
  36375. {
  36376. if (currentDimensions.x != w || currentDimensions.y != h)
  36377. {
  36378. glBindTexture(GL_TEXTURE_2D, buffers[normal]);
  36379. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, w, h, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, NULL);
  36380. //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
  36381. glBindTexture(GL_TEXTURE_2D, buffers[positionViewSpace]);
  36382. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
  36383. glBindTexture(GL_TEXTURE_2D, buffers[materialIndex]);
  36384. glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, w, h, 0, GL_RED_INTEGER, GL_SHORT, NULL);
  36385. glBindTexture(GL_TEXTURE_2D, buffers[textureUV]);
  36386. glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, w, h, 0, GL_RG, GL_FLOAT, NULL);
  36387. glBindTexture(GL_TEXTURE_2D, buffers[textureDerivates]);
  36388. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16UI, w, h, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, NULL);
  36389. //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
  36390. //glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
  36391. //glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
  36392. glBindTexture(GL_TEXTURE_2D, depthBuffer);
  36393. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  36394. currentDimensions = glm::ivec2(w, h);
  36395. }
  36396. }
  36397. void Renderer3D::InternalStruct::GBuffer::clear()
  36398. {
  36399. glDeleteFramebuffers(1, &gBuffer);
  36400. glDeleteTextures(bufferCount, buffers);
  36401. glDeleteTextures(1, &depthBuffer);
  36402. }
  36403. void Renderer3D::InternalStruct::HBAO::create(ErrorReporter &errorReporter, FileOpener &fileOpener)
  36404. {
  36405. shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/hbao/hbao.frag", errorReporter, fileOpener);
  36406. u_projection = getUniform(shader.id, "u_projection", errorReporter);
  36407. u_view = getUniform(shader.id, "u_view", errorReporter);
  36408. u_gPosition = getUniform(shader.id, "u_gPosition", errorReporter);
  36409. u_gNormal = getUniform(shader.id, "u_gNormal", errorReporter);
  36410. u_texNoise = getUniform(shader.id, "u_texNoise", errorReporter);
  36411. }
  36412. void Renderer3D::InternalStruct::HBAO::clear()
  36413. {
  36414. shader.clear();
  36415. }
  36416. void Renderer3D::CopyDepth::create(ErrorReporter &errorReporter, FileOpener &fileOpener)
  36417. {
  36418. shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/copyDepth.frag", errorReporter, fileOpener);
  36419. u_depth = getUniform(shader.id, "u_depth", errorReporter);
  36420. }
  36421. void Renderer3D::CopyDepth::clear()
  36422. {
  36423. shader.clear();
  36424. }
  36425. void Renderer3D::ColorCorrection::create(int w, int h, ErrorReporter &errorReporter, FileOpener &fileOpener)
  36426. {
  36427. shader.loadShaderProgramFromFile("shaders/drawQuads.vert", "shaders/postProcess/colorCorrection.frag", errorReporter, fileOpener);
  36428. u_texture = getUniform(shader.id, "u_texture", errorReporter);
  36429. u_lookup = getUniform(shader.id, "u_lookup", errorReporter);
  36430. glGenFramebuffers(1, &fbo);
  36431. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  36432. glGenTextures(1, &texture);
  36433. glBindTexture(GL_TEXTURE_2D, texture);
  36434. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
  36435. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  36436. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  36437. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36438. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36439. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
  36440. resize(w, h);
  36441. glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
  36442. }
  36443. void Renderer3D::ColorCorrection::resize(int w, int h)
  36444. {
  36445. if (currentDimensions.x != w || currentDimensions.y != h)
  36446. {
  36447. glBindTexture(GL_TEXTURE_2D, texture);
  36448. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
  36449. 0, GL_RGBA, GL_FLOAT, NULL);
  36450. currentDimensions = glm::ivec2(w, h);
  36451. }
  36452. }
  36453. void Renderer3D::ColorCorrection::clear()
  36454. {
  36455. glDeleteFramebuffers(1, &fbo);
  36456. glDeleteTextures(1, &texture);
  36457. shader.clear();
  36458. }
  36459. };
  36460. #pragma endregion