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