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