binary_writer.hpp 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++
  3. // | | |__ | | | | | | version 3.12.0
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #pragma once
  9. #include <algorithm> // reverse
  10. #include <array> // array
  11. #include <map> // map
  12. #include <cmath> // isnan, isinf
  13. #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
  14. #include <cstring> // memcpy
  15. #include <limits> // numeric_limits
  16. #include <string> // string
  17. #include <utility> // move
  18. #include <vector> // vector
  19. #include <nlohmann/detail/input/binary_reader.hpp>
  20. #include <nlohmann/detail/macro_scope.hpp>
  21. #include <nlohmann/detail/output/output_adapters.hpp>
  22. #include <nlohmann/detail/string_concat.hpp>
  23. NLOHMANN_JSON_NAMESPACE_BEGIN
  24. namespace detail
  25. {
  26. /// how to encode BJData
  27. enum class bjdata_version_t
  28. {
  29. draft2,
  30. draft3,
  31. };
  32. ///////////////////
  33. // binary writer //
  34. ///////////////////
  35. /*!
  36. @brief serialization to CBOR and MessagePack values
  37. */
  38. template<typename BasicJsonType, typename CharType>
  39. class binary_writer
  40. {
  41. using string_t = typename BasicJsonType::string_t;
  42. using binary_t = typename BasicJsonType::binary_t;
  43. using number_float_t = typename BasicJsonType::number_float_t;
  44. public:
  45. /*!
  46. @brief create a binary writer
  47. @param[in] adapter output adapter to write to
  48. */
  49. explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
  50. {
  51. JSON_ASSERT(oa);
  52. }
  53. /*!
  54. @param[in] j JSON value to serialize
  55. @pre j.type() == value_t::object
  56. */
  57. void write_bson(const BasicJsonType& j)
  58. {
  59. switch (j.type())
  60. {
  61. case value_t::object:
  62. {
  63. write_bson_object(*j.m_data.m_value.object);
  64. break;
  65. }
  66. case value_t::null:
  67. case value_t::array:
  68. case value_t::string:
  69. case value_t::boolean:
  70. case value_t::number_integer:
  71. case value_t::number_unsigned:
  72. case value_t::number_float:
  73. case value_t::binary:
  74. case value_t::discarded:
  75. default:
  76. {
  77. JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
  78. }
  79. }
  80. }
  81. /*!
  82. @param[in] j JSON value to serialize
  83. */
  84. void write_cbor(const BasicJsonType& j)
  85. {
  86. switch (j.type())
  87. {
  88. case value_t::null:
  89. {
  90. oa->write_character(to_char_type(0xF6));
  91. break;
  92. }
  93. case value_t::boolean:
  94. {
  95. oa->write_character(j.m_data.m_value.boolean
  96. ? to_char_type(0xF5)
  97. : to_char_type(0xF4));
  98. break;
  99. }
  100. case value_t::number_integer:
  101. {
  102. if (j.m_data.m_value.number_integer >= 0)
  103. {
  104. // CBOR does not differentiate between positive signed
  105. // integers and unsigned integers. Therefore, we used the
  106. // code from the value_t::number_unsigned case here.
  107. if (j.m_data.m_value.number_integer <= 0x17)
  108. {
  109. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  110. }
  111. else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
  112. {
  113. oa->write_character(to_char_type(0x18));
  114. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  115. }
  116. else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
  117. {
  118. oa->write_character(to_char_type(0x19));
  119. write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
  120. }
  121. else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
  122. {
  123. oa->write_character(to_char_type(0x1A));
  124. write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
  125. }
  126. else
  127. {
  128. oa->write_character(to_char_type(0x1B));
  129. write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
  130. }
  131. }
  132. else
  133. {
  134. // The conversions below encode the sign in the first
  135. // byte, and the value is converted to a positive number.
  136. const auto positive_number = -1 - j.m_data.m_value.number_integer;
  137. if (j.m_data.m_value.number_integer >= -24)
  138. {
  139. write_number(static_cast<std::uint8_t>(0x20 + positive_number));
  140. }
  141. else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
  142. {
  143. oa->write_character(to_char_type(0x38));
  144. write_number(static_cast<std::uint8_t>(positive_number));
  145. }
  146. else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
  147. {
  148. oa->write_character(to_char_type(0x39));
  149. write_number(static_cast<std::uint16_t>(positive_number));
  150. }
  151. else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
  152. {
  153. oa->write_character(to_char_type(0x3A));
  154. write_number(static_cast<std::uint32_t>(positive_number));
  155. }
  156. else
  157. {
  158. oa->write_character(to_char_type(0x3B));
  159. write_number(static_cast<std::uint64_t>(positive_number));
  160. }
  161. }
  162. break;
  163. }
  164. case value_t::number_unsigned:
  165. {
  166. if (j.m_data.m_value.number_unsigned <= 0x17)
  167. {
  168. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
  169. }
  170. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
  171. {
  172. oa->write_character(to_char_type(0x18));
  173. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
  174. }
  175. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
  176. {
  177. oa->write_character(to_char_type(0x19));
  178. write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
  179. }
  180. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
  181. {
  182. oa->write_character(to_char_type(0x1A));
  183. write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
  184. }
  185. else
  186. {
  187. oa->write_character(to_char_type(0x1B));
  188. write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
  189. }
  190. break;
  191. }
  192. case value_t::number_float:
  193. {
  194. if (std::isnan(j.m_data.m_value.number_float))
  195. {
  196. // NaN is 0xf97e00 in CBOR
  197. oa->write_character(to_char_type(0xF9));
  198. oa->write_character(to_char_type(0x7E));
  199. oa->write_character(to_char_type(0x00));
  200. }
  201. else if (std::isinf(j.m_data.m_value.number_float))
  202. {
  203. // Infinity is 0xf97c00, -Infinity is 0xf9fc00
  204. oa->write_character(to_char_type(0xf9));
  205. oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
  206. oa->write_character(to_char_type(0x00));
  207. }
  208. else
  209. {
  210. write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
  211. }
  212. break;
  213. }
  214. case value_t::string:
  215. {
  216. // step 1: write control byte and the string length
  217. const auto N = j.m_data.m_value.string->size();
  218. if (N <= 0x17)
  219. {
  220. write_number(static_cast<std::uint8_t>(0x60 + N));
  221. }
  222. else if (N <= (std::numeric_limits<std::uint8_t>::max)())
  223. {
  224. oa->write_character(to_char_type(0x78));
  225. write_number(static_cast<std::uint8_t>(N));
  226. }
  227. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  228. {
  229. oa->write_character(to_char_type(0x79));
  230. write_number(static_cast<std::uint16_t>(N));
  231. }
  232. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  233. {
  234. oa->write_character(to_char_type(0x7A));
  235. write_number(static_cast<std::uint32_t>(N));
  236. }
  237. // LCOV_EXCL_START
  238. else if (N <= (std::numeric_limits<std::uint64_t>::max)())
  239. {
  240. oa->write_character(to_char_type(0x7B));
  241. write_number(static_cast<std::uint64_t>(N));
  242. }
  243. // LCOV_EXCL_STOP
  244. // step 2: write the string
  245. oa->write_characters(
  246. reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
  247. j.m_data.m_value.string->size());
  248. break;
  249. }
  250. case value_t::array:
  251. {
  252. // step 1: write control byte and the array size
  253. const auto N = j.m_data.m_value.array->size();
  254. if (N <= 0x17)
  255. {
  256. write_number(static_cast<std::uint8_t>(0x80 + N));
  257. }
  258. else if (N <= (std::numeric_limits<std::uint8_t>::max)())
  259. {
  260. oa->write_character(to_char_type(0x98));
  261. write_number(static_cast<std::uint8_t>(N));
  262. }
  263. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  264. {
  265. oa->write_character(to_char_type(0x99));
  266. write_number(static_cast<std::uint16_t>(N));
  267. }
  268. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  269. {
  270. oa->write_character(to_char_type(0x9A));
  271. write_number(static_cast<std::uint32_t>(N));
  272. }
  273. // LCOV_EXCL_START
  274. else if (N <= (std::numeric_limits<std::uint64_t>::max)())
  275. {
  276. oa->write_character(to_char_type(0x9B));
  277. write_number(static_cast<std::uint64_t>(N));
  278. }
  279. // LCOV_EXCL_STOP
  280. // step 2: write each element
  281. for (const auto& el : *j.m_data.m_value.array)
  282. {
  283. write_cbor(el);
  284. }
  285. break;
  286. }
  287. case value_t::binary:
  288. {
  289. if (j.m_data.m_value.binary->has_subtype())
  290. {
  291. if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
  292. {
  293. write_number(static_cast<std::uint8_t>(0xd8));
  294. write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
  295. }
  296. else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
  297. {
  298. write_number(static_cast<std::uint8_t>(0xd9));
  299. write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
  300. }
  301. else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
  302. {
  303. write_number(static_cast<std::uint8_t>(0xda));
  304. write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
  305. }
  306. else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
  307. {
  308. write_number(static_cast<std::uint8_t>(0xdb));
  309. write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
  310. }
  311. }
  312. // step 1: write control byte and the binary array size
  313. const auto N = j.m_data.m_value.binary->size();
  314. if (N <= 0x17)
  315. {
  316. write_number(static_cast<std::uint8_t>(0x40 + N));
  317. }
  318. else if (N <= (std::numeric_limits<std::uint8_t>::max)())
  319. {
  320. oa->write_character(to_char_type(0x58));
  321. write_number(static_cast<std::uint8_t>(N));
  322. }
  323. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  324. {
  325. oa->write_character(to_char_type(0x59));
  326. write_number(static_cast<std::uint16_t>(N));
  327. }
  328. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  329. {
  330. oa->write_character(to_char_type(0x5A));
  331. write_number(static_cast<std::uint32_t>(N));
  332. }
  333. // LCOV_EXCL_START
  334. else if (N <= (std::numeric_limits<std::uint64_t>::max)())
  335. {
  336. oa->write_character(to_char_type(0x5B));
  337. write_number(static_cast<std::uint64_t>(N));
  338. }
  339. // LCOV_EXCL_STOP
  340. // step 2: write each element
  341. oa->write_characters(
  342. reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
  343. N);
  344. break;
  345. }
  346. case value_t::object:
  347. {
  348. // step 1: write control byte and the object size
  349. const auto N = j.m_data.m_value.object->size();
  350. if (N <= 0x17)
  351. {
  352. write_number(static_cast<std::uint8_t>(0xA0 + N));
  353. }
  354. else if (N <= (std::numeric_limits<std::uint8_t>::max)())
  355. {
  356. oa->write_character(to_char_type(0xB8));
  357. write_number(static_cast<std::uint8_t>(N));
  358. }
  359. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  360. {
  361. oa->write_character(to_char_type(0xB9));
  362. write_number(static_cast<std::uint16_t>(N));
  363. }
  364. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  365. {
  366. oa->write_character(to_char_type(0xBA));
  367. write_number(static_cast<std::uint32_t>(N));
  368. }
  369. // LCOV_EXCL_START
  370. else if (N <= (std::numeric_limits<std::uint64_t>::max)())
  371. {
  372. oa->write_character(to_char_type(0xBB));
  373. write_number(static_cast<std::uint64_t>(N));
  374. }
  375. // LCOV_EXCL_STOP
  376. // step 2: write each element
  377. for (const auto& el : *j.m_data.m_value.object)
  378. {
  379. write_cbor(el.first);
  380. write_cbor(el.second);
  381. }
  382. break;
  383. }
  384. case value_t::discarded:
  385. default:
  386. break;
  387. }
  388. }
  389. /*!
  390. @param[in] j JSON value to serialize
  391. */
  392. void write_msgpack(const BasicJsonType& j)
  393. {
  394. switch (j.type())
  395. {
  396. case value_t::null: // nil
  397. {
  398. oa->write_character(to_char_type(0xC0));
  399. break;
  400. }
  401. case value_t::boolean: // true and false
  402. {
  403. oa->write_character(j.m_data.m_value.boolean
  404. ? to_char_type(0xC3)
  405. : to_char_type(0xC2));
  406. break;
  407. }
  408. case value_t::number_integer:
  409. {
  410. if (j.m_data.m_value.number_integer >= 0)
  411. {
  412. // MessagePack does not differentiate between positive
  413. // signed integers and unsigned integers. Therefore, we used
  414. // the code from the value_t::number_unsigned case here.
  415. if (j.m_data.m_value.number_unsigned < 128)
  416. {
  417. // positive fixnum
  418. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  419. }
  420. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
  421. {
  422. // uint 8
  423. oa->write_character(to_char_type(0xCC));
  424. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  425. }
  426. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
  427. {
  428. // uint 16
  429. oa->write_character(to_char_type(0xCD));
  430. write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
  431. }
  432. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
  433. {
  434. // uint 32
  435. oa->write_character(to_char_type(0xCE));
  436. write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
  437. }
  438. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
  439. {
  440. // uint 64
  441. oa->write_character(to_char_type(0xCF));
  442. write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
  443. }
  444. }
  445. else
  446. {
  447. if (j.m_data.m_value.number_integer >= -32)
  448. {
  449. // negative fixnum
  450. write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
  451. }
  452. else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
  453. j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
  454. {
  455. // int 8
  456. oa->write_character(to_char_type(0xD0));
  457. write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
  458. }
  459. else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
  460. j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
  461. {
  462. // int 16
  463. oa->write_character(to_char_type(0xD1));
  464. write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
  465. }
  466. else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
  467. j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
  468. {
  469. // int 32
  470. oa->write_character(to_char_type(0xD2));
  471. write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
  472. }
  473. else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
  474. j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
  475. {
  476. // int 64
  477. oa->write_character(to_char_type(0xD3));
  478. write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
  479. }
  480. }
  481. break;
  482. }
  483. case value_t::number_unsigned:
  484. {
  485. if (j.m_data.m_value.number_unsigned < 128)
  486. {
  487. // positive fixnum
  488. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  489. }
  490. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
  491. {
  492. // uint 8
  493. oa->write_character(to_char_type(0xCC));
  494. write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
  495. }
  496. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
  497. {
  498. // uint 16
  499. oa->write_character(to_char_type(0xCD));
  500. write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
  501. }
  502. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
  503. {
  504. // uint 32
  505. oa->write_character(to_char_type(0xCE));
  506. write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
  507. }
  508. else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
  509. {
  510. // uint 64
  511. oa->write_character(to_char_type(0xCF));
  512. write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
  513. }
  514. break;
  515. }
  516. case value_t::number_float:
  517. {
  518. write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
  519. break;
  520. }
  521. case value_t::string:
  522. {
  523. // step 1: write control byte and the string length
  524. const auto N = j.m_data.m_value.string->size();
  525. if (N <= 31)
  526. {
  527. // fixstr
  528. write_number(static_cast<std::uint8_t>(0xA0 | N));
  529. }
  530. else if (N <= (std::numeric_limits<std::uint8_t>::max)())
  531. {
  532. // str 8
  533. oa->write_character(to_char_type(0xD9));
  534. write_number(static_cast<std::uint8_t>(N));
  535. }
  536. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  537. {
  538. // str 16
  539. oa->write_character(to_char_type(0xDA));
  540. write_number(static_cast<std::uint16_t>(N));
  541. }
  542. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  543. {
  544. // str 32
  545. oa->write_character(to_char_type(0xDB));
  546. write_number(static_cast<std::uint32_t>(N));
  547. }
  548. // step 2: write the string
  549. oa->write_characters(
  550. reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
  551. j.m_data.m_value.string->size());
  552. break;
  553. }
  554. case value_t::array:
  555. {
  556. // step 1: write control byte and the array size
  557. const auto N = j.m_data.m_value.array->size();
  558. if (N <= 15)
  559. {
  560. // fixarray
  561. write_number(static_cast<std::uint8_t>(0x90 | N));
  562. }
  563. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  564. {
  565. // array 16
  566. oa->write_character(to_char_type(0xDC));
  567. write_number(static_cast<std::uint16_t>(N));
  568. }
  569. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  570. {
  571. // array 32
  572. oa->write_character(to_char_type(0xDD));
  573. write_number(static_cast<std::uint32_t>(N));
  574. }
  575. // step 2: write each element
  576. for (const auto& el : *j.m_data.m_value.array)
  577. {
  578. write_msgpack(el);
  579. }
  580. break;
  581. }
  582. case value_t::binary:
  583. {
  584. // step 0: determine if the binary type has a set subtype to
  585. // determine whether to use the ext or fixext types
  586. const bool use_ext = j.m_data.m_value.binary->has_subtype();
  587. // step 1: write control byte and the byte string length
  588. const auto N = j.m_data.m_value.binary->size();
  589. if (N <= (std::numeric_limits<std::uint8_t>::max)())
  590. {
  591. std::uint8_t output_type{};
  592. bool fixed = true;
  593. if (use_ext)
  594. {
  595. switch (N)
  596. {
  597. case 1:
  598. output_type = 0xD4; // fixext 1
  599. break;
  600. case 2:
  601. output_type = 0xD5; // fixext 2
  602. break;
  603. case 4:
  604. output_type = 0xD6; // fixext 4
  605. break;
  606. case 8:
  607. output_type = 0xD7; // fixext 8
  608. break;
  609. case 16:
  610. output_type = 0xD8; // fixext 16
  611. break;
  612. default:
  613. output_type = 0xC7; // ext 8
  614. fixed = false;
  615. break;
  616. }
  617. }
  618. else
  619. {
  620. output_type = 0xC4; // bin 8
  621. fixed = false;
  622. }
  623. oa->write_character(to_char_type(output_type));
  624. if (!fixed)
  625. {
  626. write_number(static_cast<std::uint8_t>(N));
  627. }
  628. }
  629. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  630. {
  631. const std::uint8_t output_type = use_ext
  632. ? 0xC8 // ext 16
  633. : 0xC5; // bin 16
  634. oa->write_character(to_char_type(output_type));
  635. write_number(static_cast<std::uint16_t>(N));
  636. }
  637. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  638. {
  639. const std::uint8_t output_type = use_ext
  640. ? 0xC9 // ext 32
  641. : 0xC6; // bin 32
  642. oa->write_character(to_char_type(output_type));
  643. write_number(static_cast<std::uint32_t>(N));
  644. }
  645. // step 1.5: if this is an ext type, write the subtype
  646. if (use_ext)
  647. {
  648. write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
  649. }
  650. // step 2: write the byte string
  651. oa->write_characters(
  652. reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
  653. N);
  654. break;
  655. }
  656. case value_t::object:
  657. {
  658. // step 1: write control byte and the object size
  659. const auto N = j.m_data.m_value.object->size();
  660. if (N <= 15)
  661. {
  662. // fixmap
  663. write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
  664. }
  665. else if (N <= (std::numeric_limits<std::uint16_t>::max)())
  666. {
  667. // map 16
  668. oa->write_character(to_char_type(0xDE));
  669. write_number(static_cast<std::uint16_t>(N));
  670. }
  671. else if (N <= (std::numeric_limits<std::uint32_t>::max)())
  672. {
  673. // map 32
  674. oa->write_character(to_char_type(0xDF));
  675. write_number(static_cast<std::uint32_t>(N));
  676. }
  677. // step 2: write each element
  678. for (const auto& el : *j.m_data.m_value.object)
  679. {
  680. write_msgpack(el.first);
  681. write_msgpack(el.second);
  682. }
  683. break;
  684. }
  685. case value_t::discarded:
  686. default:
  687. break;
  688. }
  689. }
  690. /*!
  691. @param[in] j JSON value to serialize
  692. @param[in] use_count whether to use '#' prefixes (optimized format)
  693. @param[in] use_type whether to use '$' prefixes (optimized format)
  694. @param[in] add_prefix whether prefixes need to be used for this value
  695. @param[in] use_bjdata whether write in BJData format, default is false
  696. @param[in] bjdata_version which BJData version to use, default is draft2
  697. */
  698. void write_ubjson(const BasicJsonType& j, const bool use_count,
  699. const bool use_type, const bool add_prefix = true,
  700. const bool use_bjdata = false, const bjdata_version_t bjdata_version = bjdata_version_t::draft2)
  701. {
  702. const bool bjdata_draft3 = use_bjdata && bjdata_version == bjdata_version_t::draft3;
  703. switch (j.type())
  704. {
  705. case value_t::null:
  706. {
  707. if (add_prefix)
  708. {
  709. oa->write_character(to_char_type('Z'));
  710. }
  711. break;
  712. }
  713. case value_t::boolean:
  714. {
  715. if (add_prefix)
  716. {
  717. oa->write_character(j.m_data.m_value.boolean
  718. ? to_char_type('T')
  719. : to_char_type('F'));
  720. }
  721. break;
  722. }
  723. case value_t::number_integer:
  724. {
  725. write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
  726. break;
  727. }
  728. case value_t::number_unsigned:
  729. {
  730. write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
  731. break;
  732. }
  733. case value_t::number_float:
  734. {
  735. write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
  736. break;
  737. }
  738. case value_t::string:
  739. {
  740. if (add_prefix)
  741. {
  742. oa->write_character(to_char_type('S'));
  743. }
  744. write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
  745. oa->write_characters(
  746. reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
  747. j.m_data.m_value.string->size());
  748. break;
  749. }
  750. case value_t::array:
  751. {
  752. if (add_prefix)
  753. {
  754. oa->write_character(to_char_type('['));
  755. }
  756. bool prefix_required = true;
  757. if (use_type && !j.m_data.m_value.array->empty())
  758. {
  759. JSON_ASSERT(use_count);
  760. const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
  761. const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
  762. [this, first_prefix, use_bjdata](const BasicJsonType & v)
  763. {
  764. return ubjson_prefix(v, use_bjdata) == first_prefix;
  765. });
  766. std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
  767. if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
  768. {
  769. prefix_required = false;
  770. oa->write_character(to_char_type('$'));
  771. oa->write_character(first_prefix);
  772. }
  773. }
  774. if (use_count)
  775. {
  776. oa->write_character(to_char_type('#'));
  777. write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
  778. }
  779. for (const auto& el : *j.m_data.m_value.array)
  780. {
  781. write_ubjson(el, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
  782. }
  783. if (!use_count)
  784. {
  785. oa->write_character(to_char_type(']'));
  786. }
  787. break;
  788. }
  789. case value_t::binary:
  790. {
  791. if (add_prefix)
  792. {
  793. oa->write_character(to_char_type('['));
  794. }
  795. if (use_type && (bjdata_draft3 || !j.m_data.m_value.binary->empty()))
  796. {
  797. JSON_ASSERT(use_count);
  798. oa->write_character(to_char_type('$'));
  799. oa->write_character(bjdata_draft3 ? 'B' : 'U');
  800. }
  801. if (use_count)
  802. {
  803. oa->write_character(to_char_type('#'));
  804. write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
  805. }
  806. if (use_type)
  807. {
  808. oa->write_characters(
  809. reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
  810. j.m_data.m_value.binary->size());
  811. }
  812. else
  813. {
  814. for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
  815. {
  816. oa->write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
  817. oa->write_character(j.m_data.m_value.binary->data()[i]);
  818. }
  819. }
  820. if (!use_count)
  821. {
  822. oa->write_character(to_char_type(']'));
  823. }
  824. break;
  825. }
  826. case value_t::object:
  827. {
  828. if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
  829. {
  830. if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type, bjdata_version)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
  831. {
  832. break;
  833. }
  834. }
  835. if (add_prefix)
  836. {
  837. oa->write_character(to_char_type('{'));
  838. }
  839. bool prefix_required = true;
  840. if (use_type && !j.m_data.m_value.object->empty())
  841. {
  842. JSON_ASSERT(use_count);
  843. const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
  844. const bool same_prefix = std::all_of(j.begin(), j.end(),
  845. [this, first_prefix, use_bjdata](const BasicJsonType & v)
  846. {
  847. return ubjson_prefix(v, use_bjdata) == first_prefix;
  848. });
  849. std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
  850. if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
  851. {
  852. prefix_required = false;
  853. oa->write_character(to_char_type('$'));
  854. oa->write_character(first_prefix);
  855. }
  856. }
  857. if (use_count)
  858. {
  859. oa->write_character(to_char_type('#'));
  860. write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
  861. }
  862. for (const auto& el : *j.m_data.m_value.object)
  863. {
  864. write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
  865. oa->write_characters(
  866. reinterpret_cast<const CharType*>(el.first.c_str()),
  867. el.first.size());
  868. write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
  869. }
  870. if (!use_count)
  871. {
  872. oa->write_character(to_char_type('}'));
  873. }
  874. break;
  875. }
  876. case value_t::discarded:
  877. default:
  878. break;
  879. }
  880. }
  881. private:
  882. //////////
  883. // BSON //
  884. //////////
  885. /*!
  886. @return The size of a BSON document entry header, including the id marker
  887. and the entry name size (and its null-terminator).
  888. */
  889. static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
  890. {
  891. const auto it = name.find(static_cast<typename string_t::value_type>(0));
  892. if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
  893. {
  894. JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
  895. static_cast<void>(j);
  896. }
  897. return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
  898. }
  899. /*!
  900. @brief Writes the given @a element_type and @a name to the output adapter
  901. */
  902. void write_bson_entry_header(const string_t& name,
  903. const std::uint8_t element_type)
  904. {
  905. oa->write_character(to_char_type(element_type)); // boolean
  906. oa->write_characters(
  907. reinterpret_cast<const CharType*>(name.c_str()),
  908. name.size() + 1u);
  909. }
  910. /*!
  911. @brief Writes a BSON element with key @a name and boolean value @a value
  912. */
  913. void write_bson_boolean(const string_t& name,
  914. const bool value)
  915. {
  916. write_bson_entry_header(name, 0x08);
  917. oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
  918. }
  919. /*!
  920. @brief Writes a BSON element with key @a name and double value @a value
  921. */
  922. void write_bson_double(const string_t& name,
  923. const double value)
  924. {
  925. write_bson_entry_header(name, 0x01);
  926. write_number<double>(value, true);
  927. }
  928. /*!
  929. @return The size of the BSON-encoded string in @a value
  930. */
  931. static std::size_t calc_bson_string_size(const string_t& value)
  932. {
  933. return sizeof(std::int32_t) + value.size() + 1ul;
  934. }
  935. /*!
  936. @brief Writes a BSON element with key @a name and string value @a value
  937. */
  938. void write_bson_string(const string_t& name,
  939. const string_t& value)
  940. {
  941. write_bson_entry_header(name, 0x02);
  942. write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
  943. oa->write_characters(
  944. reinterpret_cast<const CharType*>(value.c_str()),
  945. value.size() + 1);
  946. }
  947. /*!
  948. @brief Writes a BSON element with key @a name and null value
  949. */
  950. void write_bson_null(const string_t& name)
  951. {
  952. write_bson_entry_header(name, 0x0A);
  953. }
  954. /*!
  955. @return The size of the BSON-encoded integer @a value
  956. */
  957. static std::size_t calc_bson_integer_size(const std::int64_t value)
  958. {
  959. return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
  960. ? sizeof(std::int32_t)
  961. : sizeof(std::int64_t);
  962. }
  963. /*!
  964. @brief Writes a BSON element with key @a name and integer @a value
  965. */
  966. void write_bson_integer(const string_t& name,
  967. const std::int64_t value)
  968. {
  969. if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
  970. {
  971. write_bson_entry_header(name, 0x10); // int32
  972. write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
  973. }
  974. else
  975. {
  976. write_bson_entry_header(name, 0x12); // int64
  977. write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
  978. }
  979. }
  980. /*!
  981. @return The size of the BSON-encoded unsigned integer in @a j
  982. */
  983. static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
  984. {
  985. return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  986. ? sizeof(std::int32_t)
  987. : sizeof(std::int64_t);
  988. }
  989. /*!
  990. @brief Writes a BSON element with key @a name and unsigned @a value
  991. */
  992. void write_bson_unsigned(const string_t& name,
  993. const BasicJsonType& j)
  994. {
  995. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  996. {
  997. write_bson_entry_header(name, 0x10 /* int32 */);
  998. write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
  999. }
  1000. else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
  1001. {
  1002. write_bson_entry_header(name, 0x12 /* int64 */);
  1003. write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
  1004. }
  1005. else
  1006. {
  1007. write_bson_entry_header(name, 0x11 /* uint64 */);
  1008. write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
  1009. }
  1010. }
  1011. /*!
  1012. @brief Writes a BSON element with key @a name and object @a value
  1013. */
  1014. void write_bson_object_entry(const string_t& name,
  1015. const typename BasicJsonType::object_t& value)
  1016. {
  1017. write_bson_entry_header(name, 0x03); // object
  1018. write_bson_object(value);
  1019. }
  1020. /*!
  1021. @return The size of the BSON-encoded array @a value
  1022. */
  1023. static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
  1024. {
  1025. std::size_t array_index = 0ul;
  1026. const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
  1027. {
  1028. return result + calc_bson_element_size(std::to_string(array_index++), el);
  1029. });
  1030. return sizeof(std::int32_t) + embedded_document_size + 1ul;
  1031. }
  1032. /*!
  1033. @return The size of the BSON-encoded binary array @a value
  1034. */
  1035. static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
  1036. {
  1037. return sizeof(std::int32_t) + value.size() + 1ul;
  1038. }
  1039. /*!
  1040. @brief Writes a BSON element with key @a name and array @a value
  1041. */
  1042. void write_bson_array(const string_t& name,
  1043. const typename BasicJsonType::array_t& value)
  1044. {
  1045. write_bson_entry_header(name, 0x04); // array
  1046. write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
  1047. std::size_t array_index = 0ul;
  1048. for (const auto& el : value)
  1049. {
  1050. write_bson_element(std::to_string(array_index++), el);
  1051. }
  1052. oa->write_character(to_char_type(0x00));
  1053. }
  1054. /*!
  1055. @brief Writes a BSON element with key @a name and binary value @a value
  1056. */
  1057. void write_bson_binary(const string_t& name,
  1058. const binary_t& value)
  1059. {
  1060. write_bson_entry_header(name, 0x05);
  1061. write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
  1062. write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
  1063. oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
  1064. }
  1065. /*!
  1066. @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
  1067. @return The calculated size for the BSON document entry for @a j with the given @a name.
  1068. */
  1069. static std::size_t calc_bson_element_size(const string_t& name,
  1070. const BasicJsonType& j)
  1071. {
  1072. const auto header_size = calc_bson_entry_header_size(name, j);
  1073. switch (j.type())
  1074. {
  1075. case value_t::object:
  1076. return header_size + calc_bson_object_size(*j.m_data.m_value.object);
  1077. case value_t::array:
  1078. return header_size + calc_bson_array_size(*j.m_data.m_value.array);
  1079. case value_t::binary:
  1080. return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
  1081. case value_t::boolean:
  1082. return header_size + 1ul;
  1083. case value_t::number_float:
  1084. return header_size + 8ul;
  1085. case value_t::number_integer:
  1086. return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
  1087. case value_t::number_unsigned:
  1088. return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
  1089. case value_t::string:
  1090. return header_size + calc_bson_string_size(*j.m_data.m_value.string);
  1091. case value_t::null:
  1092. return header_size + 0ul;
  1093. // LCOV_EXCL_START
  1094. case value_t::discarded:
  1095. default:
  1096. JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
  1097. return 0ul;
  1098. // LCOV_EXCL_STOP
  1099. }
  1100. }
  1101. /*!
  1102. @brief Serializes the JSON value @a j to BSON and associates it with the
  1103. key @a name.
  1104. @param name The name to associate with the JSON entity @a j within the
  1105. current BSON document
  1106. */
  1107. void write_bson_element(const string_t& name,
  1108. const BasicJsonType& j)
  1109. {
  1110. switch (j.type())
  1111. {
  1112. case value_t::object:
  1113. return write_bson_object_entry(name, *j.m_data.m_value.object);
  1114. case value_t::array:
  1115. return write_bson_array(name, *j.m_data.m_value.array);
  1116. case value_t::binary:
  1117. return write_bson_binary(name, *j.m_data.m_value.binary);
  1118. case value_t::boolean:
  1119. return write_bson_boolean(name, j.m_data.m_value.boolean);
  1120. case value_t::number_float:
  1121. return write_bson_double(name, j.m_data.m_value.number_float);
  1122. case value_t::number_integer:
  1123. return write_bson_integer(name, j.m_data.m_value.number_integer);
  1124. case value_t::number_unsigned:
  1125. return write_bson_unsigned(name, j);
  1126. case value_t::string:
  1127. return write_bson_string(name, *j.m_data.m_value.string);
  1128. case value_t::null:
  1129. return write_bson_null(name);
  1130. // LCOV_EXCL_START
  1131. case value_t::discarded:
  1132. default:
  1133. JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
  1134. return;
  1135. // LCOV_EXCL_STOP
  1136. }
  1137. }
  1138. /*!
  1139. @brief Calculates the size of the BSON serialization of the given
  1140. JSON-object @a j.
  1141. @param[in] value JSON value to serialize
  1142. @pre value.type() == value_t::object
  1143. */
  1144. static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
  1145. {
  1146. const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
  1147. [](size_t result, const typename BasicJsonType::object_t::value_type & el)
  1148. {
  1149. return result += calc_bson_element_size(el.first, el.second);
  1150. });
  1151. return sizeof(std::int32_t) + document_size + 1ul;
  1152. }
  1153. /*!
  1154. @param[in] value JSON value to serialize
  1155. @pre value.type() == value_t::object
  1156. */
  1157. void write_bson_object(const typename BasicJsonType::object_t& value)
  1158. {
  1159. write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
  1160. for (const auto& el : value)
  1161. {
  1162. write_bson_element(el.first, el.second);
  1163. }
  1164. oa->write_character(to_char_type(0x00));
  1165. }
  1166. //////////
  1167. // CBOR //
  1168. //////////
  1169. static constexpr CharType get_cbor_float_prefix(float /*unused*/)
  1170. {
  1171. return to_char_type(0xFA); // Single-Precision Float
  1172. }
  1173. static constexpr CharType get_cbor_float_prefix(double /*unused*/)
  1174. {
  1175. return to_char_type(0xFB); // Double-Precision Float
  1176. }
  1177. /////////////
  1178. // MsgPack //
  1179. /////////////
  1180. static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
  1181. {
  1182. return to_char_type(0xCA); // float 32
  1183. }
  1184. static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
  1185. {
  1186. return to_char_type(0xCB); // float 64
  1187. }
  1188. ////////////
  1189. // UBJSON //
  1190. ////////////
  1191. // UBJSON: write number (floating point)
  1192. template<typename NumberType, typename std::enable_if<
  1193. std::is_floating_point<NumberType>::value, int>::type = 0>
  1194. void write_number_with_ubjson_prefix(const NumberType n,
  1195. const bool add_prefix,
  1196. const bool use_bjdata)
  1197. {
  1198. if (add_prefix)
  1199. {
  1200. oa->write_character(get_ubjson_float_prefix(n));
  1201. }
  1202. write_number(n, use_bjdata);
  1203. }
  1204. // UBJSON: write number (unsigned integer)
  1205. template<typename NumberType, typename std::enable_if<
  1206. std::is_unsigned<NumberType>::value, int>::type = 0>
  1207. void write_number_with_ubjson_prefix(const NumberType n,
  1208. const bool add_prefix,
  1209. const bool use_bjdata)
  1210. {
  1211. if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
  1212. {
  1213. if (add_prefix)
  1214. {
  1215. oa->write_character(to_char_type('i')); // int8
  1216. }
  1217. write_number(static_cast<std::uint8_t>(n), use_bjdata);
  1218. }
  1219. else if (n <= (std::numeric_limits<std::uint8_t>::max)())
  1220. {
  1221. if (add_prefix)
  1222. {
  1223. oa->write_character(to_char_type('U')); // uint8
  1224. }
  1225. write_number(static_cast<std::uint8_t>(n), use_bjdata);
  1226. }
  1227. else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
  1228. {
  1229. if (add_prefix)
  1230. {
  1231. oa->write_character(to_char_type('I')); // int16
  1232. }
  1233. write_number(static_cast<std::int16_t>(n), use_bjdata);
  1234. }
  1235. else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
  1236. {
  1237. if (add_prefix)
  1238. {
  1239. oa->write_character(to_char_type('u')); // uint16 - bjdata only
  1240. }
  1241. write_number(static_cast<std::uint16_t>(n), use_bjdata);
  1242. }
  1243. else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  1244. {
  1245. if (add_prefix)
  1246. {
  1247. oa->write_character(to_char_type('l')); // int32
  1248. }
  1249. write_number(static_cast<std::int32_t>(n), use_bjdata);
  1250. }
  1251. else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
  1252. {
  1253. if (add_prefix)
  1254. {
  1255. oa->write_character(to_char_type('m')); // uint32 - bjdata only
  1256. }
  1257. write_number(static_cast<std::uint32_t>(n), use_bjdata);
  1258. }
  1259. else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
  1260. {
  1261. if (add_prefix)
  1262. {
  1263. oa->write_character(to_char_type('L')); // int64
  1264. }
  1265. write_number(static_cast<std::int64_t>(n), use_bjdata);
  1266. }
  1267. else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
  1268. {
  1269. if (add_prefix)
  1270. {
  1271. oa->write_character(to_char_type('M')); // uint64 - bjdata only
  1272. }
  1273. write_number(static_cast<std::uint64_t>(n), use_bjdata);
  1274. }
  1275. else
  1276. {
  1277. if (add_prefix)
  1278. {
  1279. oa->write_character(to_char_type('H')); // high-precision number
  1280. }
  1281. const auto number = BasicJsonType(n).dump();
  1282. write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
  1283. for (std::size_t i = 0; i < number.size(); ++i)
  1284. {
  1285. oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
  1286. }
  1287. }
  1288. }
  1289. // UBJSON: write number (signed integer)
  1290. template < typename NumberType, typename std::enable_if <
  1291. std::is_signed<NumberType>::value&&
  1292. !std::is_floating_point<NumberType>::value, int >::type = 0 >
  1293. void write_number_with_ubjson_prefix(const NumberType n,
  1294. const bool add_prefix,
  1295. const bool use_bjdata)
  1296. {
  1297. if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
  1298. {
  1299. if (add_prefix)
  1300. {
  1301. oa->write_character(to_char_type('i')); // int8
  1302. }
  1303. write_number(static_cast<std::int8_t>(n), use_bjdata);
  1304. }
  1305. else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
  1306. {
  1307. if (add_prefix)
  1308. {
  1309. oa->write_character(to_char_type('U')); // uint8
  1310. }
  1311. write_number(static_cast<std::uint8_t>(n), use_bjdata);
  1312. }
  1313. else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
  1314. {
  1315. if (add_prefix)
  1316. {
  1317. oa->write_character(to_char_type('I')); // int16
  1318. }
  1319. write_number(static_cast<std::int16_t>(n), use_bjdata);
  1320. }
  1321. else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
  1322. {
  1323. if (add_prefix)
  1324. {
  1325. oa->write_character(to_char_type('u')); // uint16 - bjdata only
  1326. }
  1327. write_number(static_cast<uint16_t>(n), use_bjdata);
  1328. }
  1329. else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
  1330. {
  1331. if (add_prefix)
  1332. {
  1333. oa->write_character(to_char_type('l')); // int32
  1334. }
  1335. write_number(static_cast<std::int32_t>(n), use_bjdata);
  1336. }
  1337. else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
  1338. {
  1339. if (add_prefix)
  1340. {
  1341. oa->write_character(to_char_type('m')); // uint32 - bjdata only
  1342. }
  1343. write_number(static_cast<uint32_t>(n), use_bjdata);
  1344. }
  1345. else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
  1346. {
  1347. if (add_prefix)
  1348. {
  1349. oa->write_character(to_char_type('L')); // int64
  1350. }
  1351. write_number(static_cast<std::int64_t>(n), use_bjdata);
  1352. }
  1353. // LCOV_EXCL_START
  1354. else
  1355. {
  1356. if (add_prefix)
  1357. {
  1358. oa->write_character(to_char_type('H')); // high-precision number
  1359. }
  1360. const auto number = BasicJsonType(n).dump();
  1361. write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
  1362. for (std::size_t i = 0; i < number.size(); ++i)
  1363. {
  1364. oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
  1365. }
  1366. }
  1367. // LCOV_EXCL_STOP
  1368. }
  1369. /*!
  1370. @brief determine the type prefix of container values
  1371. */
  1372. CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
  1373. {
  1374. switch (j.type())
  1375. {
  1376. case value_t::null:
  1377. return 'Z';
  1378. case value_t::boolean:
  1379. return j.m_data.m_value.boolean ? 'T' : 'F';
  1380. case value_t::number_integer:
  1381. {
  1382. if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
  1383. {
  1384. return 'i';
  1385. }
  1386. if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
  1387. {
  1388. return 'U';
  1389. }
  1390. if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
  1391. {
  1392. return 'I';
  1393. }
  1394. if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
  1395. {
  1396. return 'u';
  1397. }
  1398. if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
  1399. {
  1400. return 'l';
  1401. }
  1402. if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
  1403. {
  1404. return 'm';
  1405. }
  1406. if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
  1407. {
  1408. return 'L';
  1409. }
  1410. // anything else is treated as high-precision number
  1411. return 'H'; // LCOV_EXCL_LINE
  1412. }
  1413. case value_t::number_unsigned:
  1414. {
  1415. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
  1416. {
  1417. return 'i';
  1418. }
  1419. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
  1420. {
  1421. return 'U';
  1422. }
  1423. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
  1424. {
  1425. return 'I';
  1426. }
  1427. if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
  1428. {
  1429. return 'u';
  1430. }
  1431. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
  1432. {
  1433. return 'l';
  1434. }
  1435. if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
  1436. {
  1437. return 'm';
  1438. }
  1439. if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
  1440. {
  1441. return 'L';
  1442. }
  1443. if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
  1444. {
  1445. return 'M';
  1446. }
  1447. // anything else is treated as high-precision number
  1448. return 'H'; // LCOV_EXCL_LINE
  1449. }
  1450. case value_t::number_float:
  1451. return get_ubjson_float_prefix(j.m_data.m_value.number_float);
  1452. case value_t::string:
  1453. return 'S';
  1454. case value_t::array: // fallthrough
  1455. case value_t::binary:
  1456. return '[';
  1457. case value_t::object:
  1458. return '{';
  1459. case value_t::discarded:
  1460. default: // discarded values
  1461. return 'N';
  1462. }
  1463. }
  1464. static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
  1465. {
  1466. return 'd'; // float 32
  1467. }
  1468. static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
  1469. {
  1470. return 'D'; // float 64
  1471. }
  1472. /*!
  1473. @return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid
  1474. */
  1475. bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type, const bjdata_version_t bjdata_version)
  1476. {
  1477. std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
  1478. {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'},
  1479. {"char", 'C'}, {"byte", 'B'}
  1480. };
  1481. string_t key = "_ArrayType_";
  1482. auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
  1483. if (it == bjdtype.end())
  1484. {
  1485. return true;
  1486. }
  1487. CharType dtype = it->second;
  1488. key = "_ArraySize_";
  1489. std::size_t len = (value.at(key).empty() ? 0 : 1);
  1490. for (const auto& el : value.at(key))
  1491. {
  1492. len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
  1493. }
  1494. key = "_ArrayData_";
  1495. if (value.at(key).size() != len)
  1496. {
  1497. return true;
  1498. }
  1499. oa->write_character('[');
  1500. oa->write_character('$');
  1501. oa->write_character(dtype);
  1502. oa->write_character('#');
  1503. key = "_ArraySize_";
  1504. write_ubjson(value.at(key), use_count, use_type, true, true, bjdata_version);
  1505. key = "_ArrayData_";
  1506. if (dtype == 'U' || dtype == 'C' || dtype == 'B')
  1507. {
  1508. for (const auto& el : value.at(key))
  1509. {
  1510. write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
  1511. }
  1512. }
  1513. else if (dtype == 'i')
  1514. {
  1515. for (const auto& el : value.at(key))
  1516. {
  1517. write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
  1518. }
  1519. }
  1520. else if (dtype == 'u')
  1521. {
  1522. for (const auto& el : value.at(key))
  1523. {
  1524. write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
  1525. }
  1526. }
  1527. else if (dtype == 'I')
  1528. {
  1529. for (const auto& el : value.at(key))
  1530. {
  1531. write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
  1532. }
  1533. }
  1534. else if (dtype == 'm')
  1535. {
  1536. for (const auto& el : value.at(key))
  1537. {
  1538. write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
  1539. }
  1540. }
  1541. else if (dtype == 'l')
  1542. {
  1543. for (const auto& el : value.at(key))
  1544. {
  1545. write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
  1546. }
  1547. }
  1548. else if (dtype == 'M')
  1549. {
  1550. for (const auto& el : value.at(key))
  1551. {
  1552. write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
  1553. }
  1554. }
  1555. else if (dtype == 'L')
  1556. {
  1557. for (const auto& el : value.at(key))
  1558. {
  1559. write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
  1560. }
  1561. }
  1562. else if (dtype == 'd')
  1563. {
  1564. for (const auto& el : value.at(key))
  1565. {
  1566. write_number(static_cast<float>(el.m_data.m_value.number_float), true);
  1567. }
  1568. }
  1569. else if (dtype == 'D')
  1570. {
  1571. for (const auto& el : value.at(key))
  1572. {
  1573. write_number(static_cast<double>(el.m_data.m_value.number_float), true);
  1574. }
  1575. }
  1576. return false;
  1577. }
  1578. ///////////////////////
  1579. // Utility functions //
  1580. ///////////////////////
  1581. /*
  1582. @brief write a number to output input
  1583. @param[in] n number of type @a NumberType
  1584. @param[in] OutputIsLittleEndian Set to true if output data is
  1585. required to be little endian
  1586. @tparam NumberType the type of the number
  1587. @note This function needs to respect the system's endianness, because bytes
  1588. in CBOR, MessagePack, and UBJSON are stored in network order (big
  1589. endian) and therefore need reordering on little endian systems.
  1590. On the other hand, BSON and BJData use little endian and should reorder
  1591. on big endian systems.
  1592. */
  1593. template<typename NumberType>
  1594. void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
  1595. {
  1596. // step 1: write number to array of length NumberType
  1597. std::array<CharType, sizeof(NumberType)> vec{};
  1598. std::memcpy(vec.data(), &n, sizeof(NumberType));
  1599. // step 2: write array to output (with possible reordering)
  1600. if (is_little_endian != OutputIsLittleEndian)
  1601. {
  1602. // reverse byte order prior to conversion if necessary
  1603. std::reverse(vec.begin(), vec.end());
  1604. }
  1605. oa->write_characters(vec.data(), sizeof(NumberType));
  1606. }
  1607. void write_compact_float(const number_float_t n, detail::input_format_t format)
  1608. {
  1609. #ifdef __GNUC__
  1610. #pragma GCC diagnostic push
  1611. #pragma GCC diagnostic ignored "-Wfloat-equal"
  1612. #endif
  1613. if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
  1614. static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
  1615. static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
  1616. {
  1617. oa->write_character(format == detail::input_format_t::cbor
  1618. ? get_cbor_float_prefix(static_cast<float>(n))
  1619. : get_msgpack_float_prefix(static_cast<float>(n)));
  1620. write_number(static_cast<float>(n));
  1621. }
  1622. else
  1623. {
  1624. oa->write_character(format == detail::input_format_t::cbor
  1625. ? get_cbor_float_prefix(n)
  1626. : get_msgpack_float_prefix(n));
  1627. write_number(n);
  1628. }
  1629. #ifdef __GNUC__
  1630. #pragma GCC diagnostic pop
  1631. #endif
  1632. }
  1633. public:
  1634. // The following to_char_type functions are implement the conversion
  1635. // between uint8_t and CharType. In case CharType is not unsigned,
  1636. // such a conversion is required to allow values greater than 128.
  1637. // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
  1638. template < typename C = CharType,
  1639. enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
  1640. static constexpr CharType to_char_type(std::uint8_t x) noexcept
  1641. {
  1642. return *reinterpret_cast<char*>(&x);
  1643. }
  1644. template < typename C = CharType,
  1645. enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
  1646. static CharType to_char_type(std::uint8_t x) noexcept
  1647. {
  1648. static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
  1649. static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
  1650. CharType result;
  1651. std::memcpy(&result, &x, sizeof(x));
  1652. return result;
  1653. }
  1654. template<typename C = CharType,
  1655. enable_if_t<std::is_unsigned<C>::value>* = nullptr>
  1656. static constexpr CharType to_char_type(std::uint8_t x) noexcept
  1657. {
  1658. return x;
  1659. }
  1660. template < typename InputCharType, typename C = CharType,
  1661. enable_if_t <
  1662. std::is_signed<C>::value &&
  1663. std::is_signed<char>::value &&
  1664. std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
  1665. > * = nullptr >
  1666. static constexpr CharType to_char_type(InputCharType x) noexcept
  1667. {
  1668. return x;
  1669. }
  1670. private:
  1671. /// whether we can assume little endianness
  1672. const bool is_little_endian = little_endianness();
  1673. /// the output
  1674. output_adapter_t<CharType> oa = nullptr;
  1675. };
  1676. } // namespace detail
  1677. NLOHMANN_JSON_NAMESPACE_END