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