unit-ubjson.cpp 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526
  1. /*
  2. __ _____ _____ _____
  3. __| | __| | | | JSON for Modern C++ (test suite)
  4. | | |__ | | | | | | version 3.7.3
  5. |_____|_____|_____|_|___| https://github.com/nlohmann/json
  6. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
  7. SPDX-License-Identifier: MIT
  8. Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
  9. Permission is hereby granted, free of charge, to any person obtaining a copy
  10. of this software and associated documentation files (the "Software"), to deal
  11. in the Software without restriction, including without limitation the rights
  12. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. copies of the Software, and to permit persons to whom the Software is
  14. furnished to do so, subject to the following conditions:
  15. The above copyright notice and this permission notice shall be included in all
  16. copies or substantial portions of the Software.
  17. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. SOFTWARE.
  24. */
  25. #include "doctest_compatibility.h"
  26. #include <nlohmann/json.hpp>
  27. using nlohmann::json;
  28. #include <fstream>
  29. #include <set>
  30. #include <test_data.hpp>
  31. namespace
  32. {
  33. class SaxCountdown
  34. {
  35. public:
  36. explicit SaxCountdown(const int count) : events_left(count)
  37. {}
  38. bool null()
  39. {
  40. return events_left-- > 0;
  41. }
  42. bool boolean(bool)
  43. {
  44. return events_left-- > 0;
  45. }
  46. bool number_integer(json::number_integer_t)
  47. {
  48. return events_left-- > 0;
  49. }
  50. bool number_unsigned(json::number_unsigned_t)
  51. {
  52. return events_left-- > 0;
  53. }
  54. bool number_float(json::number_float_t, const std::string&)
  55. {
  56. return events_left-- > 0;
  57. }
  58. bool string(std::string&)
  59. {
  60. return events_left-- > 0;
  61. }
  62. bool binary(std::vector<std::uint8_t>&)
  63. {
  64. return events_left-- > 0;
  65. }
  66. bool start_object(std::size_t)
  67. {
  68. return events_left-- > 0;
  69. }
  70. bool key(std::string&)
  71. {
  72. return events_left-- > 0;
  73. }
  74. bool end_object()
  75. {
  76. return events_left-- > 0;
  77. }
  78. bool start_array(std::size_t)
  79. {
  80. return events_left-- > 0;
  81. }
  82. bool end_array()
  83. {
  84. return events_left-- > 0;
  85. }
  86. bool parse_error(std::size_t, const std::string&, const json::exception&)
  87. {
  88. return false;
  89. }
  90. private:
  91. int events_left = 0;
  92. };
  93. }
  94. TEST_CASE("UBJSON")
  95. {
  96. SECTION("individual values")
  97. {
  98. SECTION("discarded")
  99. {
  100. // discarded values are not serialized
  101. json j = json::value_t::discarded;
  102. const auto result = json::to_ubjson(j);
  103. CHECK(result.empty());
  104. }
  105. SECTION("null")
  106. {
  107. json j = nullptr;
  108. std::vector<uint8_t> expected = {'Z'};
  109. const auto result = json::to_ubjson(j);
  110. CHECK(result == expected);
  111. // roundtrip
  112. CHECK(json::from_ubjson(result) == j);
  113. CHECK(json::from_ubjson(result, true, false) == j);
  114. }
  115. SECTION("boolean")
  116. {
  117. SECTION("true")
  118. {
  119. json j = true;
  120. std::vector<uint8_t> expected = {'T'};
  121. const auto result = json::to_ubjson(j);
  122. CHECK(result == expected);
  123. // roundtrip
  124. CHECK(json::from_ubjson(result) == j);
  125. CHECK(json::from_ubjson(result, true, false) == j);
  126. }
  127. SECTION("false")
  128. {
  129. json j = false;
  130. std::vector<uint8_t> expected = {'F'};
  131. const auto result = json::to_ubjson(j);
  132. CHECK(result == expected);
  133. // roundtrip
  134. CHECK(json::from_ubjson(result) == j);
  135. CHECK(json::from_ubjson(result, true, false) == j);
  136. }
  137. }
  138. SECTION("number")
  139. {
  140. SECTION("signed")
  141. {
  142. SECTION("-9223372036854775808..-2147483649 (int64)")
  143. {
  144. std::vector<int64_t> numbers;
  145. numbers.push_back((std::numeric_limits<int64_t>::min)());
  146. numbers.push_back(-1000000000000000000ll);
  147. numbers.push_back(-100000000000000000ll);
  148. numbers.push_back(-10000000000000000ll);
  149. numbers.push_back(-1000000000000000ll);
  150. numbers.push_back(-100000000000000ll);
  151. numbers.push_back(-10000000000000ll);
  152. numbers.push_back(-1000000000000ll);
  153. numbers.push_back(-100000000000ll);
  154. numbers.push_back(-10000000000ll);
  155. numbers.push_back(-2147483649ll);
  156. for (auto i : numbers)
  157. {
  158. CAPTURE(i)
  159. // create JSON value with integer number
  160. json j = i;
  161. // check type
  162. CHECK(j.is_number_integer());
  163. // create expected byte vector
  164. std::vector<uint8_t> expected;
  165. expected.push_back(static_cast<uint8_t>('L'));
  166. expected.push_back(static_cast<uint8_t>((i >> 56) & 0xff));
  167. expected.push_back(static_cast<uint8_t>((i >> 48) & 0xff));
  168. expected.push_back(static_cast<uint8_t>((i >> 40) & 0xff));
  169. expected.push_back(static_cast<uint8_t>((i >> 32) & 0xff));
  170. expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
  171. expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
  172. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  173. expected.push_back(static_cast<uint8_t>(i & 0xff));
  174. // compare result + size
  175. const auto result = json::to_ubjson(j);
  176. CHECK(result == expected);
  177. CHECK(result.size() == 9);
  178. // check individual bytes
  179. CHECK(result[0] == 'L');
  180. int64_t restored = (static_cast<int64_t>(result[1]) << 070) +
  181. (static_cast<int64_t>(result[2]) << 060) +
  182. (static_cast<int64_t>(result[3]) << 050) +
  183. (static_cast<int64_t>(result[4]) << 040) +
  184. (static_cast<int64_t>(result[5]) << 030) +
  185. (static_cast<int64_t>(result[6]) << 020) +
  186. (static_cast<int64_t>(result[7]) << 010) +
  187. static_cast<int64_t>(result[8]);
  188. CHECK(restored == i);
  189. // roundtrip
  190. CHECK(json::from_ubjson(result) == j);
  191. CHECK(json::from_ubjson(result, true, false) == j);
  192. }
  193. }
  194. SECTION("-2147483648..-32769 (int32)")
  195. {
  196. std::vector<int32_t> numbers;
  197. numbers.push_back(-32769);
  198. numbers.push_back(-100000);
  199. numbers.push_back(-1000000);
  200. numbers.push_back(-10000000);
  201. numbers.push_back(-100000000);
  202. numbers.push_back(-1000000000);
  203. numbers.push_back(-2147483647 - 1); // https://stackoverflow.com/a/29356002/266378
  204. for (auto i : numbers)
  205. {
  206. CAPTURE(i)
  207. // create JSON value with integer number
  208. json j = i;
  209. // check type
  210. CHECK(j.is_number_integer());
  211. // create expected byte vector
  212. std::vector<uint8_t> expected;
  213. expected.push_back(static_cast<uint8_t>('l'));
  214. expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
  215. expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
  216. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  217. expected.push_back(static_cast<uint8_t>(i & 0xff));
  218. // compare result + size
  219. const auto result = json::to_ubjson(j);
  220. CHECK(result == expected);
  221. CHECK(result.size() == 5);
  222. // check individual bytes
  223. CHECK(result[0] == 'l');
  224. int32_t restored = (static_cast<int32_t>(result[1]) << 030) +
  225. (static_cast<int32_t>(result[2]) << 020) +
  226. (static_cast<int32_t>(result[3]) << 010) +
  227. static_cast<int32_t>(result[4]);
  228. CHECK(restored == i);
  229. // roundtrip
  230. CHECK(json::from_ubjson(result) == j);
  231. CHECK(json::from_ubjson(result, true, false) == j);
  232. }
  233. }
  234. SECTION("-32768..-129 (int16)")
  235. {
  236. for (int32_t i = -32768; i <= -129; ++i)
  237. {
  238. CAPTURE(i)
  239. // create JSON value with integer number
  240. json j = i;
  241. // check type
  242. CHECK(j.is_number_integer());
  243. // create expected byte vector
  244. std::vector<uint8_t> expected;
  245. expected.push_back(static_cast<uint8_t>('I'));
  246. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  247. expected.push_back(static_cast<uint8_t>(i & 0xff));
  248. // compare result + size
  249. const auto result = json::to_ubjson(j);
  250. CHECK(result == expected);
  251. CHECK(result.size() == 3);
  252. // check individual bytes
  253. CHECK(result[0] == 'I');
  254. int16_t restored = static_cast<int16_t>(((result[1] << 8) + result[2]));
  255. CHECK(restored == i);
  256. // roundtrip
  257. CHECK(json::from_ubjson(result) == j);
  258. CHECK(json::from_ubjson(result, true, false) == j);
  259. }
  260. }
  261. SECTION("-9263 (int16)")
  262. {
  263. json j = -9263;
  264. std::vector<uint8_t> expected = {'I', 0xdb, 0xd1};
  265. // compare result + size
  266. const auto result = json::to_ubjson(j);
  267. CHECK(result == expected);
  268. CHECK(result.size() == 3);
  269. // check individual bytes
  270. CHECK(result[0] == 'I');
  271. int16_t restored = static_cast<int16_t>(((result[1] << 8) + result[2]));
  272. CHECK(restored == -9263);
  273. // roundtrip
  274. CHECK(json::from_ubjson(result) == j);
  275. CHECK(json::from_ubjson(result, true, false) == j);
  276. }
  277. SECTION("-128..-1 (int8)")
  278. {
  279. for (auto i = -128; i <= -1; ++i)
  280. {
  281. CAPTURE(i)
  282. // create JSON value with integer number
  283. json j = i;
  284. // check type
  285. CHECK(j.is_number_integer());
  286. // create expected byte vector
  287. std::vector<uint8_t> expected;
  288. expected.push_back('i');
  289. expected.push_back(static_cast<uint8_t>(i));
  290. // compare result + size
  291. const auto result = json::to_ubjson(j);
  292. CHECK(result == expected);
  293. CHECK(result.size() == 2);
  294. // check individual bytes
  295. CHECK(result[0] == 'i');
  296. CHECK(static_cast<int8_t>(result[1]) == i);
  297. // roundtrip
  298. CHECK(json::from_ubjson(result) == j);
  299. CHECK(json::from_ubjson(result, true, false) == j);
  300. }
  301. }
  302. SECTION("0..127 (int8)")
  303. {
  304. for (size_t i = 0; i <= 127; ++i)
  305. {
  306. CAPTURE(i)
  307. // create JSON value with integer number
  308. json j = -1;
  309. j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
  310. // check type
  311. CHECK(j.is_number_integer());
  312. // create expected byte vector
  313. std::vector<uint8_t> expected;
  314. expected.push_back(static_cast<uint8_t>('i'));
  315. expected.push_back(static_cast<uint8_t>(i));
  316. // compare result + size
  317. const auto result = json::to_ubjson(j);
  318. CHECK(result == expected);
  319. CHECK(result.size() == 2);
  320. // check individual bytes
  321. CHECK(result[0] == 'i');
  322. CHECK(result[1] == i);
  323. // roundtrip
  324. CHECK(json::from_ubjson(result) == j);
  325. CHECK(json::from_ubjson(result, true, false) == j);
  326. }
  327. }
  328. SECTION("128..255 (uint8)")
  329. {
  330. for (size_t i = 128; i <= 255; ++i)
  331. {
  332. CAPTURE(i)
  333. // create JSON value with integer number
  334. json j = -1;
  335. j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
  336. // check type
  337. CHECK(j.is_number_integer());
  338. // create expected byte vector
  339. std::vector<uint8_t> expected;
  340. expected.push_back(static_cast<uint8_t>('U'));
  341. expected.push_back(static_cast<uint8_t>(i));
  342. // compare result + size
  343. const auto result = json::to_ubjson(j);
  344. CHECK(result == expected);
  345. CHECK(result.size() == 2);
  346. // check individual bytes
  347. CHECK(result[0] == 'U');
  348. CHECK(result[1] == i);
  349. // roundtrip
  350. CHECK(json::from_ubjson(result) == j);
  351. CHECK(json::from_ubjson(result, true, false) == j);
  352. }
  353. }
  354. SECTION("256..32767 (int16)")
  355. {
  356. for (size_t i = 256; i <= 32767; ++i)
  357. {
  358. CAPTURE(i)
  359. // create JSON value with integer number
  360. json j = -1;
  361. j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
  362. // check type
  363. CHECK(j.is_number_integer());
  364. // create expected byte vector
  365. std::vector<uint8_t> expected;
  366. expected.push_back(static_cast<uint8_t>('I'));
  367. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  368. expected.push_back(static_cast<uint8_t>(i & 0xff));
  369. // compare result + size
  370. const auto result = json::to_ubjson(j);
  371. CHECK(result == expected);
  372. CHECK(result.size() == 3);
  373. // check individual bytes
  374. CHECK(result[0] == 'I');
  375. uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
  376. CHECK(restored == i);
  377. // roundtrip
  378. CHECK(json::from_ubjson(result) == j);
  379. CHECK(json::from_ubjson(result, true, false) == j);
  380. }
  381. }
  382. SECTION("65536..2147483647 (int32)")
  383. {
  384. for (uint32_t i :
  385. {
  386. 65536u, 77777u, 1048576u
  387. })
  388. {
  389. CAPTURE(i)
  390. // create JSON value with integer number
  391. json j = -1;
  392. j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
  393. // check type
  394. CHECK(j.is_number_integer());
  395. // create expected byte vector
  396. std::vector<uint8_t> expected;
  397. expected.push_back('l');
  398. expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
  399. expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
  400. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  401. expected.push_back(static_cast<uint8_t>(i & 0xff));
  402. // compare result + size
  403. const auto result = json::to_ubjson(j);
  404. CHECK(result == expected);
  405. CHECK(result.size() == 5);
  406. // check individual bytes
  407. CHECK(result[0] == 'l');
  408. uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
  409. (static_cast<uint32_t>(result[2]) << 020) +
  410. (static_cast<uint32_t>(result[3]) << 010) +
  411. static_cast<uint32_t>(result[4]);
  412. CHECK(restored == i);
  413. // roundtrip
  414. CHECK(json::from_ubjson(result) == j);
  415. CHECK(json::from_ubjson(result, true, false) == j);
  416. }
  417. }
  418. SECTION("2147483648..9223372036854775807 (int64)")
  419. {
  420. std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};
  421. for (uint64_t i : v)
  422. {
  423. CAPTURE(i)
  424. // create JSON value with integer number
  425. json j = -1;
  426. j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
  427. // check type
  428. CHECK(j.is_number_integer());
  429. // create expected byte vector
  430. std::vector<uint8_t> expected;
  431. expected.push_back('L');
  432. expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
  433. expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
  434. expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
  435. expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
  436. expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
  437. expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
  438. expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
  439. expected.push_back(static_cast<uint8_t>(i & 0xff));
  440. // compare result + size
  441. const auto result = json::to_ubjson(j);
  442. CHECK(result == expected);
  443. CHECK(result.size() == 9);
  444. // check individual bytes
  445. CHECK(result[0] == 'L');
  446. uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
  447. (static_cast<uint64_t>(result[2]) << 060) +
  448. (static_cast<uint64_t>(result[3]) << 050) +
  449. (static_cast<uint64_t>(result[4]) << 040) +
  450. (static_cast<uint64_t>(result[5]) << 030) +
  451. (static_cast<uint64_t>(result[6]) << 020) +
  452. (static_cast<uint64_t>(result[7]) << 010) +
  453. static_cast<uint64_t>(result[8]);
  454. CHECK(restored == i);
  455. // roundtrip
  456. CHECK(json::from_ubjson(result) == j);
  457. CHECK(json::from_ubjson(result, true, false) == j);
  458. }
  459. }
  460. }
  461. SECTION("unsigned")
  462. {
  463. SECTION("0..127 (int8)")
  464. {
  465. for (size_t i = 0; i <= 127; ++i)
  466. {
  467. CAPTURE(i)
  468. // create JSON value with unsigned integer number
  469. json j = i;
  470. // check type
  471. CHECK(j.is_number_unsigned());
  472. // create expected byte vector
  473. std::vector<uint8_t> expected;
  474. expected.push_back('i');
  475. expected.push_back(static_cast<uint8_t>(i));
  476. // compare result + size
  477. const auto result = json::to_ubjson(j);
  478. CHECK(result == expected);
  479. CHECK(result.size() == 2);
  480. // check individual bytes
  481. CHECK(result[0] == 'i');
  482. uint8_t restored = static_cast<uint8_t>(result[1]);
  483. CHECK(restored == i);
  484. // roundtrip
  485. CHECK(json::from_ubjson(result) == j);
  486. CHECK(json::from_ubjson(result, true, false) == j);
  487. }
  488. }
  489. SECTION("128..255 (uint8)")
  490. {
  491. for (size_t i = 128; i <= 255; ++i)
  492. {
  493. CAPTURE(i)
  494. // create JSON value with unsigned integer number
  495. json j = i;
  496. // check type
  497. CHECK(j.is_number_unsigned());
  498. // create expected byte vector
  499. std::vector<uint8_t> expected;
  500. expected.push_back('U');
  501. expected.push_back(static_cast<uint8_t>(i));
  502. // compare result + size
  503. const auto result = json::to_ubjson(j);
  504. CHECK(result == expected);
  505. CHECK(result.size() == 2);
  506. // check individual bytes
  507. CHECK(result[0] == 'U');
  508. uint8_t restored = static_cast<uint8_t>(result[1]);
  509. CHECK(restored == i);
  510. // roundtrip
  511. CHECK(json::from_ubjson(result) == j);
  512. CHECK(json::from_ubjson(result, true, false) == j);
  513. }
  514. }
  515. SECTION("256..32767 (int16)")
  516. {
  517. for (size_t i = 256; i <= 32767; ++i)
  518. {
  519. CAPTURE(i)
  520. // create JSON value with unsigned integer number
  521. json j = i;
  522. // check type
  523. CHECK(j.is_number_unsigned());
  524. // create expected byte vector
  525. std::vector<uint8_t> expected;
  526. expected.push_back('I');
  527. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  528. expected.push_back(static_cast<uint8_t>(i & 0xff));
  529. // compare result + size
  530. const auto result = json::to_ubjson(j);
  531. CHECK(result == expected);
  532. CHECK(result.size() == 3);
  533. // check individual bytes
  534. CHECK(result[0] == 'I');
  535. uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
  536. CHECK(restored == i);
  537. // roundtrip
  538. CHECK(json::from_ubjson(result) == j);
  539. CHECK(json::from_ubjson(result, true, false) == j);
  540. }
  541. }
  542. SECTION("65536..2147483647 (int32)")
  543. {
  544. for (uint32_t i :
  545. {
  546. 65536u, 77777u, 1048576u
  547. })
  548. {
  549. CAPTURE(i)
  550. // create JSON value with unsigned integer number
  551. json j = i;
  552. // check type
  553. CHECK(j.is_number_unsigned());
  554. // create expected byte vector
  555. std::vector<uint8_t> expected;
  556. expected.push_back('l');
  557. expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
  558. expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
  559. expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
  560. expected.push_back(static_cast<uint8_t>(i & 0xff));
  561. // compare result + size
  562. const auto result = json::to_ubjson(j);
  563. CHECK(result == expected);
  564. CHECK(result.size() == 5);
  565. // check individual bytes
  566. CHECK(result[0] == 'l');
  567. uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
  568. (static_cast<uint32_t>(result[2]) << 020) +
  569. (static_cast<uint32_t>(result[3]) << 010) +
  570. static_cast<uint32_t>(result[4]);
  571. CHECK(restored == i);
  572. // roundtrip
  573. CHECK(json::from_ubjson(result) == j);
  574. CHECK(json::from_ubjson(result, true, false) == j);
  575. }
  576. }
  577. SECTION("2147483648..9223372036854775807 (int64)")
  578. {
  579. std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};
  580. for (uint64_t i : v)
  581. {
  582. CAPTURE(i)
  583. // create JSON value with integer number
  584. json j = i;
  585. // check type
  586. CHECK(j.is_number_unsigned());
  587. // create expected byte vector
  588. std::vector<uint8_t> expected;
  589. expected.push_back('L');
  590. expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
  591. expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
  592. expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
  593. expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
  594. expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
  595. expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
  596. expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
  597. expected.push_back(static_cast<uint8_t>(i & 0xff));
  598. // compare result + size
  599. const auto result = json::to_ubjson(j);
  600. CHECK(result == expected);
  601. CHECK(result.size() == 9);
  602. // check individual bytes
  603. CHECK(result[0] == 'L');
  604. uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
  605. (static_cast<uint64_t>(result[2]) << 060) +
  606. (static_cast<uint64_t>(result[3]) << 050) +
  607. (static_cast<uint64_t>(result[4]) << 040) +
  608. (static_cast<uint64_t>(result[5]) << 030) +
  609. (static_cast<uint64_t>(result[6]) << 020) +
  610. (static_cast<uint64_t>(result[7]) << 010) +
  611. static_cast<uint64_t>(result[8]);
  612. CHECK(restored == i);
  613. // roundtrip
  614. CHECK(json::from_ubjson(result) == j);
  615. CHECK(json::from_ubjson(result, true, false) == j);
  616. }
  617. }
  618. }
  619. SECTION("float64")
  620. {
  621. SECTION("3.1415925")
  622. {
  623. double v = 3.1415925;
  624. json j = v;
  625. std::vector<uint8_t> expected =
  626. {
  627. 'D', 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc
  628. };
  629. const auto result = json::to_ubjson(j);
  630. CHECK(result == expected);
  631. // roundtrip
  632. CHECK(json::from_ubjson(result) == j);
  633. CHECK(json::from_ubjson(result) == v);
  634. CHECK(json::from_ubjson(result, true, false) == j);
  635. }
  636. }
  637. }
  638. SECTION("string")
  639. {
  640. SECTION("N = 0..127")
  641. {
  642. for (size_t N = 0; N <= 127; ++N)
  643. {
  644. CAPTURE(N)
  645. // create JSON value with string containing of N * 'x'
  646. const auto s = std::string(N, 'x');
  647. json j = s;
  648. // create expected byte vector
  649. std::vector<uint8_t> expected;
  650. expected.push_back('S');
  651. expected.push_back('i');
  652. expected.push_back(static_cast<uint8_t>(N));
  653. for (size_t i = 0; i < N; ++i)
  654. {
  655. expected.push_back('x');
  656. }
  657. // compare result + size
  658. const auto result = json::to_ubjson(j);
  659. CHECK(result == expected);
  660. CHECK(result.size() == N + 3);
  661. // check that no null byte is appended
  662. if (N > 0)
  663. {
  664. CHECK(result.back() != '\x00');
  665. }
  666. // roundtrip
  667. CHECK(json::from_ubjson(result) == j);
  668. CHECK(json::from_ubjson(result, true, false) == j);
  669. }
  670. }
  671. SECTION("N = 128..255")
  672. {
  673. for (size_t N = 128; N <= 255; ++N)
  674. {
  675. CAPTURE(N)
  676. // create JSON value with string containing of N * 'x'
  677. const auto s = std::string(N, 'x');
  678. json j = s;
  679. // create expected byte vector
  680. std::vector<uint8_t> expected;
  681. expected.push_back('S');
  682. expected.push_back('U');
  683. expected.push_back(static_cast<uint8_t>(N));
  684. for (size_t i = 0; i < N; ++i)
  685. {
  686. expected.push_back('x');
  687. }
  688. // compare result + size
  689. const auto result = json::to_ubjson(j);
  690. CHECK(result == expected);
  691. CHECK(result.size() == N + 3);
  692. // check that no null byte is appended
  693. CHECK(result.back() != '\x00');
  694. // roundtrip
  695. CHECK(json::from_ubjson(result) == j);
  696. CHECK(json::from_ubjson(result, true, false) == j);
  697. }
  698. }
  699. SECTION("N = 256..32767")
  700. {
  701. for (size_t N :
  702. {
  703. 256u, 999u, 1025u, 3333u, 2048u, 32767u
  704. })
  705. {
  706. CAPTURE(N)
  707. // create JSON value with string containing of N * 'x'
  708. const auto s = std::string(N, 'x');
  709. json j = s;
  710. // create expected byte vector (hack: create string first)
  711. std::vector<uint8_t> expected(N, 'x');
  712. // reverse order of commands, because we insert at begin()
  713. expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
  714. expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
  715. expected.insert(expected.begin(), 'I');
  716. expected.insert(expected.begin(), 'S');
  717. // compare result + size
  718. const auto result = json::to_ubjson(j);
  719. CHECK(result == expected);
  720. CHECK(result.size() == N + 4);
  721. // check that no null byte is appended
  722. CHECK(result.back() != '\x00');
  723. // roundtrip
  724. CHECK(json::from_ubjson(result) == j);
  725. CHECK(json::from_ubjson(result, true, false) == j);
  726. }
  727. }
  728. SECTION("N = 65536..2147483647")
  729. {
  730. for (size_t N :
  731. {
  732. 65536u, 77777u, 1048576u
  733. })
  734. {
  735. CAPTURE(N)
  736. // create JSON value with string containing of N * 'x'
  737. const auto s = std::string(N, 'x');
  738. json j = s;
  739. // create expected byte vector (hack: create string first)
  740. std::vector<uint8_t> expected(N, 'x');
  741. // reverse order of commands, because we insert at begin()
  742. expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
  743. expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
  744. expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
  745. expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
  746. expected.insert(expected.begin(), 'l');
  747. expected.insert(expected.begin(), 'S');
  748. // compare result + size
  749. const auto result = json::to_ubjson(j);
  750. CHECK(result == expected);
  751. CHECK(result.size() == N + 6);
  752. // check that no null byte is appended
  753. CHECK(result.back() != '\x00');
  754. // roundtrip
  755. CHECK(json::from_ubjson(result) == j);
  756. CHECK(json::from_ubjson(result, true, false) == j);
  757. }
  758. }
  759. }
  760. SECTION("binary")
  761. {
  762. SECTION("N = 0..127")
  763. {
  764. for (std::size_t N = 0; N <= 127; ++N)
  765. {
  766. CAPTURE(N)
  767. // create JSON value with byte array containing of N * 'x'
  768. const auto s = std::vector<std::uint8_t>(N, 'x');
  769. json j = json::binary(s);
  770. // create expected byte vector
  771. std::vector<std::uint8_t> expected;
  772. expected.push_back(static_cast<std::uint8_t>('['));
  773. if (N != 0)
  774. {
  775. expected.push_back(static_cast<std::uint8_t>('$'));
  776. expected.push_back(static_cast<std::uint8_t>('U'));
  777. }
  778. expected.push_back(static_cast<std::uint8_t>('#'));
  779. expected.push_back(static_cast<std::uint8_t>('i'));
  780. expected.push_back(static_cast<std::uint8_t>(N));
  781. for (size_t i = 0; i < N; ++i)
  782. {
  783. expected.push_back(0x78);
  784. }
  785. // compare result + size
  786. const auto result = json::to_ubjson(j, true, true);
  787. CHECK(result == expected);
  788. if (N == 0)
  789. {
  790. CHECK(result.size() == N + 4);
  791. }
  792. else
  793. {
  794. CHECK(result.size() == N + 6);
  795. }
  796. // check that no null byte is appended
  797. if (N > 0)
  798. {
  799. CHECK(result.back() != '\x00');
  800. }
  801. // roundtrip only works to an array of numbers
  802. json j_out = s;
  803. CHECK(json::from_ubjson(result) == j_out);
  804. CHECK(json::from_ubjson(result, true, false) == j_out);
  805. }
  806. }
  807. SECTION("N = 128..255")
  808. {
  809. for (std::size_t N = 128; N <= 255; ++N)
  810. {
  811. CAPTURE(N)
  812. // create JSON value with byte array containing of N * 'x'
  813. const auto s = std::vector<std::uint8_t>(N, 'x');
  814. json j = json::binary(s);
  815. // create expected byte vector
  816. std::vector<uint8_t> expected;
  817. expected.push_back(static_cast<std::uint8_t>('['));
  818. expected.push_back(static_cast<std::uint8_t>('$'));
  819. expected.push_back(static_cast<std::uint8_t>('U'));
  820. expected.push_back(static_cast<std::uint8_t>('#'));
  821. expected.push_back(static_cast<std::uint8_t>('U'));
  822. expected.push_back(static_cast<std::uint8_t>(N));
  823. for (size_t i = 0; i < N; ++i)
  824. {
  825. expected.push_back(0x78);
  826. }
  827. // compare result + size
  828. const auto result = json::to_ubjson(j, true, true);
  829. CHECK(result == expected);
  830. CHECK(result.size() == N + 6);
  831. // check that no null byte is appended
  832. CHECK(result.back() != '\x00');
  833. // roundtrip only works to an array of numbers
  834. json j_out = s;
  835. CHECK(json::from_ubjson(result) == j_out);
  836. CHECK(json::from_ubjson(result, true, false) == j_out);
  837. }
  838. }
  839. SECTION("N = 256..32767")
  840. {
  841. for (std::size_t N :
  842. {
  843. 256u, 999u, 1025u, 3333u, 2048u, 32767u
  844. })
  845. {
  846. CAPTURE(N)
  847. // create JSON value with byte array containing of N * 'x'
  848. const auto s = std::vector<std::uint8_t>(N, 'x');
  849. json j = json::binary(s);
  850. // create expected byte vector
  851. std::vector<std::uint8_t> expected(N + 7, 'x');
  852. expected[0] = '[';
  853. expected[1] = '$';
  854. expected[2] = 'U';
  855. expected[3] = '#';
  856. expected[4] = 'I';
  857. expected[5] = static_cast<std::uint8_t>((N >> 8) & 0xFF);
  858. expected[6] = static_cast<std::uint8_t>(N & 0xFF);
  859. // compare result + size
  860. const auto result = json::to_ubjson(j, true, true);
  861. CHECK(result == expected);
  862. CHECK(result.size() == N + 7);
  863. // check that no null byte is appended
  864. CHECK(result.back() != '\x00');
  865. // roundtrip only works to an array of numbers
  866. json j_out = s;
  867. CHECK(json::from_ubjson(result) == j_out);
  868. CHECK(json::from_ubjson(result, true, false) == j_out);
  869. }
  870. }
  871. SECTION("N = 32768..2147483647")
  872. {
  873. for (std::size_t N :
  874. {
  875. 32768u, 77777u, 1048576u
  876. })
  877. {
  878. CAPTURE(N)
  879. // create JSON value with byte array containing of N * 'x'
  880. const auto s = std::vector<std::uint8_t>(N, 'x');
  881. json j = json::binary(s);
  882. // create expected byte vector
  883. std::vector<std::uint8_t> expected(N + 9, 'x');
  884. expected[0] = '[';
  885. expected[1] = '$';
  886. expected[2] = 'U';
  887. expected[3] = '#';
  888. expected[4] = 'l';
  889. expected[5] = static_cast<std::uint8_t>((N >> 24) & 0xFF);
  890. expected[6] = static_cast<std::uint8_t>((N >> 16) & 0xFF);
  891. expected[7] = static_cast<std::uint8_t>((N >> 8) & 0xFF);
  892. expected[8] = static_cast<std::uint8_t>(N & 0xFF);
  893. // compare result + size
  894. const auto result = json::to_ubjson(j, true, true);
  895. CHECK(result == expected);
  896. CHECK(result.size() == N + 9);
  897. // check that no null byte is appended
  898. CHECK(result.back() != '\x00');
  899. // roundtrip only works to an array of numbers
  900. json j_out = s;
  901. CHECK(json::from_ubjson(result) == j_out);
  902. CHECK(json::from_ubjson(result, true, false) == j_out);
  903. }
  904. }
  905. SECTION("Other Serializations")
  906. {
  907. const std::size_t N = 10;
  908. const auto s = std::vector<std::uint8_t>(N, 'x');
  909. json j = json::binary(s);
  910. SECTION("No Count No Type")
  911. {
  912. std::vector<uint8_t> expected;
  913. expected.push_back(static_cast<std::uint8_t>('['));
  914. for (std::size_t i = 0; i < N; ++i)
  915. {
  916. expected.push_back(static_cast<std::uint8_t>('U'));
  917. expected.push_back(static_cast<std::uint8_t>(0x78));
  918. }
  919. expected.push_back(static_cast<std::uint8_t>(']'));
  920. // compare result + size
  921. const auto result = json::to_ubjson(j, false, false);
  922. CHECK(result == expected);
  923. CHECK(result.size() == N + 12);
  924. // check that no null byte is appended
  925. CHECK(result.back() != '\x00');
  926. // roundtrip only works to an array of numbers
  927. json j_out = s;
  928. CHECK(json::from_ubjson(result) == j_out);
  929. CHECK(json::from_ubjson(result, true, false) == j_out);
  930. }
  931. SECTION("Yes Count No Type")
  932. {
  933. std::vector<std::uint8_t> expected;
  934. expected.push_back(static_cast<std::uint8_t>('['));
  935. expected.push_back(static_cast<std::uint8_t>('#'));
  936. expected.push_back(static_cast<std::uint8_t>('i'));
  937. expected.push_back(static_cast<std::uint8_t>(N));
  938. for (size_t i = 0; i < N; ++i)
  939. {
  940. expected.push_back(static_cast<std::uint8_t>('U'));
  941. expected.push_back(static_cast<std::uint8_t>(0x78));
  942. }
  943. // compare result + size
  944. const auto result = json::to_ubjson(j, true, false);
  945. CHECK(result == expected);
  946. CHECK(result.size() == N + 14);
  947. // check that no null byte is appended
  948. CHECK(result.back() != '\x00');
  949. // roundtrip only works to an array of numbers
  950. json j_out = s;
  951. CHECK(json::from_ubjson(result) == j_out);
  952. CHECK(json::from_ubjson(result, true, false) == j_out);
  953. }
  954. }
  955. }
  956. SECTION("array")
  957. {
  958. SECTION("empty")
  959. {
  960. SECTION("size=false type=false")
  961. {
  962. json j = json::array();
  963. std::vector<uint8_t> expected = {'[', ']'};
  964. const auto result = json::to_ubjson(j);
  965. CHECK(result == expected);
  966. // roundtrip
  967. CHECK(json::from_ubjson(result) == j);
  968. CHECK(json::from_ubjson(result, true, false) == j);
  969. }
  970. SECTION("size=true type=false")
  971. {
  972. json j = json::array();
  973. std::vector<uint8_t> expected = {'[', '#', 'i', 0};
  974. const auto result = json::to_ubjson(j, true);
  975. CHECK(result == expected);
  976. // roundtrip
  977. CHECK(json::from_ubjson(result) == j);
  978. CHECK(json::from_ubjson(result, true, false) == j);
  979. }
  980. SECTION("size=true type=true")
  981. {
  982. json j = json::array();
  983. std::vector<uint8_t> expected = {'[', '#', 'i', 0};
  984. const auto result = json::to_ubjson(j, true, true);
  985. CHECK(result == expected);
  986. // roundtrip
  987. CHECK(json::from_ubjson(result) == j);
  988. CHECK(json::from_ubjson(result, true, false) == j);
  989. }
  990. }
  991. SECTION("[null]")
  992. {
  993. SECTION("size=false type=false")
  994. {
  995. json j = {nullptr};
  996. std::vector<uint8_t> expected = {'[', 'Z', ']'};
  997. const auto result = json::to_ubjson(j);
  998. CHECK(result == expected);
  999. // roundtrip
  1000. CHECK(json::from_ubjson(result) == j);
  1001. CHECK(json::from_ubjson(result, true, false) == j);
  1002. }
  1003. SECTION("size=true type=false")
  1004. {
  1005. json j = {nullptr};
  1006. std::vector<uint8_t> expected = {'[', '#', 'i', 1, 'Z'};
  1007. const auto result = json::to_ubjson(j, true);
  1008. CHECK(result == expected);
  1009. // roundtrip
  1010. CHECK(json::from_ubjson(result) == j);
  1011. CHECK(json::from_ubjson(result, true, false) == j);
  1012. }
  1013. SECTION("size=true type=true")
  1014. {
  1015. json j = {nullptr};
  1016. std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'i', 1};
  1017. const auto result = json::to_ubjson(j, true, true);
  1018. CHECK(result == expected);
  1019. // roundtrip
  1020. CHECK(json::from_ubjson(result) == j);
  1021. CHECK(json::from_ubjson(result, true, false) == j);
  1022. }
  1023. }
  1024. SECTION("[1,2,3,4,5]")
  1025. {
  1026. SECTION("size=false type=false")
  1027. {
  1028. json j = json::parse("[1,2,3,4,5]");
  1029. std::vector<uint8_t> expected = {'[', 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5, ']'};
  1030. const auto result = json::to_ubjson(j);
  1031. CHECK(result == expected);
  1032. // roundtrip
  1033. CHECK(json::from_ubjson(result) == j);
  1034. CHECK(json::from_ubjson(result, true, false) == j);
  1035. }
  1036. SECTION("size=true type=false")
  1037. {
  1038. json j = json::parse("[1,2,3,4,5]");
  1039. std::vector<uint8_t> expected = {'[', '#', 'i', 5, 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5};
  1040. const auto result = json::to_ubjson(j, true);
  1041. CHECK(result == expected);
  1042. // roundtrip
  1043. CHECK(json::from_ubjson(result) == j);
  1044. CHECK(json::from_ubjson(result, true, false) == j);
  1045. }
  1046. SECTION("size=true type=true")
  1047. {
  1048. json j = json::parse("[1,2,3,4,5]");
  1049. std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 5, 1, 2, 3, 4, 5};
  1050. const auto result = json::to_ubjson(j, true, true);
  1051. CHECK(result == expected);
  1052. // roundtrip
  1053. CHECK(json::from_ubjson(result) == j);
  1054. CHECK(json::from_ubjson(result, true, false) == j);
  1055. }
  1056. }
  1057. SECTION("[[[[]]]]")
  1058. {
  1059. SECTION("size=false type=false")
  1060. {
  1061. json j = json::parse("[[[[]]]]");
  1062. std::vector<uint8_t> expected = {'[', '[', '[', '[', ']', ']', ']', ']'};
  1063. const auto result = json::to_ubjson(j);
  1064. CHECK(result == expected);
  1065. // roundtrip
  1066. CHECK(json::from_ubjson(result) == j);
  1067. CHECK(json::from_ubjson(result, true, false) == j);
  1068. }
  1069. SECTION("size=true type=false")
  1070. {
  1071. json j = json::parse("[[[[]]]]");
  1072. std::vector<uint8_t> expected = {'[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 0};
  1073. const auto result = json::to_ubjson(j, true);
  1074. CHECK(result == expected);
  1075. // roundtrip
  1076. CHECK(json::from_ubjson(result) == j);
  1077. CHECK(json::from_ubjson(result, true, false) == j);
  1078. }
  1079. SECTION("size=true type=true")
  1080. {
  1081. json j = json::parse("[[[[]]]]");
  1082. std::vector<uint8_t> expected = {'[', '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '#', 'i', 0};
  1083. const auto result = json::to_ubjson(j, true, true);
  1084. CHECK(result == expected);
  1085. // roundtrip
  1086. CHECK(json::from_ubjson(result) == j);
  1087. CHECK(json::from_ubjson(result, true, false) == j);
  1088. }
  1089. }
  1090. SECTION("array with uint16_t elements")
  1091. {
  1092. SECTION("size=false type=false")
  1093. {
  1094. json j(257, nullptr);
  1095. std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null
  1096. expected[0] = '['; // opening array
  1097. expected[258] = ']'; // closing array
  1098. const auto result = json::to_ubjson(j);
  1099. CHECK(result == expected);
  1100. // roundtrip
  1101. CHECK(json::from_ubjson(result) == j);
  1102. CHECK(json::from_ubjson(result, true, false) == j);
  1103. }
  1104. SECTION("size=true type=false")
  1105. {
  1106. json j(257, nullptr);
  1107. std::vector<uint8_t> expected(j.size() + 5, 'Z'); // all null
  1108. expected[0] = '['; // opening array
  1109. expected[1] = '#'; // array size
  1110. expected[2] = 'I'; // int16
  1111. expected[3] = 0x01; // 0x0101, first byte
  1112. expected[4] = 0x01; // 0x0101, second byte
  1113. const auto result = json::to_ubjson(j, true);
  1114. CHECK(result == expected);
  1115. // roundtrip
  1116. CHECK(json::from_ubjson(result) == j);
  1117. CHECK(json::from_ubjson(result, true, false) == j);
  1118. }
  1119. SECTION("size=true type=true")
  1120. {
  1121. json j(257, nullptr);
  1122. std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'I', 0x01, 0x01};
  1123. const auto result = json::to_ubjson(j, true, true);
  1124. CHECK(result == expected);
  1125. // roundtrip
  1126. CHECK(json::from_ubjson(result) == j);
  1127. CHECK(json::from_ubjson(result, true, false) == j);
  1128. }
  1129. }
  1130. SECTION("array with uint32_t elements")
  1131. {
  1132. SECTION("size=false type=false")
  1133. {
  1134. json j(65793, nullptr);
  1135. std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null
  1136. expected[0] = '['; // opening array
  1137. expected[65794] = ']'; // closing array
  1138. const auto result = json::to_ubjson(j);
  1139. CHECK(result == expected);
  1140. // roundtrip
  1141. CHECK(json::from_ubjson(result) == j);
  1142. CHECK(json::from_ubjson(result, true, false) == j);
  1143. }
  1144. SECTION("size=true type=false")
  1145. {
  1146. json j(65793, nullptr);
  1147. std::vector<uint8_t> expected(j.size() + 7, 'Z'); // all null
  1148. expected[0] = '['; // opening array
  1149. expected[1] = '#'; // array size
  1150. expected[2] = 'l'; // int32
  1151. expected[3] = 0x00; // 0x00010101, first byte
  1152. expected[4] = 0x01; // 0x00010101, second byte
  1153. expected[5] = 0x01; // 0x00010101, third byte
  1154. expected[6] = 0x01; // 0x00010101, fourth byte
  1155. const auto result = json::to_ubjson(j, true);
  1156. CHECK(result == expected);
  1157. // roundtrip
  1158. CHECK(json::from_ubjson(result) == j);
  1159. CHECK(json::from_ubjson(result, true, false) == j);
  1160. }
  1161. SECTION("size=true type=true")
  1162. {
  1163. json j(65793, nullptr);
  1164. std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'l', 0x00, 0x01, 0x01, 0x01};
  1165. const auto result = json::to_ubjson(j, true, true);
  1166. CHECK(result == expected);
  1167. // roundtrip
  1168. CHECK(json::from_ubjson(result) == j);
  1169. CHECK(json::from_ubjson(result, true, false) == j);
  1170. }
  1171. }
  1172. }
  1173. SECTION("object")
  1174. {
  1175. SECTION("empty")
  1176. {
  1177. SECTION("size=false type=false")
  1178. {
  1179. json j = json::object();
  1180. std::vector<uint8_t> expected = {'{', '}'};
  1181. const auto result = json::to_ubjson(j);
  1182. CHECK(result == expected);
  1183. // roundtrip
  1184. CHECK(json::from_ubjson(result) == j);
  1185. CHECK(json::from_ubjson(result, true, false) == j);
  1186. }
  1187. SECTION("size=true type=false")
  1188. {
  1189. json j = json::object();
  1190. std::vector<uint8_t> expected = {'{', '#', 'i', 0};
  1191. const auto result = json::to_ubjson(j, true);
  1192. CHECK(result == expected);
  1193. // roundtrip
  1194. CHECK(json::from_ubjson(result) == j);
  1195. CHECK(json::from_ubjson(result, true, false) == j);
  1196. }
  1197. SECTION("size=true type=true")
  1198. {
  1199. json j = json::object();
  1200. std::vector<uint8_t> expected = {'{', '#', 'i', 0};
  1201. const auto result = json::to_ubjson(j, true, true);
  1202. CHECK(result == expected);
  1203. // roundtrip
  1204. CHECK(json::from_ubjson(result) == j);
  1205. CHECK(json::from_ubjson(result, true, false) == j);
  1206. }
  1207. }
  1208. SECTION("{\"\":null}")
  1209. {
  1210. SECTION("size=false type=false")
  1211. {
  1212. json j = {{"", nullptr}};
  1213. std::vector<uint8_t> expected = {'{', 'i', 0, 'Z', '}'};
  1214. const auto result = json::to_ubjson(j);
  1215. CHECK(result == expected);
  1216. // roundtrip
  1217. CHECK(json::from_ubjson(result) == j);
  1218. CHECK(json::from_ubjson(result, true, false) == j);
  1219. }
  1220. SECTION("size=true type=false")
  1221. {
  1222. json j = {{"", nullptr}};
  1223. std::vector<uint8_t> expected = {'{', '#', 'i', 1, 'i', 0, 'Z'};
  1224. const auto result = json::to_ubjson(j, true);
  1225. CHECK(result == expected);
  1226. // roundtrip
  1227. CHECK(json::from_ubjson(result) == j);
  1228. CHECK(json::from_ubjson(result, true, false) == j);
  1229. }
  1230. SECTION("size=true type=true")
  1231. {
  1232. json j = {{"", nullptr}};
  1233. std::vector<uint8_t> expected = {'{', '$', 'Z', '#', 'i', 1, 'i', 0};
  1234. const auto result = json::to_ubjson(j, true, true);
  1235. CHECK(result == expected);
  1236. // roundtrip
  1237. CHECK(json::from_ubjson(result) == j);
  1238. CHECK(json::from_ubjson(result, true, false) == j);
  1239. }
  1240. }
  1241. SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
  1242. {
  1243. SECTION("size=false type=false")
  1244. {
  1245. json j = json::parse("{\"a\": {\"b\": {\"c\": {}}}}");
  1246. std::vector<uint8_t> expected =
  1247. {
  1248. '{', 'i', 1, 'a', '{', 'i', 1, 'b', '{', 'i', 1, 'c', '{', '}', '}', '}', '}'
  1249. };
  1250. const auto result = json::to_ubjson(j);
  1251. CHECK(result == expected);
  1252. // roundtrip
  1253. CHECK(json::from_ubjson(result) == j);
  1254. CHECK(json::from_ubjson(result, true, false) == j);
  1255. }
  1256. SECTION("size=true type=false")
  1257. {
  1258. json j = json::parse("{\"a\": {\"b\": {\"c\": {}}}}");
  1259. std::vector<uint8_t> expected =
  1260. {
  1261. '{', '#', 'i', 1, 'i', 1, 'a', '{', '#', 'i', 1, 'i', 1, 'b', '{', '#', 'i', 1, 'i', 1, 'c', '{', '#', 'i', 0
  1262. };
  1263. const auto result = json::to_ubjson(j, true);
  1264. CHECK(result == expected);
  1265. // roundtrip
  1266. CHECK(json::from_ubjson(result) == j);
  1267. CHECK(json::from_ubjson(result, true, false) == j);
  1268. }
  1269. SECTION("size=true type=true")
  1270. {
  1271. json j = json::parse("{\"a\": {\"b\": {\"c\": {}}}}");
  1272. std::vector<uint8_t> expected =
  1273. {
  1274. '{', '$', '{', '#', 'i', 1, 'i', 1, 'a', '$', '{', '#', 'i', 1, 'i', 1, 'b', '$', '{', '#', 'i', 1, 'i', 1, 'c', '#', 'i', 0
  1275. };
  1276. const auto result = json::to_ubjson(j, true, true);
  1277. CHECK(result == expected);
  1278. // roundtrip
  1279. CHECK(json::from_ubjson(result) == j);
  1280. CHECK(json::from_ubjson(result, true, false) == j);
  1281. }
  1282. }
  1283. }
  1284. }
  1285. SECTION("errors")
  1286. {
  1287. SECTION("strict mode")
  1288. {
  1289. std::vector<uint8_t> vec = {'Z', 'Z'};
  1290. SECTION("non-strict mode")
  1291. {
  1292. const auto result = json::from_ubjson(vec, false);
  1293. CHECK(result == json());
  1294. }
  1295. SECTION("strict mode")
  1296. {
  1297. json _;
  1298. CHECK_THROWS_AS(_ = json::from_ubjson(vec), json::parse_error&);
  1299. CHECK_THROWS_WITH(_ = json::from_ubjson(vec),
  1300. "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A");
  1301. }
  1302. }
  1303. SECTION("number out of range")
  1304. {
  1305. // larger than max int64
  1306. json j = 9223372036854775808llu;
  1307. json _;
  1308. CHECK_THROWS_AS(_ = json::to_ubjson(j), json::out_of_range&);
  1309. CHECK_THROWS_WITH(_ = json::to_ubjson(j), "[json.exception.out_of_range.407] integer number 9223372036854775808 cannot be represented by UBJSON as it does not fit int64");
  1310. }
  1311. SECTION("excessive size")
  1312. {
  1313. SECTION("array")
  1314. {
  1315. std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
  1316. json _;
  1317. CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
  1318. json j;
  1319. nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int, json::parse_event_t, const json&)
  1320. {
  1321. return true;
  1322. });
  1323. CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);
  1324. }
  1325. SECTION("object")
  1326. {
  1327. std::vector<uint8_t> v_ubjson = {'{', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
  1328. json _;
  1329. CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
  1330. json j;
  1331. nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int, json::parse_event_t, const json&)
  1332. {
  1333. return true;
  1334. });
  1335. CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);
  1336. }
  1337. }
  1338. }
  1339. SECTION("SAX aborts")
  1340. {
  1341. SECTION("start_array()")
  1342. {
  1343. std::vector<uint8_t> v = {'[', 'T', 'F', ']'};
  1344. SaxCountdown scp(0);
  1345. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1346. }
  1347. SECTION("start_object()")
  1348. {
  1349. std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
  1350. SaxCountdown scp(0);
  1351. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1352. }
  1353. SECTION("key() in object")
  1354. {
  1355. std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
  1356. SaxCountdown scp(1);
  1357. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1358. }
  1359. SECTION("start_array(len)")
  1360. {
  1361. std::vector<uint8_t> v = {'[', '#', 'i', '2', 'T', 'F'};
  1362. SaxCountdown scp(0);
  1363. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1364. }
  1365. SECTION("start_object(len)")
  1366. {
  1367. std::vector<uint8_t> v = {'{', '#', 'i', '1', 3, 'f', 'o', 'o', 'F'};
  1368. SaxCountdown scp(0);
  1369. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1370. }
  1371. SECTION("key() in object with length")
  1372. {
  1373. std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
  1374. SaxCountdown scp(1);
  1375. CHECK(not json::sax_parse(v, &scp, json::input_format_t::ubjson));
  1376. }
  1377. }
  1378. SECTION("parsing values")
  1379. {
  1380. SECTION("strings")
  1381. {
  1382. // create a single-character string for all number types
  1383. std::vector<uint8_t> s_i = {'S', 'i', 1, 'a'};
  1384. std::vector<uint8_t> s_U = {'S', 'U', 1, 'a'};
  1385. std::vector<uint8_t> s_I = {'S', 'I', 0, 1, 'a'};
  1386. std::vector<uint8_t> s_l = {'S', 'l', 0, 0, 0, 1, 'a'};
  1387. std::vector<uint8_t> s_L = {'S', 'L', 0, 0, 0, 0, 0, 0, 0, 1, 'a'};
  1388. // check if string is parsed correctly to "a"
  1389. CHECK(json::from_ubjson(s_i) == "a");
  1390. CHECK(json::from_ubjson(s_U) == "a");
  1391. CHECK(json::from_ubjson(s_I) == "a");
  1392. CHECK(json::from_ubjson(s_l) == "a");
  1393. CHECK(json::from_ubjson(s_L) == "a");
  1394. // roundtrip: output should be optimized
  1395. CHECK(json::to_ubjson(json::from_ubjson(s_i)) == s_i);
  1396. CHECK(json::to_ubjson(json::from_ubjson(s_U)) == s_i);
  1397. CHECK(json::to_ubjson(json::from_ubjson(s_I)) == s_i);
  1398. CHECK(json::to_ubjson(json::from_ubjson(s_l)) == s_i);
  1399. CHECK(json::to_ubjson(json::from_ubjson(s_L)) == s_i);
  1400. }
  1401. SECTION("number")
  1402. {
  1403. SECTION("float")
  1404. {
  1405. // float32
  1406. std::vector<uint8_t> v_d = {'d', 0x40, 0x49, 0x0f, 0xd0};
  1407. CHECK(json::from_ubjson(v_d) == 3.14159f);
  1408. // float64
  1409. std::vector<uint8_t> v_D = {'D', 0x40, 0x09, 0x21, 0xf9, 0xf0, 0x1b, 0x86, 0x6e};
  1410. CHECK(json::from_ubjson(v_D) == 3.14159);
  1411. // float32 is serialized as float64 as the library does not support float32
  1412. CHECK(json::to_ubjson(json::from_ubjson(v_d)) == json::to_ubjson(3.14159f));
  1413. }
  1414. }
  1415. SECTION("array")
  1416. {
  1417. SECTION("optimized version (length only)")
  1418. {
  1419. // create vector with two elements of the same type
  1420. std::vector<uint8_t> v_TU = {'[', '#', 'U', 2, 'T', 'T'};
  1421. std::vector<uint8_t> v_T = {'[', '#', 'i', 2, 'T', 'T'};
  1422. std::vector<uint8_t> v_F = {'[', '#', 'i', 2, 'F', 'F'};
  1423. std::vector<uint8_t> v_Z = {'[', '#', 'i', 2, 'Z', 'Z'};
  1424. std::vector<uint8_t> v_i = {'[', '#', 'i', 2, 'i', 0x7F, 'i', 0x7F};
  1425. std::vector<uint8_t> v_U = {'[', '#', 'i', 2, 'U', 0xFF, 'U', 0xFF};
  1426. std::vector<uint8_t> v_I = {'[', '#', 'i', 2, 'I', 0x7F, 0xFF, 'I', 0x7F, 0xFF};
  1427. std::vector<uint8_t> v_l = {'[', '#', 'i', 2, 'l', 0x7F, 0xFF, 0xFF, 0xFF, 'l', 0x7F, 0xFF, 0xFF, 0xFF};
  1428. std::vector<uint8_t> v_L = {'[', '#', 'i', 2, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  1429. std::vector<uint8_t> v_D = {'[', '#', 'i', 2, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};
  1430. std::vector<uint8_t> v_S = {'[', '#', 'i', 2, 'S', 'i', 1, 'a', 'S', 'i', 1, 'a'};
  1431. std::vector<uint8_t> v_C = {'[', '#', 'i', 2, 'C', 'a', 'C', 'a'};
  1432. // check if vector is parsed correctly
  1433. CHECK(json::from_ubjson(v_TU) == json({true, true}));
  1434. CHECK(json::from_ubjson(v_T) == json({true, true}));
  1435. CHECK(json::from_ubjson(v_F) == json({false, false}));
  1436. CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));
  1437. CHECK(json::from_ubjson(v_i) == json({127, 127}));
  1438. CHECK(json::from_ubjson(v_U) == json({255, 255}));
  1439. CHECK(json::from_ubjson(v_I) == json({32767, 32767}));
  1440. CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));
  1441. CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));
  1442. CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));
  1443. CHECK(json::from_ubjson(v_S) == json({"a", "a"}));
  1444. CHECK(json::from_ubjson(v_C) == json({"a", "a"}));
  1445. // roundtrip: output should be optimized
  1446. CHECK(json::to_ubjson(json::from_ubjson(v_T), true) == v_T);
  1447. CHECK(json::to_ubjson(json::from_ubjson(v_F), true) == v_F);
  1448. CHECK(json::to_ubjson(json::from_ubjson(v_Z), true) == v_Z);
  1449. CHECK(json::to_ubjson(json::from_ubjson(v_i), true) == v_i);
  1450. CHECK(json::to_ubjson(json::from_ubjson(v_U), true) == v_U);
  1451. CHECK(json::to_ubjson(json::from_ubjson(v_I), true) == v_I);
  1452. CHECK(json::to_ubjson(json::from_ubjson(v_l), true) == v_l);
  1453. CHECK(json::to_ubjson(json::from_ubjson(v_L), true) == v_L);
  1454. CHECK(json::to_ubjson(json::from_ubjson(v_D), true) == v_D);
  1455. CHECK(json::to_ubjson(json::from_ubjson(v_S), true) == v_S);
  1456. CHECK(json::to_ubjson(json::from_ubjson(v_C), true) == v_S); // char is serialized to string
  1457. }
  1458. SECTION("optimized version (type and length)")
  1459. {
  1460. // create vector with two elements of the same type
  1461. std::vector<uint8_t> v_N = {'[', '$', 'N', '#', 'i', 2};
  1462. std::vector<uint8_t> v_T = {'[', '$', 'T', '#', 'i', 2};
  1463. std::vector<uint8_t> v_F = {'[', '$', 'F', '#', 'i', 2};
  1464. std::vector<uint8_t> v_Z = {'[', '$', 'Z', '#', 'i', 2};
  1465. std::vector<uint8_t> v_i = {'[', '$', 'i', '#', 'i', 2, 0x7F, 0x7F};
  1466. std::vector<uint8_t> v_U = {'[', '$', 'U', '#', 'i', 2, 0xFF, 0xFF};
  1467. std::vector<uint8_t> v_I = {'[', '$', 'I', '#', 'i', 2, 0x7F, 0xFF, 0x7F, 0xFF};
  1468. std::vector<uint8_t> v_l = {'[', '$', 'l', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF};
  1469. std::vector<uint8_t> v_L = {'[', '$', 'L', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  1470. std::vector<uint8_t> v_D = {'[', '$', 'D', '#', 'i', 2, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};
  1471. std::vector<uint8_t> v_S = {'[', '$', 'S', '#', 'i', 2, 'i', 1, 'a', 'i', 1, 'a'};
  1472. std::vector<uint8_t> v_C = {'[', '$', 'C', '#', 'i', 2, 'a', 'a'};
  1473. // check if vector is parsed correctly
  1474. CHECK(json::from_ubjson(v_N) == json::array());
  1475. CHECK(json::from_ubjson(v_T) == json({true, true}));
  1476. CHECK(json::from_ubjson(v_F) == json({false, false}));
  1477. CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));
  1478. CHECK(json::from_ubjson(v_i) == json({127, 127}));
  1479. CHECK(json::from_ubjson(v_U) == json({255, 255}));
  1480. CHECK(json::from_ubjson(v_I) == json({32767, 32767}));
  1481. CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));
  1482. CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));
  1483. CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));
  1484. CHECK(json::from_ubjson(v_S) == json({"a", "a"}));
  1485. CHECK(json::from_ubjson(v_C) == json({"a", "a"}));
  1486. // roundtrip: output should be optimized
  1487. std::vector<uint8_t> v_empty = {'[', '#', 'i', 0};
  1488. CHECK(json::to_ubjson(json::from_ubjson(v_N), true, true) == v_empty);
  1489. CHECK(json::to_ubjson(json::from_ubjson(v_T), true, true) == v_T);
  1490. CHECK(json::to_ubjson(json::from_ubjson(v_F), true, true) == v_F);
  1491. CHECK(json::to_ubjson(json::from_ubjson(v_Z), true, true) == v_Z);
  1492. CHECK(json::to_ubjson(json::from_ubjson(v_i), true, true) == v_i);
  1493. CHECK(json::to_ubjson(json::from_ubjson(v_U), true, true) == v_U);
  1494. CHECK(json::to_ubjson(json::from_ubjson(v_I), true, true) == v_I);
  1495. CHECK(json::to_ubjson(json::from_ubjson(v_l), true, true) == v_l);
  1496. CHECK(json::to_ubjson(json::from_ubjson(v_L), true, true) == v_L);
  1497. CHECK(json::to_ubjson(json::from_ubjson(v_D), true, true) == v_D);
  1498. CHECK(json::to_ubjson(json::from_ubjson(v_S), true, true) == v_S);
  1499. CHECK(json::to_ubjson(json::from_ubjson(v_C), true, true) == v_S); // char is serialized to string
  1500. }
  1501. }
  1502. }
  1503. SECTION("parse errors")
  1504. {
  1505. SECTION("empty byte vector")
  1506. {
  1507. json _;
  1508. CHECK_THROWS_AS(_ = json::from_ubjson(std::vector<uint8_t>()), json::parse_error&);
  1509. CHECK_THROWS_WITH(_ = json::from_ubjson(std::vector<uint8_t>()),
  1510. "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing UBJSON value: unexpected end of input");
  1511. }
  1512. SECTION("char")
  1513. {
  1514. SECTION("eof after C byte")
  1515. {
  1516. std::vector<uint8_t> v = {'C'};
  1517. json _;
  1518. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1519. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input");
  1520. }
  1521. SECTION("byte out of range")
  1522. {
  1523. std::vector<uint8_t> v = {'C', 130};
  1524. json _;
  1525. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1526. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82");
  1527. }
  1528. }
  1529. SECTION("strings")
  1530. {
  1531. SECTION("eof after S byte")
  1532. {
  1533. std::vector<uint8_t> v = {'S'};
  1534. json _;
  1535. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1536. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input");
  1537. }
  1538. SECTION("invalid byte")
  1539. {
  1540. std::vector<uint8_t> v = {'S', '1', 'a'};
  1541. json _;
  1542. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1543. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31");
  1544. }
  1545. }
  1546. SECTION("array")
  1547. {
  1548. SECTION("optimized array: no size following type")
  1549. {
  1550. std::vector<uint8_t> v = {'[', '$', 'i', 2};
  1551. json _;
  1552. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1553. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02");
  1554. }
  1555. }
  1556. SECTION("strings")
  1557. {
  1558. std::vector<uint8_t> vS = {'S'};
  1559. json _;
  1560. CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);
  1561. CHECK_THROWS_WITH(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input");
  1562. CHECK(json::from_ubjson(vS, true, false).is_discarded());
  1563. std::vector<uint8_t> v = {'S', 'i', '2', 'a'};
  1564. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1565. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON string: unexpected end of input");
  1566. CHECK(json::from_ubjson(v, true, false).is_discarded());
  1567. std::vector<uint8_t> vC = {'C'};
  1568. CHECK_THROWS_AS(_ = json::from_ubjson(vC), json::parse_error&);
  1569. CHECK_THROWS_WITH(_ = json::from_ubjson(vC), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input");
  1570. CHECK(json::from_ubjson(vC, true, false).is_discarded());
  1571. }
  1572. SECTION("sizes")
  1573. {
  1574. std::vector<uint8_t> vU = {'[', '#', 'U'};
  1575. json _;
  1576. CHECK_THROWS_AS(_ = json::from_ubjson(vU), json::parse_error&);
  1577. CHECK_THROWS_WITH(_ = json::from_ubjson(vU), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
  1578. CHECK(json::from_ubjson(vU, true, false).is_discarded());
  1579. std::vector<uint8_t> vi = {'[', '#', 'i'};
  1580. CHECK_THROWS_AS(_ = json::from_ubjson(vi), json::parse_error&);
  1581. CHECK_THROWS_WITH(_ = json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
  1582. CHECK(json::from_ubjson(vi, true, false).is_discarded());
  1583. std::vector<uint8_t> vI = {'[', '#', 'I'};
  1584. CHECK_THROWS_AS(_ = json::from_ubjson(vI), json::parse_error&);
  1585. CHECK_THROWS_WITH(_ = json::from_ubjson(vI), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
  1586. CHECK(json::from_ubjson(vI, true, false).is_discarded());
  1587. std::vector<uint8_t> vl = {'[', '#', 'l'};
  1588. CHECK_THROWS_AS(_ = json::from_ubjson(vl), json::parse_error&);
  1589. CHECK_THROWS_WITH(_ = json::from_ubjson(vl), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
  1590. CHECK(json::from_ubjson(vl, true, false).is_discarded());
  1591. std::vector<uint8_t> vL = {'[', '#', 'L'};
  1592. CHECK_THROWS_AS(_ = json::from_ubjson(vL), json::parse_error&);
  1593. CHECK_THROWS_WITH(_ = json::from_ubjson(vL), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
  1594. CHECK(json::from_ubjson(vL, true, false).is_discarded());
  1595. std::vector<uint8_t> v0 = {'[', '#', 'T', ']'};
  1596. CHECK_THROWS_AS(_ = json::from_ubjson(v0), json::parse_error&);
  1597. CHECK_THROWS_WITH(_ = json::from_ubjson(v0), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x54");
  1598. CHECK(json::from_ubjson(v0, true, false).is_discarded());
  1599. }
  1600. SECTION("types")
  1601. {
  1602. std::vector<uint8_t> v0 = {'[', '$'};
  1603. json _;
  1604. CHECK_THROWS_AS(_ = json::from_ubjson(v0), json::parse_error&);
  1605. CHECK_THROWS_WITH(_ = json::from_ubjson(v0), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing UBJSON type: unexpected end of input");
  1606. CHECK(json::from_ubjson(v0, true, false).is_discarded());
  1607. std::vector<uint8_t> vi = {'[', '$', '#'};
  1608. CHECK_THROWS_AS(_ = json::from_ubjson(vi), json::parse_error&);
  1609. CHECK_THROWS_WITH(_ = json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input");
  1610. CHECK(json::from_ubjson(vi, true, false).is_discarded());
  1611. std::vector<uint8_t> vT = {'[', '$', 'T'};
  1612. CHECK_THROWS_AS(_ = json::from_ubjson(vT), json::parse_error&);
  1613. CHECK_THROWS_WITH(_ = json::from_ubjson(vT), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input");
  1614. CHECK(json::from_ubjson(vT, true, false).is_discarded());
  1615. }
  1616. SECTION("arrays")
  1617. {
  1618. std::vector<uint8_t> vST = {'[', '$', 'i', '#', 'i', 2, 1};
  1619. json _;
  1620. CHECK_THROWS_AS(_ = json::from_ubjson(vST), json::parse_error&);
  1621. CHECK_THROWS_WITH(_ = json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input");
  1622. CHECK(json::from_ubjson(vST, true, false).is_discarded());
  1623. std::vector<uint8_t> vS = {'[', '#', 'i', 2, 'i', 1};
  1624. CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);
  1625. CHECK_THROWS_WITH(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input");
  1626. CHECK(json::from_ubjson(vS, true, false).is_discarded());
  1627. std::vector<uint8_t> v = {'[', 'i', 2, 'i', 1};
  1628. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1629. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing UBJSON value: unexpected end of input");
  1630. CHECK(json::from_ubjson(v, true, false).is_discarded());
  1631. }
  1632. SECTION("objects")
  1633. {
  1634. std::vector<uint8_t> vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1};
  1635. json _;
  1636. CHECK_THROWS_AS(_ = json::from_ubjson(vST), json::parse_error&);
  1637. CHECK_THROWS_WITH(_ = json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 11: syntax error while parsing UBJSON value: unexpected end of input");
  1638. CHECK(json::from_ubjson(vST, true, false).is_discarded());
  1639. std::vector<uint8_t> vT = {'{', '$', 'i', 'i', 1, 'a', 1};
  1640. CHECK_THROWS_AS(_ = json::from_ubjson(vT), json::parse_error&);
  1641. CHECK_THROWS_WITH(_ = json::from_ubjson(vT), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x69");
  1642. CHECK(json::from_ubjson(vT, true, false).is_discarded());
  1643. std::vector<uint8_t> vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1};
  1644. CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);
  1645. CHECK_THROWS_WITH(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON value: unexpected end of input");
  1646. CHECK(json::from_ubjson(vS, true, false).is_discarded());
  1647. std::vector<uint8_t> v = {'{', 'i', 1, 'a', 'i', 1};
  1648. CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);
  1649. CHECK_THROWS_WITH(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input");
  1650. CHECK(json::from_ubjson(v, true, false).is_discarded());
  1651. std::vector<uint8_t> v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'};
  1652. CHECK_THROWS_AS(_ = json::from_ubjson(v2), json::parse_error&);
  1653. CHECK_THROWS_WITH(_ = json::from_ubjson(v2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input");
  1654. CHECK(json::from_ubjson(v2, true, false).is_discarded());
  1655. std::vector<uint8_t> v3 = {'{', 'i', 1, 'a'};
  1656. CHECK_THROWS_AS(_ = json::from_ubjson(v3), json::parse_error&);
  1657. CHECK_THROWS_WITH(_ = json::from_ubjson(v3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON value: unexpected end of input");
  1658. CHECK(json::from_ubjson(v3, true, false).is_discarded());
  1659. std::vector<uint8_t> vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'};
  1660. CHECK_THROWS_AS(_ = json::from_ubjson(vST1), json::parse_error&);
  1661. CHECK_THROWS_WITH(_ = json::from_ubjson(vST1), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON number: unexpected end of input");
  1662. CHECK(json::from_ubjson(vST1, true, false).is_discarded());
  1663. std::vector<uint8_t> vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'};
  1664. CHECK_THROWS_AS(_ = json::from_ubjson(vST2), json::parse_error&);
  1665. CHECK_THROWS_WITH(_ = json::from_ubjson(vST2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON value: unexpected end of input");
  1666. CHECK(json::from_ubjson(vST2, true, false).is_discarded());
  1667. }
  1668. }
  1669. SECTION("writing optimized values")
  1670. {
  1671. SECTION("integer")
  1672. {
  1673. SECTION("array of i")
  1674. {
  1675. json j = {1, -1};
  1676. std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 0xff};
  1677. CHECK(json::to_ubjson(j, true, true) == expected);
  1678. }
  1679. SECTION("array of U")
  1680. {
  1681. json j = {200, 201};
  1682. std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};
  1683. CHECK(json::to_ubjson(j, true, true) == expected);
  1684. }
  1685. SECTION("array of I")
  1686. {
  1687. json j = {30000, -30000};
  1688. std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x8a, 0xd0};
  1689. CHECK(json::to_ubjson(j, true, true) == expected);
  1690. }
  1691. SECTION("array of l")
  1692. {
  1693. json j = {70000, -70000};
  1694. std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0xFF, 0xFE, 0xEE, 0x90};
  1695. CHECK(json::to_ubjson(j, true, true) == expected);
  1696. }
  1697. SECTION("array of L")
  1698. {
  1699. json j = {5000000000, -5000000000};
  1700. std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0xD5, 0xFA, 0x0E, 0x00};
  1701. CHECK(json::to_ubjson(j, true, true) == expected);
  1702. }
  1703. }
  1704. SECTION("unsigned integer")
  1705. {
  1706. SECTION("array of i")
  1707. {
  1708. json j = {1u, 2u};
  1709. std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 2};
  1710. std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'i', 1, 'i', 2};
  1711. CHECK(json::to_ubjson(j, true, true) == expected);
  1712. CHECK(json::to_ubjson(j, true) == expected_size);
  1713. }
  1714. SECTION("array of U")
  1715. {
  1716. json j = {200u, 201u};
  1717. std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};
  1718. std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'U', 0xC8, 'U', 0xC9};
  1719. CHECK(json::to_ubjson(j, true, true) == expected);
  1720. CHECK(json::to_ubjson(j, true) == expected_size);
  1721. }
  1722. SECTION("array of I")
  1723. {
  1724. json j = {30000u, 30001u};
  1725. std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x75, 0x31};
  1726. std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'I', 0x75, 0x30, 'I', 0x75, 0x31};
  1727. CHECK(json::to_ubjson(j, true, true) == expected);
  1728. CHECK(json::to_ubjson(j, true) == expected_size);
  1729. }
  1730. SECTION("array of l")
  1731. {
  1732. json j = {70000u, 70001u};
  1733. std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0x00, 0x01, 0x11, 0x71};
  1734. std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'l', 0x00, 0x01, 0x11, 0x70, 'l', 0x00, 0x01, 0x11, 0x71};
  1735. CHECK(json::to_ubjson(j, true, true) == expected);
  1736. CHECK(json::to_ubjson(j, true) == expected_size);
  1737. }
  1738. SECTION("array of L")
  1739. {
  1740. json j = {5000000000u, 5000000001u};
  1741. std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};
  1742. std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};
  1743. CHECK(json::to_ubjson(j, true, true) == expected);
  1744. CHECK(json::to_ubjson(j, true) == expected_size);
  1745. }
  1746. }
  1747. SECTION("discarded")
  1748. {
  1749. json j = {json::value_t::discarded, json::value_t::discarded};
  1750. std::vector<uint8_t> expected = {'[', '$', 'N', '#', 'i', 2};
  1751. CHECK(json::to_ubjson(j, true, true) == expected);
  1752. }
  1753. }
  1754. }
  1755. TEST_CASE("Universal Binary JSON Specification Examples 1")
  1756. {
  1757. SECTION("Null Value")
  1758. {
  1759. json j = {{"passcode", nullptr}};
  1760. std::vector<uint8_t> v = {'{', 'i', 8, 'p', 'a', 's', 's', 'c', 'o', 'd', 'e', 'Z', '}'};
  1761. CHECK(json::to_ubjson(j) == v);
  1762. CHECK(json::from_ubjson(v) == j);
  1763. }
  1764. SECTION("No-Op Value")
  1765. {
  1766. json j = {"foo", "bar", "baz"};
  1767. std::vector<uint8_t> v = {'[', 'S', 'i', 3, 'f', 'o', 'o',
  1768. 'S', 'i', 3, 'b', 'a', 'r',
  1769. 'S', 'i', 3, 'b', 'a', 'z', ']'
  1770. };
  1771. std::vector<uint8_t> v2 = {'[', 'S', 'i', 3, 'f', 'o', 'o', 'N',
  1772. 'S', 'i', 3, 'b', 'a', 'r', 'N', 'N', 'N',
  1773. 'S', 'i', 3, 'b', 'a', 'z', 'N', 'N', ']'
  1774. };
  1775. CHECK(json::to_ubjson(j) == v);
  1776. CHECK(json::from_ubjson(v) == j);
  1777. CHECK(json::from_ubjson(v2) == j);
  1778. }
  1779. SECTION("Boolean Types")
  1780. {
  1781. json j = {{"authorized", true}, {"verified", false}};
  1782. std::vector<uint8_t> v = {'{', 'i', 10, 'a', 'u', 't', 'h', 'o', 'r', 'i', 'z', 'e', 'd', 'T',
  1783. 'i', 8, 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'F', '}'
  1784. };
  1785. CHECK(json::to_ubjson(j) == v);
  1786. CHECK(json::from_ubjson(v) == j);
  1787. }
  1788. SECTION("Numeric Types")
  1789. {
  1790. json j =
  1791. {
  1792. {"int8", 16},
  1793. {"uint8", 255},
  1794. {"int16", 32767},
  1795. {"int32", 2147483647},
  1796. {"int64", 9223372036854775807},
  1797. {"float64", 113243.7863123}
  1798. };
  1799. std::vector<uint8_t> v = {'{',
  1800. 'i', 7, 'f', 'l', 'o', 'a', 't', '6', '4', 'D', 0x40, 0xfb, 0xa5, 0xbc, 0x94, 0xbc, 0x34, 0xcf,
  1801. 'i', 5, 'i', 'n', 't', '1', '6', 'I', 0x7f, 0xff,
  1802. 'i', 5, 'i', 'n', 't', '3', '2', 'l', 0x7f, 0xff, 0xff, 0xff,
  1803. 'i', 5, 'i', 'n', 't', '6', '4', 'L', 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  1804. 'i', 4, 'i', 'n', 't', '8', 'i', 16,
  1805. 'i', 5, 'u', 'i', 'n', 't', '8', 'U', 0xff,
  1806. '}'
  1807. };
  1808. CHECK(json::to_ubjson(j) == v);
  1809. CHECK(json::from_ubjson(v) == j);
  1810. }
  1811. SECTION("Char Type")
  1812. {
  1813. json j = {{"rolecode", "a"}, {"delim", ";"}};
  1814. std::vector<uint8_t> v = {'{', 'i', 5, 'd', 'e', 'l', 'i', 'm', 'C', ';', 'i', 8, 'r', 'o', 'l', 'e', 'c', 'o', 'd', 'e', 'C', 'a', '}'};
  1815. //CHECK(json::to_ubjson(j) == v);
  1816. CHECK(json::from_ubjson(v) == j);
  1817. }
  1818. SECTION("String Type")
  1819. {
  1820. SECTION("English")
  1821. {
  1822. json j = "hello";
  1823. std::vector<uint8_t> v = {'S', 'i', 5, 'h', 'e', 'l', 'l', 'o'};
  1824. CHECK(json::to_ubjson(j) == v);
  1825. CHECK(json::from_ubjson(v) == j);
  1826. }
  1827. SECTION("Russian")
  1828. {
  1829. json j = "привет";
  1830. std::vector<uint8_t> v = {'S', 'i', 12, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82};
  1831. CHECK(json::to_ubjson(j) == v);
  1832. CHECK(json::from_ubjson(v) == j);
  1833. }
  1834. SECTION("Russian")
  1835. {
  1836. json j = "مرحبا";
  1837. std::vector<uint8_t> v = {'S', 'i', 10, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7};
  1838. CHECK(json::to_ubjson(j) == v);
  1839. CHECK(json::from_ubjson(v) == j);
  1840. }
  1841. }
  1842. SECTION("Array Type")
  1843. {
  1844. SECTION("size=false type=false")
  1845. {
  1846. // note the float has been replaced by a double
  1847. json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
  1848. std::vector<uint8_t> v = {'[', 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm', ']'};
  1849. CHECK(json::to_ubjson(j) == v);
  1850. CHECK(json::from_ubjson(v) == j);
  1851. }
  1852. SECTION("size=true type=false")
  1853. {
  1854. // note the float has been replaced by a double
  1855. json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
  1856. std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};
  1857. CHECK(json::to_ubjson(j, true) == v);
  1858. CHECK(json::from_ubjson(v) == j);
  1859. }
  1860. SECTION("size=true type=true")
  1861. {
  1862. // note the float has been replaced by a double
  1863. json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
  1864. std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};
  1865. CHECK(json::to_ubjson(j, true, true) == v);
  1866. CHECK(json::from_ubjson(v) == j);
  1867. }
  1868. }
  1869. SECTION("Object Type")
  1870. {
  1871. SECTION("size=false type=false")
  1872. {
  1873. json j =
  1874. {
  1875. {
  1876. "post", {
  1877. {"id", 1137},
  1878. {"author", "rkalla"},
  1879. {"timestamp", 1364482090592},
  1880. {"body", "I totally agree!"}
  1881. }
  1882. }
  1883. };
  1884. std::vector<uint8_t> v = {'{', 'i', 4, 'p', 'o', 's', 't', '{',
  1885. 'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
  1886. 'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
  1887. 'i', 2, 'i', 'd', 'I', 0x04, 0x71,
  1888. 'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60,
  1889. '}', '}'
  1890. };
  1891. CHECK(json::to_ubjson(j) == v);
  1892. CHECK(json::from_ubjson(v) == j);
  1893. }
  1894. SECTION("size=true type=false")
  1895. {
  1896. json j =
  1897. {
  1898. {
  1899. "post", {
  1900. {"id", 1137},
  1901. {"author", "rkalla"},
  1902. {"timestamp", 1364482090592},
  1903. {"body", "I totally agree!"}
  1904. }
  1905. }
  1906. };
  1907. std::vector<uint8_t> v = {'{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '{', '#', 'i', 4,
  1908. 'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
  1909. 'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
  1910. 'i', 2, 'i', 'd', 'I', 0x04, 0x71,
  1911. 'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60
  1912. };
  1913. CHECK(json::to_ubjson(j, true) == v);
  1914. CHECK(json::from_ubjson(v) == j);
  1915. }
  1916. SECTION("size=true type=true")
  1917. {
  1918. json j =
  1919. {
  1920. {
  1921. "post", {
  1922. {"id", 1137},
  1923. {"author", "rkalla"},
  1924. {"timestamp", 1364482090592},
  1925. {"body", "I totally agree!"}
  1926. }
  1927. }
  1928. };
  1929. std::vector<uint8_t> v = {'{', '$', '{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '#', 'i', 4,
  1930. 'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
  1931. 'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
  1932. 'i', 2, 'i', 'd', 'I', 0x04, 0x71,
  1933. 'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60
  1934. };
  1935. CHECK(json::to_ubjson(j, true, true) == v);
  1936. CHECK(json::from_ubjson(v) == j);
  1937. }
  1938. }
  1939. SECTION("Optimized Format")
  1940. {
  1941. SECTION("Array Example")
  1942. {
  1943. SECTION("No Optimization")
  1944. {
  1945. // note the floats have been replaced by doubles
  1946. json j = {29.97, 31.13, 67.0, 2.113, 23.888};
  1947. std::vector<uint8_t> v = {'[',
  1948. 'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
  1949. 'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
  1950. 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  1951. 'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
  1952. 'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17,
  1953. ']'
  1954. };
  1955. CHECK(json::to_ubjson(j) == v);
  1956. CHECK(json::from_ubjson(v) == j);
  1957. }
  1958. SECTION("Optimized with count")
  1959. {
  1960. // note the floats have been replaced by doubles
  1961. json j = {29.97, 31.13, 67.0, 2.113, 23.888};
  1962. std::vector<uint8_t> v = {'[', '#', 'i', 5,
  1963. 'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
  1964. 'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
  1965. 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  1966. 'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
  1967. 'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17
  1968. };
  1969. CHECK(json::to_ubjson(j, true) == v);
  1970. CHECK(json::from_ubjson(v) == j);
  1971. }
  1972. SECTION("Optimized with type & count")
  1973. {
  1974. // note the floats have been replaced by doubles
  1975. json j = {29.97, 31.13, 67.0, 2.113, 23.888};
  1976. std::vector<uint8_t> v = {'[', '$', 'D', '#', 'i', 5,
  1977. 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
  1978. 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
  1979. 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  1980. 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
  1981. 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17
  1982. };
  1983. CHECK(json::to_ubjson(j, true, true) == v);
  1984. CHECK(json::from_ubjson(v) == j);
  1985. }
  1986. }
  1987. SECTION("Object Example")
  1988. {
  1989. SECTION("No Optimization")
  1990. {
  1991. // note the floats have been replaced by doubles
  1992. json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
  1993. std::vector<uint8_t> v = {'{',
  1994. 'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  1995. 'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
  1996. 'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8,
  1997. '}'
  1998. };
  1999. CHECK(json::to_ubjson(j) == v);
  2000. CHECK(json::from_ubjson(v) == j);
  2001. }
  2002. SECTION("Optimized with count")
  2003. {
  2004. // note the floats have been replaced by doubles
  2005. json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
  2006. std::vector<uint8_t> v = {'{', '#', 'i', 3,
  2007. 'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  2008. 'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
  2009. 'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8
  2010. };
  2011. CHECK(json::to_ubjson(j, true) == v);
  2012. CHECK(json::from_ubjson(v) == j);
  2013. }
  2014. SECTION("Optimized with type & count")
  2015. {
  2016. // note the floats have been replaced by doubles
  2017. json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
  2018. std::vector<uint8_t> v = {'{', '$', 'D', '#', 'i', 3,
  2019. 'i', 3, 'a', 'l', 't', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
  2020. 'i', 3, 'l', 'a', 't', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
  2021. 'i', 4, 'l', 'o', 'n', 'g', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8
  2022. };
  2023. CHECK(json::to_ubjson(j, true, true) == v);
  2024. CHECK(json::from_ubjson(v) == j);
  2025. }
  2026. }
  2027. SECTION("Special Cases (Null, No-Op and Boolean)")
  2028. {
  2029. SECTION("Array")
  2030. {
  2031. std::vector<uint8_t> v = {'[', '$', 'N', '#', 'I', 0x02, 0x00};
  2032. CHECK(json::from_ubjson(v) == json::array());
  2033. }
  2034. SECTION("Object")
  2035. {
  2036. std::vector<uint8_t> v = {'{', '$', 'Z', '#', 'i', 3, 'i', 4, 'n', 'a', 'm', 'e', 'i', 8, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 'i', 5, 'e', 'm', 'a', 'i', 'l'};
  2037. CHECK(json::from_ubjson(v) == json({ {"name", nullptr}, {"password", nullptr}, {"email", nullptr} }));
  2038. }
  2039. }
  2040. }
  2041. }
  2042. #if not defined(JSON_NOEXCEPTION)
  2043. TEST_CASE("all UBJSON first bytes")
  2044. {
  2045. // these bytes will fail immediately with exception parse_error.112
  2046. std::set<uint8_t> supported =
  2047. {
  2048. 'T', 'F', 'Z', 'U', 'i', 'I', 'l', 'L', 'd', 'D', 'C', 'S', '[', '{', 'N'
  2049. };
  2050. for (auto i = 0; i < 256; ++i)
  2051. {
  2052. const auto byte = static_cast<uint8_t>(i);
  2053. CAPTURE(byte)
  2054. try
  2055. {
  2056. auto res = json::from_ubjson(std::vector<uint8_t>(1, byte));
  2057. }
  2058. catch (const json::parse_error& e)
  2059. {
  2060. // check that parse_error.112 is only thrown if the
  2061. // first byte is not in the supported set
  2062. INFO_WITH_TEMP(e.what());
  2063. if (std::find(supported.begin(), supported.end(), byte) == supported.end())
  2064. {
  2065. CHECK(e.id == 112);
  2066. }
  2067. else
  2068. {
  2069. CHECK(e.id != 112);
  2070. }
  2071. }
  2072. }
  2073. }
  2074. #endif
  2075. TEST_CASE("UBJSON roundtrips" * doctest::skip())
  2076. {
  2077. SECTION("input from self-generated UBJSON files")
  2078. {
  2079. for (std::string filename :
  2080. {
  2081. TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
  2082. TEST_DATA_DIRECTORY "/json.org/1.json",
  2083. TEST_DATA_DIRECTORY "/json.org/2.json",
  2084. TEST_DATA_DIRECTORY "/json.org/3.json",
  2085. TEST_DATA_DIRECTORY "/json.org/4.json",
  2086. TEST_DATA_DIRECTORY "/json.org/5.json",
  2087. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
  2088. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
  2089. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
  2090. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
  2091. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
  2092. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
  2093. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
  2094. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
  2095. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
  2096. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
  2097. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
  2098. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
  2099. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
  2100. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
  2101. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
  2102. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
  2103. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
  2104. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
  2105. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
  2106. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
  2107. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
  2108. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
  2109. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
  2110. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
  2111. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
  2112. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
  2113. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
  2114. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
  2115. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
  2116. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
  2117. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
  2118. TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
  2119. TEST_DATA_DIRECTORY "/json_testsuite/sample.json",
  2120. TEST_DATA_DIRECTORY "/json_tests/pass1.json",
  2121. TEST_DATA_DIRECTORY "/json_tests/pass2.json",
  2122. TEST_DATA_DIRECTORY "/json_tests/pass3.json"
  2123. })
  2124. {
  2125. CAPTURE(filename)
  2126. {
  2127. INFO_WITH_TEMP(filename + ": std::vector<uint8_t>");
  2128. // parse JSON file
  2129. std::ifstream f_json(filename);
  2130. json j1 = json::parse(f_json);
  2131. // parse MessagePack file
  2132. std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
  2133. std::vector<uint8_t> packed(
  2134. (std::istreambuf_iterator<char>(f_ubjson)),
  2135. std::istreambuf_iterator<char>());
  2136. json j2;
  2137. CHECK_NOTHROW(j2 = json::from_ubjson(packed));
  2138. // compare parsed JSON values
  2139. CHECK(j1 == j2);
  2140. }
  2141. {
  2142. INFO_WITH_TEMP(filename + ": std::ifstream");
  2143. // parse JSON file
  2144. std::ifstream f_json(filename);
  2145. json j1 = json::parse(f_json);
  2146. // parse MessagePack file
  2147. std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
  2148. json j2;
  2149. CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson));
  2150. // compare parsed JSON values
  2151. CHECK(j1 == j2);
  2152. }
  2153. {
  2154. INFO_WITH_TEMP(filename + ": uint8_t* and size");
  2155. // parse JSON file
  2156. std::ifstream f_json(filename);
  2157. json j1 = json::parse(f_json);
  2158. // parse MessagePack file
  2159. std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
  2160. std::vector<uint8_t> packed(
  2161. (std::istreambuf_iterator<char>(f_ubjson)),
  2162. std::istreambuf_iterator<char>());
  2163. json j2;
  2164. CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
  2165. // compare parsed JSON values
  2166. CHECK(j1 == j2);
  2167. }
  2168. {
  2169. INFO_WITH_TEMP(filename + ": output to output adapters");
  2170. // parse JSON file
  2171. std::ifstream f_json(filename);
  2172. json j1 = json::parse(f_json);
  2173. // parse MessagePack file
  2174. std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
  2175. std::vector<uint8_t> packed(
  2176. (std::istreambuf_iterator<char>(f_ubjson)),
  2177. std::istreambuf_iterator<char>());
  2178. {
  2179. INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
  2180. std::vector<uint8_t> vec;
  2181. json::to_ubjson(j1, vec);
  2182. CHECK(vec == packed);
  2183. }
  2184. }
  2185. }
  2186. }
  2187. }