pack.hpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  1. //
  2. // MessagePack for C++ serializing routine
  3. //
  4. // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef MSGPACK_V1_PACK_HPP
  11. #define MSGPACK_V1_PACK_HPP
  12. #include "msgpack/v1/pack_decl.hpp"
  13. #include <stdexcept>
  14. #include <limits>
  15. #include <cstring>
  16. #include <climits>
  17. namespace msgpack {
  18. /// @cond
  19. MSGPACK_API_VERSION_NAMESPACE(v1) {
  20. /// @endcond
  21. /// The class template that supports continuous packing.
  22. /**
  23. * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)`
  24. *
  25. */
  26. template <typename Stream>
  27. class packer {
  28. public:
  29. /// Constructor
  30. /**
  31. * This constructor is left for compatibility.
  32. * Use `packer(Stream& s)` instead of the constructor.
  33. *
  34. * @param s A pointer to packing destination stream object.
  35. */
  36. packer(Stream* s);
  37. /// Constructor
  38. /**
  39. * @param s Packing destination stream object.
  40. */
  41. packer(Stream& s);
  42. public:
  43. /// Packing function template
  44. /**
  45. * @tparam T The type of packing object.
  46. *
  47. * @param v a packing object.
  48. *
  49. * @return The reference of `*this`.
  50. */
  51. template <typename T>
  52. packer<Stream>& pack(const T& v);
  53. /// Packing uint8
  54. /**
  55. * The byte size of the packed data depends on `d`.
  56. * The packed type is positive fixnum or uint8.
  57. * The minimum byte size expression is used.
  58. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  59. *
  60. * @param d a packing object.
  61. *
  62. * @return The reference of `*this`.
  63. */
  64. packer<Stream>& pack_uint8(uint8_t d);
  65. /// Packing uint16
  66. /**
  67. * The byte size of the packed data depends on `d`.
  68. * The packed type is positive fixnum, uint8 or uint16.
  69. * The minimum byte size expression is used.
  70. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  71. *
  72. * @param d a packing object.
  73. *
  74. * @return The reference of `*this`.
  75. */
  76. packer<Stream>& pack_uint16(uint16_t d);
  77. /// Packing uint32
  78. /**
  79. * The byte size of the packed data depends on `d`.
  80. * The packed type is positive fixnum, uint8, uint16 or uint32.
  81. * The minimum byte size expression is used.
  82. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  83. *
  84. * @param d a packing object.
  85. *
  86. * @return The reference of `*this`.
  87. */
  88. packer<Stream>& pack_uint32(uint32_t d);
  89. /// Packing uint16
  90. /**
  91. * The byte size of the packed data depends on `d`.
  92. * The packed type is positive fixnum, uint8, uint16, uint32 or uint64.
  93. * The minimum byte size expression is used.
  94. * positive fixnum, uint8, uint16, or uint32 is used.
  95. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  96. *
  97. * @param d a packing object.
  98. *
  99. * @return The reference of `*this`.
  100. */
  101. packer<Stream>& pack_uint64(uint64_t d);
  102. /// Packing int8
  103. /**
  104. * The byte size of the packed data depends on `d`.
  105. * If `d` is zero or positive, the packed type is positive fixnum, or uint8,
  106. * else the packed type is negative fixnum, or int8
  107. * The minimum byte size expression is used.
  108. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  109. *
  110. * @param d a packing object.
  111. *
  112. * @return The reference of `*this`.
  113. */
  114. packer<Stream>& pack_int8(int8_t d);
  115. /// Packing int16
  116. /**
  117. * The byte size of the packed data depends on `d`.
  118. * If `d` is zero or positive, the packed type is positive fixnum, uint8, or uint16,
  119. * else the packed type is negative fixnum, int8, or int16.
  120. * The minimum byte size expression is used.
  121. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  122. *
  123. * @param d a packing object.
  124. *
  125. * @return The reference of `*this`.
  126. */
  127. packer<Stream>& pack_int16(int16_t d);
  128. /// Packing int32
  129. /**
  130. * The byte size of the packed data depends on `d`.
  131. * If `d` is zero or positive, the packed type is positive fixnum, uint8, uint16, or uint32,
  132. * else the packed type is negative fixnum, int8, int16, or int32.
  133. * The minimum byte size expression is used.
  134. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  135. *
  136. * @param d a packing object.
  137. *
  138. * @return The reference of `*this`.
  139. */
  140. packer<Stream>& pack_int32(int32_t d);
  141. /// Packing int32
  142. /**
  143. * The byte size of the packed data depends on `d`.
  144. * If `d` is zero or positive, the packed type is positive fixnum, uint8, uint16, uint32, or uint64,
  145. * else the packed type is negative fixnum, int8, int16, int32, or int64.
  146. * The minimum byte size expression is used.
  147. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  148. *
  149. * @param d a packing object.
  150. *
  151. * @return The reference of `*this`.
  152. */
  153. packer<Stream>& pack_int64(int64_t d);
  154. /// Packing uint8 (fixed packed type).
  155. /**
  156. * The packed type is always uint8.
  157. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  158. *
  159. * @param d a packing object.
  160. *
  161. * @return The reference of `*this`.
  162. */
  163. packer<Stream>& pack_fix_uint8(uint8_t d);
  164. /// Packing uint8 (fixed packed type).
  165. /**
  166. * The packed type is always uint16.
  167. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  168. *
  169. * @param d a packing object.
  170. *
  171. * @return The reference of `*this`.
  172. */
  173. packer<Stream>& pack_fix_uint16(uint16_t d);
  174. /// Packing uint8 (fixed packed type).
  175. /**
  176. * The packed type is always uint32.
  177. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  178. *
  179. * @param d a packing object.
  180. *
  181. * @return The reference of `*this`.
  182. */
  183. packer<Stream>& pack_fix_uint32(uint32_t d);
  184. /// Packing uint8 (fixed packed type).
  185. /**
  186. * The packed type is always uint64.
  187. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  188. *
  189. * @param d a packing object.
  190. *
  191. * @return The reference of `*this`.
  192. */
  193. packer<Stream>& pack_fix_uint64(uint64_t d);
  194. /// Packing uint8 (fixed packed type).
  195. /**
  196. * The packed type is always int8.
  197. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  198. *
  199. * @param d a packing object.
  200. *
  201. * @return The reference of `*this`.
  202. */
  203. packer<Stream>& pack_fix_int8(int8_t d);
  204. /// Packing uint8 (fixed packed type).
  205. /**
  206. * The packed type is always int16.
  207. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  208. *
  209. * @param d a packing object.
  210. *
  211. * @return The reference of `*this`.
  212. */
  213. packer<Stream>& pack_fix_int16(int16_t d);
  214. /// Packing uint8 (fixed packed type).
  215. /**
  216. * The packed type is always int32.
  217. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  218. *
  219. * @param d a packing object.
  220. *
  221. * @return The reference of `*this`.
  222. */
  223. packer<Stream>& pack_fix_int32(int32_t d);
  224. /// Packing uint8 (fixed packed type).
  225. /**
  226. * The packed type is always int64.
  227. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  228. *
  229. * @param d a packing object.
  230. *
  231. * @return The reference of `*this`.
  232. */
  233. packer<Stream>& pack_fix_int64(int64_t d);
  234. /// Packing char
  235. /**
  236. * The byte size of the packed data depends on `d`.
  237. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  238. * else the packed type is negative fixnum, or int*
  239. * The minimum byte size expression is used.
  240. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  241. *
  242. * @param d a packing object.
  243. *
  244. * @return The reference of `*this`.
  245. */
  246. packer<Stream>& pack_char(char d);
  247. /// Packing signed char
  248. /**
  249. * The byte size of the packed data depends on `d`.
  250. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  251. * else the packed type is negative fixnum, or int*
  252. * The minimum byte size expression is used.
  253. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  254. *
  255. * @param d a packing object.
  256. *
  257. * @return The reference of `*this`.
  258. */
  259. packer<Stream>& pack_signed_char(signed char d);
  260. /// Packing short
  261. /**
  262. * The byte size of the packed data depends on `d`.
  263. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  264. * else the packed type is negative fixnum, or int*
  265. * The minimum byte size expression is used.
  266. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  267. *
  268. * @param d a packing object.
  269. *
  270. * @return The reference of `*this`.
  271. */
  272. packer<Stream>& pack_short(short d);
  273. /// Packing int
  274. /**
  275. * The byte size of the packed data depends on `d`.
  276. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  277. * else the packed type is negative fixnum, or int*
  278. * The minimum byte size expression is used.
  279. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  280. *
  281. * @param d a packing object.
  282. *
  283. * @return The reference of `*this`.
  284. */
  285. packer<Stream>& pack_int(int d);
  286. /// Packing long
  287. /**
  288. * The byte size of the packed data depends on `d`.
  289. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  290. * else the packed type is negative fixnum, or int*
  291. * The minimum byte size expression is used.
  292. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  293. *
  294. * @param d a packing object.
  295. *
  296. * @return The reference of `*this`.
  297. */
  298. packer<Stream>& pack_long(long d);
  299. /// Packing long long
  300. /**
  301. * The byte size of the packed data depends on `d`.
  302. * If `d` is zero or positive, the packed type is positive fixnum, or uint*,
  303. * else the packed type is negative fixnum, or int*
  304. * The minimum byte size expression is used.
  305. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  306. *
  307. * @param d a packing object.
  308. *
  309. * @return The reference of `*this`.
  310. */
  311. packer<Stream>& pack_long_long(long long d);
  312. /// Packing unsigned char
  313. /**
  314. * The byte size of the packed data depends on `d`.
  315. * The packed type is positive fixnum, or uint*.
  316. * The minimum byte size expression is used.
  317. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  318. *
  319. * @param d a packing object.
  320. *
  321. * @return The reference of `*this`.
  322. */
  323. packer<Stream>& pack_unsigned_char(unsigned char d);
  324. /// Packing unsigned short
  325. /**
  326. * The byte size of the packed data depends on `d`.
  327. * The packed type is positive fixnum, or uint*.
  328. * The minimum byte size expression is used.
  329. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  330. *
  331. * @param d a packing object.
  332. *
  333. * @return The reference of `*this`.
  334. */
  335. packer<Stream>& pack_unsigned_short(unsigned short d);
  336. /// Packing unsigned int
  337. /**
  338. * The byte size of the packed data depends on `d`.
  339. * The packed type is positive fixnum, or uint*.
  340. * The minimum byte size expression is used.
  341. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  342. *
  343. * @param d a packing object.
  344. *
  345. * @return The reference of `*this`.
  346. */
  347. packer<Stream>& pack_unsigned_int(unsigned int d);
  348. /// Packing unsigned long
  349. /**
  350. * The byte size of the packed data depends on `d`.
  351. * The packed type is positive fixnum, or uint*.
  352. * The minimum byte size expression is used.
  353. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  354. *
  355. * @param d a packing object.
  356. *
  357. * @return The reference of `*this`.
  358. */
  359. packer<Stream>& pack_unsigned_long(unsigned long d);
  360. /// Packing unsigned long long
  361. /**
  362. * The byte size of the packed data depends on `d`.
  363. * The packed type is positive fixnum, or uint*.
  364. * The minimum byte size expression is used.
  365. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
  366. *
  367. * @param d a packing object.
  368. *
  369. * @return The reference of `*this`.
  370. */
  371. packer<Stream>& pack_unsigned_long_long(unsigned long long d);
  372. /// Packing float
  373. /**
  374. * The packed type is float32.
  375. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-float
  376. *
  377. * @param d a packing object.
  378. *
  379. * @return The reference of `*this`.
  380. */
  381. packer<Stream>& pack_float(float d);
  382. /// Packing double
  383. /**
  384. * The packed type is float64.
  385. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-float
  386. *
  387. * @param d a packing object.
  388. *
  389. * @return The reference of `*this`.
  390. */
  391. packer<Stream>& pack_double(double d);
  392. /// Packing nil
  393. /**
  394. * The packed type is nil.
  395. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-nil
  396. *
  397. * @return The reference of `*this`.
  398. */
  399. packer<Stream>& pack_nil();
  400. /// Packing true
  401. /**
  402. * The packed type is bool, value is true.
  403. * See https://github.com/msgpack/msgpack/blob/master/spec.md#bool-format-family
  404. *
  405. * @return The reference of `*this`.
  406. */
  407. packer<Stream>& pack_true();
  408. /// Packing false
  409. /**
  410. * The packed type is bool, value is false.
  411. * See https://github.com/msgpack/msgpack/blob/master/spec.md#bool-format-family
  412. *
  413. * @return The reference of `*this`.
  414. */
  415. packer<Stream>& pack_false();
  416. /// Packing array header and size
  417. /**
  418. * The packed type is array header and array size.
  419. * You need to pack `n` msgpack objects following this header and size.
  420. * See https://github.com/msgpack/msgpack/blob/master/spec.md#array-format-family
  421. *
  422. * @param n The number of array elements (array size).
  423. *
  424. * @return The reference of `*this`.
  425. */
  426. packer<Stream>& pack_array(uint32_t n);
  427. /// Packing map header and size
  428. /**
  429. * The packed type is map header and map size.
  430. * You need to pack `n` pairs of msgpack objects following this header and size.
  431. * See https://github.com/msgpack/msgpack/blob/master/spec.md#map-format-family
  432. *
  433. * @param n The number of array elements (array size).
  434. *
  435. * @return The reference of `*this`.
  436. */
  437. packer<Stream>& pack_map(uint32_t n);
  438. /// Packing str header and length
  439. /**
  440. * The packed type is str header and length.
  441. * The minimum byte size length expression is used.
  442. * You need to call `pack_str_body(const char* b, uint32_t l)` after this function calling with the same `l` value.
  443. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str
  444. *
  445. * @param l The length of string.
  446. *
  447. * @return The reference of `*this`.
  448. */
  449. packer<Stream>& pack_str(uint32_t l);
  450. /// Packing str body
  451. /**
  452. * You need to call this function just after `pack_str(uint32_t l)` calling.
  453. * The value `l` should be the same as `pack_str(uint32_t l)` argument `l`.
  454. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str
  455. *
  456. * @param l The length of string.
  457. *
  458. * @return The reference of `*this`.
  459. */
  460. packer<Stream>& pack_str_body(const char* b, uint32_t l);
  461. /// Packing raw (v4) header and length
  462. /**
  463. * The packed type is raw header and length.
  464. * The minimum byte size length expression is used.
  465. * The format raw (v4) is old MessagePack version4 format.
  466. * You need to call `pack_v4raw_body(const char* b, uint32_t l)` after this function calling with the same `l` value.
  467. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str
  468. *
  469. * @param l The length of string.
  470. *
  471. * @return The reference of `*this`.
  472. */
  473. packer<Stream>& pack_v4raw(uint32_t l);
  474. /// Packing raw (v4) body
  475. /**
  476. * The format raw (v4) is old MessagePack version4 format.
  477. * You need to call this function just after `pack_v4raw(uint32_t l)` calling.
  478. * The value `l` should be the same as `pack_v4raw(uint32_t l)` argument `l`.
  479. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str
  480. *
  481. * @param l The length of string.
  482. *
  483. * @return The reference of `*this`.
  484. */
  485. packer<Stream>& pack_v4raw_body(const char* b, uint32_t l);
  486. /// Packing bin header and length
  487. /**
  488. * The packed type is bin header and length.
  489. * The minimum byte size length expression is used.
  490. * You need to call `pack_bin_body(const char* b, uint32_t l)` after this function calling with the same `l` value.
  491. * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family
  492. *
  493. * @param l The length of string.
  494. *
  495. * @return The reference of `*this`.
  496. */
  497. packer<Stream>& pack_bin(uint32_t l);
  498. /// Packing bin body
  499. /**
  500. * You need to call this function just after `pack_bin(uint32_t l)` calling.
  501. * The value `l` should be the same as `pack_bin(uint32_t l)` argument `l`.
  502. * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family
  503. *
  504. * @param l The length of string.
  505. *
  506. * @return The reference of `*this`.
  507. */
  508. packer<Stream>& pack_bin_body(const char* b, uint32_t l);
  509. /// Packing ext header, type, and length
  510. /**
  511. * The packed type is ext.
  512. * The minimum byte size length expression is used.
  513. * The length 1, 2, 4, 8, and 16 can be encoded in the header.
  514. * You need to call `pack_ext_body(const char* b, uint32_t l)` after this function calling with the same `l` value.
  515. * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-ext
  516. *
  517. * @param l The length of string.
  518. *
  519. * @return The reference of `*this`.
  520. */
  521. packer<Stream>& pack_ext(size_t l, int8_t type);
  522. /// Packing ext body
  523. /**
  524. * You need to call this function just after `pack_ext(size_t l, int8_t type)` calling.
  525. * The value `l` should be the same as `pack_ext(size_t l, int8_t type)` argument `l`.
  526. * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family
  527. *
  528. * @param l The length of string.
  529. *
  530. * @return The reference of `*this`.
  531. */
  532. packer<Stream>& pack_ext_body(const char* b, uint32_t l);
  533. private:
  534. template <typename T>
  535. void pack_imp_uint8(T d);
  536. template <typename T>
  537. void pack_imp_uint16(T d);
  538. template <typename T>
  539. void pack_imp_uint32(T d);
  540. template <typename T>
  541. void pack_imp_uint64(T d);
  542. template <typename T>
  543. void pack_imp_int8(T d);
  544. template <typename T>
  545. void pack_imp_int16(T d);
  546. template <typename T>
  547. void pack_imp_int32(T d);
  548. template <typename T>
  549. void pack_imp_int64(T d);
  550. void append_buffer(const char* buf, size_t len)
  551. { m_stream.write(buf, len); }
  552. private:
  553. Stream& m_stream;
  554. #if defined(MSGPACK_USE_CPP03)
  555. private:
  556. packer(const packer&);
  557. packer& operator=(const packer&);
  558. packer();
  559. #else // defined(MSGPACK_USE_CPP03)
  560. public:
  561. packer(const packer&) = delete;
  562. packer& operator=(const packer&) = delete;
  563. packer() = delete;
  564. #endif // defined(MSGPACK_USE_CPP03)
  565. };
  566. /// Pack the value as MessagePack format into the stream
  567. /**
  568. * This function template is left for compatibility.
  569. * Use `void pack(Stream& s, const T& v)` instead of the function template.
  570. *
  571. * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)`
  572. * @tparam T Any type that is adapted to MessagePack
  573. * @param s The pointer to packing destination stream
  574. * @param v Packing value
  575. */
  576. template <typename Stream, typename T>
  577. inline void pack(Stream* s, const T& v)
  578. {
  579. packer<Stream>(*s).pack(v);
  580. }
  581. /// Pack the value as MessagePack format into the stream
  582. /**
  583. * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)`
  584. * @tparam T Any type that is adapted to MessagePack
  585. * @param s Packing destination stream
  586. * @param v Packing value
  587. */
  588. template <typename Stream, typename T>
  589. inline void pack(Stream& s, const T& v)
  590. {
  591. packer<Stream>(s).pack(v);
  592. }
  593. #if MSGPACK_ENDIAN_LITTLE_BYTE
  594. template <typename T>
  595. inline char take8_8(T d) {
  596. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
  597. }
  598. template <typename T>
  599. inline char take8_16(T d) {
  600. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
  601. }
  602. template <typename T>
  603. inline char take8_32(T d) {
  604. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
  605. }
  606. template <typename T>
  607. inline char take8_64(T d) {
  608. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
  609. }
  610. #elif MSGPACK_ENDIAN_BIG_BYTE
  611. template <typename T>
  612. inline char take8_8(T d) {
  613. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
  614. }
  615. template <typename T>
  616. inline char take8_16(T d) {
  617. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[1]);
  618. }
  619. template <typename T>
  620. inline char take8_32(T d) {
  621. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[3]);
  622. }
  623. template <typename T>
  624. inline char take8_64(T d) {
  625. return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[7]);
  626. }
  627. #else
  628. #error msgpack-c supports only big endian and little endian
  629. #endif
  630. template <typename Stream>
  631. inline packer<Stream>::packer(Stream* s) : m_stream(*s) { }
  632. template <typename Stream>
  633. inline packer<Stream>::packer(Stream& s) : m_stream(s) { }
  634. template <typename Stream>
  635. inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)
  636. { pack_imp_uint8(d); return *this; }
  637. template <typename Stream>
  638. inline packer<Stream>& packer<Stream>::pack_uint16(uint16_t d)
  639. { pack_imp_uint16(d); return *this; }
  640. template <typename Stream>
  641. inline packer<Stream>& packer<Stream>::pack_uint32(uint32_t d)
  642. { pack_imp_uint32(d); return *this; }
  643. template <typename Stream>
  644. inline packer<Stream>& packer<Stream>::pack_uint64(uint64_t d)
  645. { pack_imp_uint64(d); return *this; }
  646. template <typename Stream>
  647. inline packer<Stream>& packer<Stream>::pack_int8(int8_t d)
  648. { pack_imp_int8(d); return *this; }
  649. template <typename Stream>
  650. inline packer<Stream>& packer<Stream>::pack_int16(int16_t d)
  651. { pack_imp_int16(d); return *this; }
  652. template <typename Stream>
  653. inline packer<Stream>& packer<Stream>::pack_int32(int32_t d)
  654. { pack_imp_int32(d); return *this; }
  655. template <typename Stream>
  656. inline packer<Stream>& packer<Stream>::pack_int64(int64_t d)
  657. { pack_imp_int64(d); return *this;}
  658. template <typename Stream>
  659. inline packer<Stream>& packer<Stream>::pack_fix_uint8(uint8_t d)
  660. {
  661. char buf[2] = {static_cast<char>(0xccu), take8_8(d)};
  662. append_buffer(buf, 2);
  663. return *this;
  664. }
  665. template <typename Stream>
  666. inline packer<Stream>& packer<Stream>::pack_fix_uint16(uint16_t d)
  667. {
  668. char buf[3];
  669. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], d);
  670. append_buffer(buf, 3);
  671. return *this;
  672. }
  673. template <typename Stream>
  674. inline packer<Stream>& packer<Stream>::pack_fix_uint32(uint32_t d)
  675. {
  676. char buf[5];
  677. buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], d);
  678. append_buffer(buf, 5);
  679. return *this;
  680. }
  681. template <typename Stream>
  682. inline packer<Stream>& packer<Stream>::pack_fix_uint64(uint64_t d)
  683. {
  684. char buf[9];
  685. buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d);
  686. append_buffer(buf, 9);
  687. return *this;
  688. }
  689. template <typename Stream>
  690. inline packer<Stream>& packer<Stream>::pack_fix_int8(int8_t d)
  691. {
  692. char buf[2] = {static_cast<char>(0xd0u), take8_8(d)};
  693. append_buffer(buf, 2);
  694. return *this;
  695. }
  696. template <typename Stream>
  697. inline packer<Stream>& packer<Stream>::pack_fix_int16(int16_t d)
  698. {
  699. char buf[3];
  700. buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], d);
  701. append_buffer(buf, 3);
  702. return *this;
  703. }
  704. template <typename Stream>
  705. inline packer<Stream>& packer<Stream>::pack_fix_int32(int32_t d)
  706. {
  707. char buf[5];
  708. buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], d);
  709. append_buffer(buf, 5);
  710. return *this;
  711. }
  712. template <typename Stream>
  713. inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d)
  714. {
  715. char buf[9];
  716. buf[0] = static_cast<char>(0xd3u); _msgpack_store64(&buf[1], d);
  717. append_buffer(buf, 9);
  718. return *this;
  719. }
  720. template <typename Stream>
  721. inline packer<Stream>& packer<Stream>::pack_char(char d)
  722. {
  723. #if defined(CHAR_MIN)
  724. #if CHAR_MIN < 0
  725. pack_imp_int8(d);
  726. #else
  727. pack_imp_uint8(d);
  728. #endif
  729. #else
  730. #error CHAR_MIN is not defined
  731. #endif
  732. return *this;
  733. }
  734. template <typename Stream>
  735. inline packer<Stream>& packer<Stream>::pack_signed_char(signed char d)
  736. {
  737. pack_imp_int8(d);
  738. return *this;
  739. }
  740. template <typename Stream>
  741. inline packer<Stream>& packer<Stream>::pack_short(short d)
  742. {
  743. #if defined(SIZEOF_SHORT)
  744. #if SIZEOF_SHORT == 2
  745. pack_imp_int16(d);
  746. #elif SIZEOF_SHORT == 4
  747. pack_imp_int32(d);
  748. #else
  749. pack_imp_int64(d);
  750. #endif
  751. #elif defined(SHRT_MAX)
  752. #if SHRT_MAX == 0x7fff
  753. pack_imp_int16(d);
  754. #elif SHRT_MAX == 0x7fffffff
  755. pack_imp_int32(d);
  756. #else
  757. pack_imp_int64(d);
  758. #endif
  759. #else
  760. if(sizeof(short) == 2) {
  761. pack_imp_int16(d);
  762. } else if(sizeof(short) == 4) {
  763. pack_imp_int32(d);
  764. } else {
  765. pack_imp_int64(d);
  766. }
  767. #endif
  768. return *this;
  769. }
  770. template <typename Stream>
  771. inline packer<Stream>& packer<Stream>::pack_int(int d)
  772. {
  773. #if defined(SIZEOF_INT)
  774. #if SIZEOF_INT == 2
  775. pack_imp_int16(d);
  776. #elif SIZEOF_INT == 4
  777. pack_imp_int32(d);
  778. #else
  779. pack_imp_int64(d);
  780. #endif
  781. #elif defined(INT_MAX)
  782. #if INT_MAX == 0x7fff
  783. pack_imp_int16(d);
  784. #elif INT_MAX == 0x7fffffff
  785. pack_imp_int32(d);
  786. #else
  787. pack_imp_int64(d);
  788. #endif
  789. #else
  790. if(sizeof(int) == 2) {
  791. pack_imp_int16(d);
  792. } else if(sizeof(int) == 4) {
  793. pack_imp_int32(d);
  794. } else {
  795. pack_imp_int64(d);
  796. }
  797. #endif
  798. return *this;
  799. }
  800. template <typename Stream>
  801. inline packer<Stream>& packer<Stream>::pack_long(long d)
  802. {
  803. #if defined(SIZEOF_LONG)
  804. #if SIZEOF_LONG == 2
  805. pack_imp_int16(d);
  806. #elif SIZEOF_LONG == 4
  807. pack_imp_int32(d);
  808. #else
  809. pack_imp_int64(d);
  810. #endif
  811. #elif defined(LONG_MAX)
  812. #if LONG_MAX == 0x7fffL
  813. pack_imp_int16(d);
  814. #elif LONG_MAX == 0x7fffffffL
  815. pack_imp_int32(d);
  816. #else
  817. pack_imp_int64(d);
  818. #endif
  819. #else
  820. if(sizeof(long) == 2) {
  821. pack_imp_int16(d);
  822. } else if(sizeof(long) == 4) {
  823. pack_imp_int32(d);
  824. } else {
  825. pack_imp_int64(d);
  826. }
  827. #endif
  828. return *this;
  829. }
  830. template <typename Stream>
  831. inline packer<Stream>& packer<Stream>::pack_long_long(long long d)
  832. {
  833. #if defined(SIZEOF_LONG_LONG)
  834. #if SIZEOF_LONG_LONG == 2
  835. pack_imp_int16(d);
  836. #elif SIZEOF_LONG_LONG == 4
  837. pack_imp_int32(d);
  838. #else
  839. pack_imp_int64(d);
  840. #endif
  841. #elif defined(LLONG_MAX)
  842. #if LLONG_MAX == 0x7fffL
  843. pack_imp_int16(d);
  844. #elif LLONG_MAX == 0x7fffffffL
  845. pack_imp_int32(d);
  846. #else
  847. pack_imp_int64(d);
  848. #endif
  849. #else
  850. if(sizeof(long long) == 2) {
  851. pack_imp_int16(d);
  852. } else if(sizeof(long long) == 4) {
  853. pack_imp_int32(d);
  854. } else {
  855. pack_imp_int64(d);
  856. }
  857. #endif
  858. return *this;
  859. }
  860. template <typename Stream>
  861. inline packer<Stream>& packer<Stream>::pack_unsigned_char(unsigned char d)
  862. {
  863. pack_imp_uint8(d);
  864. return *this;
  865. }
  866. template <typename Stream>
  867. inline packer<Stream>& packer<Stream>::pack_unsigned_short(unsigned short d)
  868. {
  869. #if defined(SIZEOF_SHORT)
  870. #if SIZEOF_SHORT == 2
  871. pack_imp_uint16(d);
  872. #elif SIZEOF_SHORT == 4
  873. pack_imp_uint32(d);
  874. #else
  875. pack_imp_uint64(d);
  876. #endif
  877. #elif defined(USHRT_MAX)
  878. #if USHRT_MAX == 0xffffU
  879. pack_imp_uint16(d);
  880. #elif USHRT_MAX == 0xffffffffU
  881. pack_imp_uint32(d);
  882. #else
  883. pack_imp_uint64(d);
  884. #endif
  885. #else
  886. if(sizeof(unsigned short) == 2) {
  887. pack_imp_uint16(d);
  888. } else if(sizeof(unsigned short) == 4) {
  889. pack_imp_uint32(d);
  890. } else {
  891. pack_imp_uint64(d);
  892. }
  893. #endif
  894. return *this;
  895. }
  896. template <typename Stream>
  897. inline packer<Stream>& packer<Stream>::pack_unsigned_int(unsigned int d)
  898. {
  899. #if defined(SIZEOF_INT)
  900. #if SIZEOF_INT == 2
  901. pack_imp_uint16(d);
  902. #elif SIZEOF_INT == 4
  903. pack_imp_uint32(d);
  904. #else
  905. pack_imp_uint64(d);
  906. #endif
  907. #elif defined(UINT_MAX)
  908. #if UINT_MAX == 0xffffU
  909. pack_imp_uint16(d);
  910. #elif UINT_MAX == 0xffffffffU
  911. pack_imp_uint32(d);
  912. #else
  913. pack_imp_uint64(d);
  914. #endif
  915. #else
  916. if(sizeof(unsigned int) == 2) {
  917. pack_imp_uint16(d);
  918. } else if(sizeof(unsigned int) == 4) {
  919. pack_imp_uint32(d);
  920. } else {
  921. pack_imp_uint64(d);
  922. }
  923. #endif
  924. return *this;
  925. }
  926. template <typename Stream>
  927. inline packer<Stream>& packer<Stream>::pack_unsigned_long(unsigned long d)
  928. {
  929. #if defined(SIZEOF_LONG)
  930. #if SIZEOF_LONG == 2
  931. pack_imp_uint16(d);
  932. #elif SIZEOF_LONG == 4
  933. pack_imp_uint32(d);
  934. #else
  935. pack_imp_uint64(d);
  936. #endif
  937. #elif defined(ULONG_MAX)
  938. #if ULONG_MAX == 0xffffUL
  939. pack_imp_uint16(d);
  940. #elif ULONG_MAX == 0xffffffffUL
  941. pack_imp_uint32(d);
  942. #else
  943. pack_imp_uint64(d);
  944. #endif
  945. #else
  946. if(sizeof(unsigned long) == 2) {
  947. pack_imp_uint16(d);
  948. } else if(sizeof(unsigned long) == 4) {
  949. pack_imp_uint32(d);
  950. } else {
  951. pack_imp_uint64(d);
  952. }
  953. #endif
  954. return *this;
  955. }
  956. template <typename Stream>
  957. inline packer<Stream>& packer<Stream>::pack_unsigned_long_long(unsigned long long d)
  958. {
  959. #if defined(SIZEOF_LONG_LONG)
  960. #if SIZEOF_LONG_LONG == 2
  961. pack_imp_uint16(d);
  962. #elif SIZEOF_LONG_LONG == 4
  963. pack_imp_uint32(d);
  964. #else
  965. pack_imp_uint64(d);
  966. #endif
  967. #elif defined(ULLONG_MAX)
  968. #if ULLONG_MAX == 0xffffUL
  969. pack_imp_uint16(d);
  970. #elif ULLONG_MAX == 0xffffffffUL
  971. pack_imp_uint32(d);
  972. #else
  973. pack_imp_uint64(d);
  974. #endif
  975. #else
  976. if(sizeof(unsigned long long) == 2) {
  977. pack_imp_uint16(d);
  978. } else if(sizeof(unsigned long long) == 4) {
  979. pack_imp_uint32(d);
  980. } else {
  981. pack_imp_uint64(d);
  982. }
  983. #endif
  984. return *this;
  985. }
  986. template <typename Stream>
  987. inline packer<Stream>& packer<Stream>::pack_float(float d)
  988. {
  989. union { float f; uint32_t i; } mem;
  990. mem.f = d;
  991. char buf[5];
  992. buf[0] = static_cast<char>(0xcau); _msgpack_store32(&buf[1], mem.i);
  993. append_buffer(buf, 5);
  994. return *this;
  995. }
  996. template <typename Stream>
  997. inline packer<Stream>& packer<Stream>::pack_double(double d)
  998. {
  999. union { double f; uint64_t i; } mem;
  1000. mem.f = d;
  1001. char buf[9];
  1002. buf[0] = static_cast<char>(0xcbu);
  1003. #if defined(TARGET_OS_IPHONE)
  1004. // ok
  1005. #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
  1006. // https://github.com/msgpack/msgpack-perl/pull/1
  1007. mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
  1008. #endif
  1009. _msgpack_store64(&buf[1], mem.i);
  1010. append_buffer(buf, 9);
  1011. return *this;
  1012. }
  1013. template <typename Stream>
  1014. inline packer<Stream>& packer<Stream>::pack_nil()
  1015. {
  1016. const char d = static_cast<char>(0xc0u);
  1017. append_buffer(&d, 1);
  1018. return *this;
  1019. }
  1020. template <typename Stream>
  1021. inline packer<Stream>& packer<Stream>::pack_true()
  1022. {
  1023. const char d = static_cast<char>(0xc3u);
  1024. append_buffer(&d, 1);
  1025. return *this;
  1026. }
  1027. template <typename Stream>
  1028. inline packer<Stream>& packer<Stream>::pack_false()
  1029. {
  1030. const char d = static_cast<char>(0xc2u);
  1031. append_buffer(&d, 1);
  1032. return *this;
  1033. }
  1034. template <typename Stream>
  1035. inline packer<Stream>& packer<Stream>::pack_array(uint32_t n)
  1036. {
  1037. if(n < 16) {
  1038. char d = static_cast<char>(0x90u | n);
  1039. append_buffer(&d, 1);
  1040. } else if(n < 65536) {
  1041. char buf[3];
  1042. buf[0] = static_cast<char>(0xdcu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n));
  1043. append_buffer(buf, 3);
  1044. } else {
  1045. char buf[5];
  1046. buf[0] = static_cast<char>(0xddu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n));
  1047. append_buffer(buf, 5);
  1048. }
  1049. return *this;
  1050. }
  1051. template <typename Stream>
  1052. inline packer<Stream>& packer<Stream>::pack_map(uint32_t n)
  1053. {
  1054. if(n < 16) {
  1055. unsigned char d = static_cast<unsigned char>(0x80u | n);
  1056. char buf = take8_8(d);
  1057. append_buffer(&buf, 1);
  1058. } else if(n < 65536) {
  1059. char buf[3];
  1060. buf[0] = static_cast<char>(0xdeu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n));
  1061. append_buffer(buf, 3);
  1062. } else {
  1063. char buf[5];
  1064. buf[0] = static_cast<char>(0xdfu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n));
  1065. append_buffer(buf, 5);
  1066. }
  1067. return *this;
  1068. }
  1069. template <typename Stream>
  1070. inline packer<Stream>& packer<Stream>::pack_str(uint32_t l)
  1071. {
  1072. if(l < 32) {
  1073. unsigned char d = static_cast<uint8_t>(0xa0u | l);
  1074. char buf = take8_8(d);
  1075. append_buffer(&buf, 1);
  1076. } else if(l < 256) {
  1077. char buf[2];
  1078. buf[0] = static_cast<char>(0xd9u); buf[1] = static_cast<uint8_t>(l);
  1079. append_buffer(buf, 2);
  1080. } else if(l < 65536) {
  1081. char buf[3];
  1082. buf[0] = static_cast<char>(0xdau); _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
  1083. append_buffer(buf, 3);
  1084. } else {
  1085. char buf[5];
  1086. buf[0] = static_cast<char>(0xdbu); _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
  1087. append_buffer(buf, 5);
  1088. }
  1089. return *this;
  1090. }
  1091. template <typename Stream>
  1092. inline packer<Stream>& packer<Stream>::pack_str_body(const char* b, uint32_t l)
  1093. {
  1094. append_buffer(b, l);
  1095. return *this;
  1096. }
  1097. // Raw (V4)
  1098. template <typename Stream>
  1099. inline packer<Stream>& packer<Stream>::pack_v4raw(uint32_t l)
  1100. {
  1101. if(l < 32) {
  1102. unsigned char d = static_cast<uint8_t>(0xa0u | l);
  1103. char buf = take8_8(d);
  1104. append_buffer(&buf, 1);
  1105. } else if(l < 65536) {
  1106. char buf[3];
  1107. buf[0] = static_cast<char>(0xdau); _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
  1108. append_buffer(buf, 3);
  1109. } else {
  1110. char buf[5];
  1111. buf[0] = static_cast<char>(0xdbu); _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
  1112. append_buffer(buf, 5);
  1113. }
  1114. return *this;
  1115. }
  1116. template <typename Stream>
  1117. inline packer<Stream>& packer<Stream>::pack_v4raw_body(const char* b, uint32_t l)
  1118. {
  1119. append_buffer(b, l);
  1120. return *this;
  1121. }
  1122. template <typename Stream>
  1123. inline packer<Stream>& packer<Stream>::pack_bin(uint32_t l)
  1124. {
  1125. if(l < 256) {
  1126. char buf[2];
  1127. buf[0] = static_cast<char>(0xc4u); buf[1] = static_cast<uint8_t>(l);
  1128. append_buffer(buf, 2);
  1129. } else if(l < 65536) {
  1130. char buf[3];
  1131. buf[0] = static_cast<char>(0xc5u); _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
  1132. append_buffer(buf, 3);
  1133. } else {
  1134. char buf[5];
  1135. buf[0] = static_cast<char>(0xc6u); _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
  1136. append_buffer(buf, 5);
  1137. }
  1138. return *this;
  1139. }
  1140. template <typename Stream>
  1141. inline packer<Stream>& packer<Stream>::pack_bin_body(const char* b, uint32_t l)
  1142. {
  1143. append_buffer(b, l);
  1144. return *this;
  1145. }
  1146. template <typename Stream>
  1147. inline packer<Stream>& packer<Stream>::pack_ext(size_t l, int8_t type)
  1148. {
  1149. switch(l) {
  1150. case 1: {
  1151. char buf[2];
  1152. buf[0] = static_cast<char>(0xd4u);
  1153. buf[1] = static_cast<char>(type);
  1154. append_buffer(buf, 2);
  1155. } break;
  1156. case 2: {
  1157. char buf[2];
  1158. buf[0] = static_cast<char>(0xd5u);
  1159. buf[1] = static_cast<char>(type);
  1160. append_buffer(buf, 2);
  1161. } break;
  1162. case 4: {
  1163. char buf[2];
  1164. buf[0] = static_cast<char>(0xd6u);
  1165. buf[1] = static_cast<char>(type);
  1166. append_buffer(buf, 2);
  1167. } break;
  1168. case 8: {
  1169. char buf[2];
  1170. buf[0] = static_cast<char>(0xd7u);
  1171. buf[1] = static_cast<char>(type);
  1172. append_buffer(buf, 2);
  1173. } break;
  1174. case 16: {
  1175. char buf[2];
  1176. buf[0] = static_cast<char>(0xd8u);
  1177. buf[1] = static_cast<char>(type);
  1178. append_buffer(buf, 2);
  1179. } break;
  1180. default:
  1181. if(l < 256) {
  1182. char buf[3];
  1183. buf[0] = static_cast<char>(0xc7u);
  1184. buf[1] = static_cast<char>(l);
  1185. buf[2] = static_cast<char>(type);
  1186. append_buffer(buf, 3);
  1187. } else if(l < 65536) {
  1188. char buf[4];
  1189. buf[0] = static_cast<char>(0xc8u);
  1190. _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
  1191. buf[3] = static_cast<char>(type);
  1192. append_buffer(buf, 4);
  1193. } else {
  1194. char buf[6];
  1195. buf[0] = static_cast<char>(0xc9u);
  1196. _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
  1197. buf[5] = static_cast<char>(type);
  1198. append_buffer(buf, 6);
  1199. }
  1200. break;
  1201. }
  1202. return *this;
  1203. }
  1204. template <typename Stream>
  1205. inline packer<Stream>& packer<Stream>::pack_ext_body(const char* b, uint32_t l)
  1206. {
  1207. append_buffer(b, l);
  1208. return *this;
  1209. }
  1210. template <typename Stream>
  1211. template <typename T>
  1212. inline void packer<Stream>::pack_imp_uint8(T d)
  1213. {
  1214. if(d < (1<<7)) {
  1215. /* fixnum */
  1216. char buf = take8_8(d);
  1217. append_buffer(&buf, 1);
  1218. } else {
  1219. /* unsigned 8 */
  1220. char buf[2] = {static_cast<char>(0xccu), take8_8(d)};
  1221. append_buffer(buf, 2);
  1222. }
  1223. }
  1224. template <typename Stream>
  1225. template <typename T>
  1226. inline void packer<Stream>::pack_imp_uint16(T d)
  1227. {
  1228. if(d < (1<<7)) {
  1229. /* fixnum */
  1230. char buf = take8_16(d);
  1231. append_buffer(&buf, 1);
  1232. } else if(d < (1<<8)) {
  1233. /* unsigned 8 */
  1234. char buf[2] = {static_cast<char>(0xccu), take8_16(d)};
  1235. append_buffer(buf, 2);
  1236. } else {
  1237. /* unsigned 16 */
  1238. char buf[3];
  1239. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1240. append_buffer(buf, 3);
  1241. }
  1242. }
  1243. template <typename Stream>
  1244. template <typename T>
  1245. inline void packer<Stream>::pack_imp_uint32(T d)
  1246. {
  1247. if(d < (1<<8)) {
  1248. if(d < (1<<7)) {
  1249. /* fixnum */
  1250. char buf = take8_32(d);
  1251. append_buffer(&buf, 1);
  1252. } else {
  1253. /* unsigned 8 */
  1254. char buf[2] = {static_cast<char>(0xccu), take8_32(d)};
  1255. append_buffer(buf, 2);
  1256. }
  1257. } else {
  1258. if(d < (1<<16)) {
  1259. /* unsigned 16 */
  1260. char buf[3];
  1261. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1262. append_buffer(buf, 3);
  1263. } else {
  1264. /* unsigned 32 */
  1265. char buf[5];
  1266. buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
  1267. append_buffer(buf, 5);
  1268. }
  1269. }
  1270. }
  1271. template <typename Stream>
  1272. template <typename T>
  1273. inline void packer<Stream>::pack_imp_uint64(T d)
  1274. {
  1275. if(d < (1ULL<<8)) {
  1276. if(d < (1ULL<<7)) {
  1277. /* fixnum */
  1278. char buf = take8_64(d);
  1279. append_buffer(&buf, 1);
  1280. } else {
  1281. /* unsigned 8 */
  1282. char buf[2] = {static_cast<char>(0xccu), take8_64(d)};
  1283. append_buffer(buf, 2);
  1284. }
  1285. } else {
  1286. if(d < (1ULL<<16)) {
  1287. /* unsigned 16 */
  1288. char buf[3];
  1289. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1290. append_buffer(buf, 3);
  1291. } else if(d < (1ULL<<32)) {
  1292. /* unsigned 32 */
  1293. char buf[5];
  1294. buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
  1295. append_buffer(buf, 5);
  1296. } else {
  1297. /* unsigned 64 */
  1298. char buf[9];
  1299. buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d);
  1300. append_buffer(buf, 9);
  1301. }
  1302. }
  1303. }
  1304. template <typename Stream>
  1305. template <typename T>
  1306. inline void packer<Stream>::pack_imp_int8(T d)
  1307. {
  1308. if(d < -(1<<5)) {
  1309. /* signed 8 */
  1310. char buf[2] = {static_cast<char>(0xd0u), take8_8(d)};
  1311. append_buffer(buf, 2);
  1312. } else {
  1313. /* fixnum */
  1314. char buf = take8_8(d);
  1315. append_buffer(&buf, 1);
  1316. }
  1317. }
  1318. template <typename Stream>
  1319. template <typename T>
  1320. inline void packer<Stream>::pack_imp_int16(T d)
  1321. {
  1322. if(d < -(1<<5)) {
  1323. if(d < -(1<<7)) {
  1324. /* signed 16 */
  1325. char buf[3];
  1326. buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d));
  1327. append_buffer(buf, 3);
  1328. } else {
  1329. /* signed 8 */
  1330. char buf[2] = {static_cast<char>(0xd0u), take8_16(d)};
  1331. append_buffer(buf, 2);
  1332. }
  1333. } else if(d < (1<<7)) {
  1334. /* fixnum */
  1335. char buf = take8_16(d);
  1336. append_buffer(&buf, 1);
  1337. } else {
  1338. if(d < (1<<8)) {
  1339. /* unsigned 8 */
  1340. char buf[2] = {static_cast<char>(0xccu), take8_16(d)};
  1341. append_buffer(buf, 2);
  1342. } else {
  1343. /* unsigned 16 */
  1344. char buf[3];
  1345. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1346. append_buffer(buf, 3);
  1347. }
  1348. }
  1349. }
  1350. template <typename Stream>
  1351. template <typename T>
  1352. inline void packer<Stream>::pack_imp_int32(T d)
  1353. {
  1354. if(d < -(1<<5)) {
  1355. if(d < -(1<<15)) {
  1356. /* signed 32 */
  1357. char buf[5];
  1358. buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], static_cast<int32_t>(d));
  1359. append_buffer(buf, 5);
  1360. } else if(d < -(1<<7)) {
  1361. /* signed 16 */
  1362. char buf[3];
  1363. buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d));
  1364. append_buffer(buf, 3);
  1365. } else {
  1366. /* signed 8 */
  1367. char buf[2] = { static_cast<char>(0xd0u), take8_32(d)};
  1368. append_buffer(buf, 2);
  1369. }
  1370. } else if(d < (1<<7)) {
  1371. /* fixnum */
  1372. char buf = take8_32(d);
  1373. append_buffer(&buf, 1);
  1374. } else {
  1375. if(d < (1<<8)) {
  1376. /* unsigned 8 */
  1377. char buf[2] = { static_cast<char>(0xccu), take8_32(d)};
  1378. append_buffer(buf, 2);
  1379. } else if(d < (1<<16)) {
  1380. /* unsigned 16 */
  1381. char buf[3];
  1382. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1383. append_buffer(buf, 3);
  1384. } else {
  1385. /* unsigned 32 */
  1386. char buf[5];
  1387. buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
  1388. append_buffer(buf, 5);
  1389. }
  1390. }
  1391. }
  1392. template <typename Stream>
  1393. template <typename T>
  1394. inline void packer<Stream>::pack_imp_int64(T d)
  1395. {
  1396. if(d < -(1LL<<5)) {
  1397. if(d < -(1LL<<15)) {
  1398. if(d < -(1LL<<31)) {
  1399. /* signed 64 */
  1400. char buf[9];
  1401. buf[0] = static_cast<char>(0xd3u); _msgpack_store64(&buf[1], d);
  1402. append_buffer(buf, 9);
  1403. } else {
  1404. /* signed 32 */
  1405. char buf[5];
  1406. buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], static_cast<int32_t>(d));
  1407. append_buffer(buf, 5);
  1408. }
  1409. } else {
  1410. if(d < -(1<<7)) {
  1411. /* signed 16 */
  1412. char buf[3];
  1413. buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d));
  1414. append_buffer(buf, 3);
  1415. } else {
  1416. /* signed 8 */
  1417. char buf[2] = {static_cast<char>(0xd0u), take8_64(d)};
  1418. append_buffer(buf, 2);
  1419. }
  1420. }
  1421. } else if(d < (1<<7)) {
  1422. /* fixnum */
  1423. char buf = take8_64(d);
  1424. append_buffer(&buf, 1);
  1425. } else {
  1426. if(d < (1LL<<16)) {
  1427. if(d < (1<<8)) {
  1428. /* unsigned 8 */
  1429. char buf[2] = {static_cast<char>(0xccu), take8_64(d)};
  1430. append_buffer(buf, 2);
  1431. } else {
  1432. /* unsigned 16 */
  1433. char buf[3];
  1434. buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
  1435. append_buffer(buf, 3);
  1436. }
  1437. } else {
  1438. if(d < (1LL<<32)) {
  1439. /* unsigned 32 */
  1440. char buf[5];
  1441. buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
  1442. append_buffer(buf, 5);
  1443. } else {
  1444. /* unsigned 64 */
  1445. char buf[9];
  1446. buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d);
  1447. append_buffer(buf, 9);
  1448. }
  1449. }
  1450. }
  1451. }
  1452. /// @cond
  1453. } // MSGPACK_API_VERSION_NAMESPACE(v1)
  1454. /// @endcond
  1455. } // namespace msgpack
  1456. #endif // MSGPACK_V1_PACK_HPP