Coverage Report

Created: 2026-09-11 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/msgpack-c/include/msgpack/v1/pack.hpp
Line
Count
Source
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
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
2.63M
    {
623
2.63M
        append_buffer(&Stream::write, buf, len);
624
2.63M
    }
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
2.63M
    {
629
2.63M
        m_stream.write(buf, static_cast<SizeType>(len));
630
2.63M
    }
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
1.09k
{
675
1.09k
    packer<Stream>(s).pack(v);
676
1.09k
}
677
678
679
#if MSGPACK_ENDIAN_LITTLE_BYTE
680
template <typename T>
681
582k
inline char take8_8(T d) {
682
582k
    return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
683
582k
}
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
1.08M
inline char take8_64(T d) {
694
1.08M
    return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
695
1.08M
}
char msgpack::v1::take8_64<unsigned long>(unsigned long)
Line
Count
Source
693
837k
inline char take8_64(T d) {
694
837k
    return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
695
837k
}
char msgpack::v1::take8_64<long>(long)
Line
Count
Source
693
246k
inline char take8_64(T d) {
694
246k
    return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]);
695
246k
}
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
1.09k
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
851k
{ 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
280k
{ 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
443k
{
1141
443k
    union { float f; uint32_t i; } mem;
1142
443k
    mem.f = d;
1143
443k
    char buf[5];
1144
443k
    buf[0] = static_cast<char>(0xcau); _msgpack_store32(&buf[1], mem.i);
1145
443k
    append_buffer(buf, 5);
1146
443k
    return *this;
1147
443k
}
1148
1149
template <typename Stream>
1150
inline packer<Stream>& packer<Stream>::pack_double(double d)
1151
11.1k
{
1152
11.1k
    union { double f; uint64_t i; } mem;
1153
11.1k
    mem.f = d;
1154
11.1k
    char buf[9];
1155
11.1k
    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
11.1k
    _msgpack_store64(&buf[1], mem.i);
1164
11.1k
    append_buffer(buf, 9);
1165
11.1k
    return *this;
1166
11.1k
}
1167
1168
1169
template <typename Stream>
1170
inline packer<Stream>& packer<Stream>::pack_nil()
1171
46.1k
{
1172
46.1k
    const char d = static_cast<char>(0xc0u);
1173
46.1k
    append_buffer(&d, 1);
1174
46.1k
    return *this;
1175
46.1k
}
1176
1177
template <typename Stream>
1178
inline packer<Stream>& packer<Stream>::pack_true()
1179
6.51k
{
1180
6.51k
    const char d = static_cast<char>(0xc3u);
1181
6.51k
    append_buffer(&d, 1);
1182
6.51k
    return *this;
1183
6.51k
}
1184
1185
template <typename Stream>
1186
inline packer<Stream>& packer<Stream>::pack_false()
1187
35.6k
{
1188
35.6k
    const char d = static_cast<char>(0xc2u);
1189
35.6k
    append_buffer(&d, 1);
1190
35.6k
    return *this;
1191
35.6k
}
1192
1193
1194
template <typename Stream>
1195
inline packer<Stream>& packer<Stream>::pack_array(uint32_t n)
1196
89.2k
{
1197
89.2k
    if(n < 16) {
1198
75.1k
        char d = static_cast<char>(0x90u | n);
1199
75.1k
        append_buffer(&d, 1);
1200
75.1k
    } else if(n < 65536) {
1201
14.1k
        char buf[3];
1202
14.1k
        buf[0] = static_cast<char>(0xdcu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n));
1203
14.1k
        append_buffer(buf, 3);
1204
14.1k
    } else {
1205
0
        char buf[5];
1206
0
        buf[0] = static_cast<char>(0xddu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n));
1207
0
        append_buffer(buf, 5);
1208
0
    }
1209
89.2k
    return *this;
1210
89.2k
}
1211
1212
template <typename Stream>
1213
inline packer<Stream>& packer<Stream>::pack_map(uint32_t n)
1214
400k
{
1215
400k
    if(n < 16) {
1216
397k
        unsigned char d = static_cast<unsigned char>(0x80u | n);
1217
397k
        char buf = take8_8(d);
1218
397k
        append_buffer(&buf, 1);
1219
397k
    } else if(n < 65536) {
1220
2.95k
        char buf[3];
1221
2.95k
        buf[0] = static_cast<char>(0xdeu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n));
1222
2.95k
        append_buffer(buf, 3);
1223
2.95k
    } else {
1224
0
        char buf[5];
1225
0
        buf[0] = static_cast<char>(0xdfu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n));
1226
0
        append_buffer(buf, 5);
1227
0
    }
1228
400k
    return *this;
1229
400k
}
1230
1231
template <typename Stream>
1232
inline packer<Stream>& packer<Stream>::pack_str(uint32_t l)
1233
188k
{
1234
188k
    if(l < 32) {
1235
185k
        unsigned char d = static_cast<uint8_t>(0xa0u | l);
1236
185k
        char buf = take8_8(d);
1237
185k
        append_buffer(&buf, 1);
1238
185k
    } else if(l < 256) {
1239
1.62k
        char buf[2];
1240
1.62k
        buf[0] = static_cast<char>(0xd9u); buf[1] = static_cast<char>(l);
1241
1.62k
        append_buffer(buf, 2);
1242
1.88k
    } else if(l < 65536) {
1243
1.88k
        char buf[3];
1244
1.88k
        buf[0] = static_cast<char>(0xdau); _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
1245
1.88k
        append_buffer(buf, 3);
1246
1.88k
    } else {
1247
0
        char buf[5];
1248
0
        buf[0] = static_cast<char>(0xdbu); _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
1249
0
        append_buffer(buf, 5);
1250
0
    }
1251
188k
    return *this;
1252
188k
}
1253
1254
template <typename Stream>
1255
inline packer<Stream>& packer<Stream>::pack_str_body(const char* b, uint32_t l)
1256
188k
{
1257
188k
    append_buffer(b, l);
1258
188k
    return *this;
1259
188k
}
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
5.98k
{
1292
5.98k
    if(l < 256) {
1293
4.87k
        char buf[2];
1294
4.87k
        buf[0] = static_cast<char>(0xc4u); buf[1] = static_cast<char>(l);
1295
4.87k
        append_buffer(buf, 2);
1296
4.87k
    } else if(l < 65536) {
1297
1.10k
        char buf[3];
1298
1.10k
        buf[0] = static_cast<char>(0xc5u); _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
1299
1.10k
        append_buffer(buf, 3);
1300
1.10k
    } else {
1301
0
        char buf[5];
1302
0
        buf[0] = static_cast<char>(0xc6u); _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
1303
0
        append_buffer(buf, 5);
1304
0
    }
1305
5.98k
    return *this;
1306
5.98k
}
1307
1308
template <typename Stream>
1309
inline packer<Stream>& packer<Stream>::pack_bin_body(const char* b, uint32_t l)
1310
5.98k
{
1311
5.98k
    append_buffer(b, l);
1312
5.98k
    return *this;
1313
5.98k
}
1314
1315
template <typename Stream>
1316
inline packer<Stream>& packer<Stream>::pack_ext(size_t l, int8_t type)
1317
41.8k
{
1318
41.8k
    switch(l) {
1319
6.88k
    case 1: {
1320
6.88k
        char buf[2];
1321
6.88k
        buf[0] = static_cast<char>(0xd4u);
1322
6.88k
        buf[1] = static_cast<char>(type);
1323
6.88k
        append_buffer(buf, 2);
1324
6.88k
    } break;
1325
3.80k
    case 2: {
1326
3.80k
        char buf[2];
1327
3.80k
        buf[0] = static_cast<char>(0xd5u);
1328
3.80k
        buf[1] = static_cast<char>(type);
1329
3.80k
        append_buffer(buf, 2);
1330
3.80k
    } break;
1331
20.0k
    case 4: {
1332
20.0k
        char buf[2];
1333
20.0k
        buf[0] = static_cast<char>(0xd6u);
1334
20.0k
        buf[1] = static_cast<char>(type);
1335
20.0k
        append_buffer(buf, 2);
1336
20.0k
    } break;
1337
4.94k
    case 8: {
1338
4.94k
        char buf[2];
1339
4.94k
        buf[0] = static_cast<char>(0xd7u);
1340
4.94k
        buf[1] = static_cast<char>(type);
1341
4.94k
        append_buffer(buf, 2);
1342
4.94k
    } break;
1343
2.54k
    case 16: {
1344
2.54k
        char buf[2];
1345
2.54k
        buf[0] = static_cast<char>(0xd8u);
1346
2.54k
        buf[1] = static_cast<char>(type);
1347
2.54k
        append_buffer(buf, 2);
1348
2.54k
    } break;
1349
3.58k
    default:
1350
3.58k
        if(l < 256) {
1351
3.20k
            char buf[3];
1352
3.20k
            buf[0] = static_cast<char>(0xc7u);
1353
3.20k
            buf[1] = static_cast<char>(l);
1354
3.20k
            buf[2] = static_cast<char>(type);
1355
3.20k
            append_buffer(buf, 3);
1356
3.20k
        } else if(l < 65536) {
1357
379
            char buf[4];
1358
379
            buf[0] = static_cast<char>(0xc8u);
1359
379
            _msgpack_store16(&buf[1], static_cast<uint16_t>(l));
1360
379
            buf[3] = static_cast<char>(type);
1361
379
            append_buffer(buf, 4);
1362
379
        } else {
1363
0
            char buf[6];
1364
0
            buf[0] = static_cast<char>(0xc9u);
1365
0
            _msgpack_store32(&buf[1], static_cast<uint32_t>(l));
1366
0
            buf[5] = static_cast<char>(type);
1367
0
            append_buffer(buf, 6);
1368
0
        }
1369
3.58k
        break;
1370
41.8k
    }
1371
41.8k
    return *this;
1372
41.8k
}
1373
1374
template <typename Stream>
1375
inline packer<Stream>& packer<Stream>::pack_ext_body(const char* b, uint32_t l)
1376
41.8k
{
1377
41.8k
    append_buffer(b, l);
1378
41.8k
    return *this;
1379
41.8k
}
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
851k
{
1449
851k
    if(d < (1ULL<<8)) {
1450
837k
        if(d < (1ULL<<7)) {
1451
            /* fixnum */
1452
832k
            char buf = take8_64(d);
1453
832k
            append_buffer(&buf, 1);
1454
832k
        } else {
1455
            /* unsigned 8 */
1456
4.62k
            char buf[2] = {static_cast<char>(0xccu), take8_64(d)};
1457
4.62k
            append_buffer(buf, 2);
1458
4.62k
        }
1459
837k
    } else {
1460
14.0k
        if(d < (1ULL<<16)) {
1461
            /* unsigned 16 */
1462
5.27k
            char buf[3];
1463
5.27k
            buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
1464
5.27k
            append_buffer(buf, 3);
1465
8.78k
        } else if(d < (1ULL<<32)) {
1466
            /* unsigned 32 */
1467
6.15k
            char buf[5];
1468
6.15k
            buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
1469
6.15k
            append_buffer(buf, 5);
1470
6.15k
        } else {
1471
            /* unsigned 64 */
1472
2.63k
            char buf[9];
1473
2.63k
            buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d);
1474
2.63k
            append_buffer(buf, 9);
1475
2.63k
        }
1476
14.0k
    }
1477
851k
}
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
280k
{
1574
280k
    if(d < -(1LL<<5)) {
1575
78.0k
        if(d < -(1LL<<15)) {
1576
22.0k
            if(d < -(1LL<<31)) {
1577
                /* signed 64 */
1578
9.46k
                char buf[9];
1579
9.46k
                buf[0] = static_cast<char>(0xd3u); _msgpack_store64(&buf[1], d);
1580
9.46k
                append_buffer(buf, 9);
1581
12.5k
            } else {
1582
                /* signed 32 */
1583
12.5k
                char buf[5];
1584
12.5k
                buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], static_cast<int32_t>(d));
1585
12.5k
                append_buffer(buf, 5);
1586
12.5k
            }
1587
56.0k
        } else {
1588
56.0k
            if(d < -(1<<7)) {
1589
                /* signed 16 */
1590
11.7k
                char buf[3];
1591
11.7k
                buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d));
1592
11.7k
                append_buffer(buf, 3);
1593
44.2k
            } else {
1594
                /* signed 8 */
1595
44.2k
                char buf[2] = {static_cast<char>(0xd0u), take8_64(d)};
1596
44.2k
                append_buffer(buf, 2);
1597
44.2k
            }
1598
56.0k
        }
1599
202k
    } else if(d < (1<<7)) {
1600
        /* fixnum */
1601
202k
        char buf = take8_64(d);
1602
202k
        append_buffer(&buf, 1);
1603
202k
    } else {
1604
0
        if(d < (1LL<<16)) {
1605
0
            if(d < (1<<8)) {
1606
                /* unsigned 8 */
1607
0
                char buf[2] = {static_cast<char>(0xccu), take8_64(d)};
1608
0
                append_buffer(buf, 2);
1609
0
            } else {
1610
                /* unsigned 16 */
1611
0
                char buf[3];
1612
0
                buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d));
1613
0
                append_buffer(buf, 3);
1614
0
            }
1615
0
        } else {
1616
0
            if(d < (1LL<<32)) {
1617
                /* unsigned 32 */
1618
0
                char buf[5];
1619
0
                buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d));
1620
0
                append_buffer(buf, 5);
1621
0
            } else {
1622
                /* unsigned 64 */
1623
0
                char buf[9];
1624
                buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d);
1625
0
                append_buffer(buf, 9);
1626
0
            }
1627
0
        }
1628
0
    }
1629
280k
}
1630
1631
/// @cond
1632
}  // MSGPACK_API_VERSION_NAMESPACE(v1)
1633
/// @endcond
1634
1635
}  // namespace msgpack
1636
1637
#endif // MSGPACK_V1_PACK_HPP