messagepack implementation for embedded systems (mbed / arduino)
Dependents: hello_message_pack
pack.hpp
00001 // 00002 // MessagePack for C++ serializing routine 00003 // 00004 // Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // (See accompanying file LICENSE_1_0.txt or copy at 00008 // http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 #ifndef MSGPACK_PACK_HPP 00011 #define MSGPACK_PACK_HPP 00012 00013 #include "msgpack/versioning.hpp" 00014 #include "msgpack/cpp_config.hpp" 00015 00016 #include <stdexcept> 00017 #include <limits> 00018 #include <cstring> 00019 #include <climits> 00020 00021 #include "../sysdep.h" 00022 00023 namespace msgpack { 00024 00025 /// @cond 00026 MSGPACK_API_VERSION_NAMESPACE(v1) { 00027 /// @endcond 00028 00029 /// The class template that supports continuous packing. 00030 /** 00031 * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)` 00032 * 00033 */ 00034 template <typename Stream> 00035 class packer { 00036 public: 00037 /// Constructor 00038 /** 00039 * This constructor is left for compatibility. 00040 * Use `packer(Stream* s)` instead of the constructor. 00041 * 00042 * @param s A pointer to packing destination stream object. 00043 */ 00044 packer (Stream* s); 00045 /// Constructor 00046 /** 00047 * @param s Packing destination stream object. 00048 */ 00049 packer (Stream& s); 00050 00051 public: 00052 /// Packing function template 00053 /** 00054 * @tparam T The type of packing object. 00055 * 00056 * @param v a packing object. 00057 * 00058 * @return The reference of `*this`. 00059 */ 00060 template <typename T> 00061 packer<Stream> & pack(const T& v); 00062 00063 /// Packing uint8 00064 /** 00065 * The byte size of the packed data depends on `d`. 00066 * The packed type is positive fixnum or uint8. 00067 * The minimum byte size expression is used. 00068 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00069 * 00070 * @param d a packing object. 00071 * 00072 * @return The reference of `*this`. 00073 */ 00074 packer<Stream> & pack_uint8(uint8_t d); 00075 00076 /// Packing uint16 00077 /** 00078 * The byte size of the packed data depends on `d`. 00079 * The packed type is positive fixnum, uint8 or uint16. 00080 * The minimum byte size expression is used. 00081 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00082 * 00083 * @param d a packing object. 00084 * 00085 * @return The reference of `*this`. 00086 */ 00087 packer<Stream> & pack_uint16(uint16_t d); 00088 00089 /// Packing uint32 00090 /** 00091 * The byte size of the packed data depends on `d`. 00092 * The packed type is positive fixnum, uint8, uint16 or uint32. 00093 * The minimum byte size expression is used. 00094 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00095 * 00096 * @param d a packing object. 00097 * 00098 * @return The reference of `*this`. 00099 */ 00100 packer<Stream> & pack_uint32(uint32_t d); 00101 00102 /// Packing uint16 00103 /** 00104 * The byte size of the packed data depends on `d`. 00105 * The packed type is positive fixnum, uint8, uint16, uint32 or uint64. 00106 * The minimum byte size expression is used. 00107 * positive fixnum, uint8, uint16, or uint32 is used. 00108 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00109 * 00110 * @param d a packing object. 00111 * 00112 * @return The reference of `*this`. 00113 */ 00114 packer<Stream> & pack_uint64(uint64_t d); 00115 00116 /// Packing int8 00117 /** 00118 * The byte size of the packed data depends on `d`. 00119 * If `d` is zero or positive, the packed type is positive fixnum, or uint8, 00120 * else the packed type is negative fixnum, or int8 00121 * The minimum byte size expression is used. 00122 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00123 * 00124 * @param d a packing object. 00125 * 00126 * @return The reference of `*this`. 00127 */ 00128 packer<Stream> & pack_int8(int8_t d); 00129 00130 /// Packing int16 00131 /** 00132 * The byte size of the packed data depends on `d`. 00133 * If `d` is zero or positive, the packed type is positive fixnum, uint8, or uint16, 00134 * else the packed type is negative fixnum, int8, or int16. 00135 * The minimum byte size expression is used. 00136 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00137 * 00138 * @param d a packing object. 00139 * 00140 * @return The reference of `*this`. 00141 */ 00142 packer<Stream> & pack_int16(int16_t d); 00143 00144 /// Packing int32 00145 /** 00146 * The byte size of the packed data depends on `d`. 00147 * If `d` is zero or positive, the packed type is positive fixnum, uint8, uint16, or uint32, 00148 * else the packed type is negative fixnum, int8, int16, or int32. 00149 * The minimum byte size expression is used. 00150 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00151 * 00152 * @param d a packing object. 00153 * 00154 * @return The reference of `*this`. 00155 */ 00156 packer<Stream> & pack_int32(int32_t d); 00157 00158 /// Packing int32 00159 /** 00160 * The byte size of the packed data depends on `d`. 00161 * If `d` is zero or positive, the packed type is positive fixnum, uint8, uint16, uint32, or uint64, 00162 * else the packed type is negative fixnum, int8, int16, int32, or int64. 00163 * The minimum byte size expression is used. 00164 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00165 * 00166 * @param d a packing object. 00167 * 00168 * @return The reference of `*this`. 00169 */ 00170 packer<Stream> & pack_int64(int64_t d); 00171 00172 00173 00174 /// Packing uint8 (fixed packed type). 00175 /** 00176 * The packed type is always uint8. 00177 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00178 * 00179 * @param d a packing object. 00180 * 00181 * @return The reference of `*this`. 00182 */ 00183 packer<Stream> & pack_fix_uint8(uint8_t d); 00184 00185 /// Packing uint8 (fixed packed type). 00186 /** 00187 * The packed type is always uint16. 00188 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00189 * 00190 * @param d a packing object. 00191 * 00192 * @return The reference of `*this`. 00193 */ 00194 packer<Stream> & pack_fix_uint16(uint16_t d); 00195 00196 /// Packing uint8 (fixed packed type). 00197 /** 00198 * The packed type is always uint32. 00199 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00200 * 00201 * @param d a packing object. 00202 * 00203 * @return The reference of `*this`. 00204 */ 00205 packer<Stream> & pack_fix_uint32(uint32_t d); 00206 00207 /// Packing uint8 (fixed packed type). 00208 /** 00209 * The packed type is always uint64. 00210 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00211 * 00212 * @param d a packing object. 00213 * 00214 * @return The reference of `*this`. 00215 */ 00216 packer<Stream> & pack_fix_uint64(uint64_t d); 00217 00218 /// Packing uint8 (fixed packed type). 00219 /** 00220 * The packed type is always int8. 00221 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00222 * 00223 * @param d a packing object. 00224 * 00225 * @return The reference of `*this`. 00226 */ 00227 packer<Stream> & pack_fix_int8(int8_t d); 00228 00229 /// Packing uint8 (fixed packed type). 00230 /** 00231 * The packed type is always int16. 00232 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00233 * 00234 * @param d a packing object. 00235 * 00236 * @return The reference of `*this`. 00237 */ 00238 packer<Stream> & pack_fix_int16(int16_t d); 00239 00240 /// Packing uint8 (fixed packed type). 00241 /** 00242 * The packed type is always int32. 00243 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00244 * 00245 * @param d a packing object. 00246 * 00247 * @return The reference of `*this`. 00248 */ 00249 packer<Stream> & pack_fix_int32(int32_t d); 00250 00251 /// Packing uint8 (fixed packed type). 00252 /** 00253 * The packed type is always int64. 00254 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00255 * 00256 * @param d a packing object. 00257 * 00258 * @return The reference of `*this`. 00259 */ 00260 packer<Stream> & pack_fix_int64(int64_t d); 00261 00262 00263 /// Packing char 00264 /** 00265 * The byte size of the packed data depends on `d`. 00266 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00267 * else the packed type is negative fixnum, or int* 00268 * The minimum byte size expression is used. 00269 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00270 * 00271 * @param d a packing object. 00272 * 00273 * @return The reference of `*this`. 00274 */ 00275 packer<Stream> & pack_char(char d); 00276 00277 /// Packing signed char 00278 /** 00279 * The byte size of the packed data depends on `d`. 00280 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00281 * else the packed type is negative fixnum, or int* 00282 * The minimum byte size expression is used. 00283 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00284 * 00285 * @param d a packing object. 00286 * 00287 * @return The reference of `*this`. 00288 */ 00289 packer<Stream> & pack_signed_char(signed char d); 00290 00291 /// Packing short 00292 /** 00293 * The byte size of the packed data depends on `d`. 00294 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00295 * else the packed type is negative fixnum, or int* 00296 * The minimum byte size expression is used. 00297 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00298 * 00299 * @param d a packing object. 00300 * 00301 * @return The reference of `*this`. 00302 */ 00303 packer<Stream> & pack_short(short d); 00304 00305 /// Packing int 00306 /** 00307 * The byte size of the packed data depends on `d`. 00308 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00309 * else the packed type is negative fixnum, or int* 00310 * The minimum byte size expression is used. 00311 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00312 * 00313 * @param d a packing object. 00314 * 00315 * @return The reference of `*this`. 00316 */ 00317 packer<Stream> & pack_int(int d); 00318 00319 /// Packing long 00320 /** 00321 * The byte size of the packed data depends on `d`. 00322 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00323 * else the packed type is negative fixnum, or int* 00324 * The minimum byte size expression is used. 00325 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00326 * 00327 * @param d a packing object. 00328 * 00329 * @return The reference of `*this`. 00330 */ 00331 packer<Stream> & pack_long(long d); 00332 00333 /// Packing long long 00334 /** 00335 * The byte size of the packed data depends on `d`. 00336 * If `d` is zero or positive, the packed type is positive fixnum, or uint*, 00337 * else the packed type is negative fixnum, or int* 00338 * The minimum byte size expression is used. 00339 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00340 * 00341 * @param d a packing object. 00342 * 00343 * @return The reference of `*this`. 00344 */ 00345 packer<Stream> & pack_long_long(long long d); 00346 00347 00348 /// Packing unsigned char 00349 /** 00350 * The byte size of the packed data depends on `d`. 00351 * The packed type is positive fixnum, or uint*. 00352 * The minimum byte size expression is used. 00353 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00354 * 00355 * @param d a packing object. 00356 * 00357 * @return The reference of `*this`. 00358 */ 00359 packer<Stream> & pack_unsigned_char(unsigned char d); 00360 00361 /// Packing unsigned short 00362 /** 00363 * The byte size of the packed data depends on `d`. 00364 * The packed type is positive fixnum, or uint*. 00365 * The minimum byte size expression is used. 00366 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00367 * 00368 * @param d a packing object. 00369 * 00370 * @return The reference of `*this`. 00371 */ 00372 packer<Stream> & pack_unsigned_short(unsigned short d); 00373 00374 /// Packing unsigned int 00375 /** 00376 * The byte size of the packed data depends on `d`. 00377 * The packed type is positive fixnum, or uint*. 00378 * The minimum byte size expression is used. 00379 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00380 * 00381 * @param d a packing object. 00382 * 00383 * @return The reference of `*this`. 00384 */ 00385 packer<Stream> & pack_unsigned_int(unsigned int d); 00386 00387 /// Packing unsigned long 00388 /** 00389 * The byte size of the packed data depends on `d`. 00390 * The packed type is positive fixnum, or uint*. 00391 * The minimum byte size expression is used. 00392 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00393 * 00394 * @param d a packing object. 00395 * 00396 * @return The reference of `*this`. 00397 */ 00398 packer<Stream> & pack_unsigned_long(unsigned long d); 00399 00400 /// Packing unsigned long long 00401 /** 00402 * The byte size of the packed data depends on `d`. 00403 * The packed type is positive fixnum, or uint*. 00404 * The minimum byte size expression is used. 00405 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int 00406 * 00407 * @param d a packing object. 00408 * 00409 * @return The reference of `*this`. 00410 */ 00411 packer<Stream> & pack_unsigned_long_long(unsigned long long d); 00412 00413 /// Packing float 00414 /** 00415 * The packed type is float32. 00416 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-float 00417 * 00418 * @param d a packing object. 00419 * 00420 * @return The reference of `*this`. 00421 */ 00422 packer<Stream> & pack_float(float d); 00423 00424 /// Packing double 00425 /** 00426 * The packed type is float64. 00427 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-float 00428 * 00429 * @param d a packing object. 00430 * 00431 * @return The reference of `*this`. 00432 */ 00433 packer<Stream> & pack_double(double d); 00434 00435 00436 /// Packing nil 00437 /** 00438 * The packed type is nil. 00439 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-nil 00440 * 00441 * @return The reference of `*this`. 00442 */ 00443 packer<Stream> & pack_nil(); 00444 00445 /// Packing true 00446 /** 00447 * The packed type is bool, value is true. 00448 * See https://github.com/msgpack/msgpack/blob/master/spec.md#bool-format-family 00449 * 00450 * @return The reference of `*this`. 00451 */ 00452 packer<Stream> & pack_true(); 00453 00454 /// Packing false 00455 /** 00456 * The packed type is bool, value is false. 00457 * See https://github.com/msgpack/msgpack/blob/master/spec.md#bool-format-family 00458 * 00459 * @return The reference of `*this`. 00460 */ 00461 packer<Stream> & pack_false(); 00462 00463 /// Packing array header and size 00464 /** 00465 * The packed type is array header and array size. 00466 * You need to pack `n` msgpack objects following this header and size. 00467 * See https://github.com/msgpack/msgpack/blob/master/spec.md#array-format-family 00468 * 00469 * @param n The number of array elements (array size). 00470 * 00471 * @return The reference of `*this`. 00472 */ 00473 packer<Stream> & pack_array(uint32_t n); 00474 00475 /// Packing map header and size 00476 /** 00477 * The packed type is map header and map size. 00478 * You need to pack `n` pairs of msgpack objects following this header and size. 00479 * See https://github.com/msgpack/msgpack/blob/master/spec.md#map-format-family 00480 * 00481 * @param n The number of array elements (array size). 00482 * 00483 * @return The reference of `*this`. 00484 */ 00485 packer<Stream> & pack_map(uint32_t n); 00486 00487 00488 /// Packing str header and length 00489 /** 00490 * The packed type is str header and length. 00491 * The minimum byte size length expression is used. 00492 * You need to call `pack_str_body(const char* b, uint32_t l)` after this function calling with the same `l` value. 00493 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str 00494 * 00495 * @param l The length of string. 00496 * 00497 * @return The reference of `*this`. 00498 */ 00499 packer<Stream> & pack_str(uint32_t l); 00500 00501 /// Packing str body 00502 /** 00503 * You need to call this function just after `pack_str(uint32_t l)` calling. 00504 * The value `l` should be the same as `pack_str(uint32_t l)` argument `l`. 00505 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str 00506 * 00507 * @param l The length of string. 00508 * 00509 * @return The reference of `*this`. 00510 */ 00511 packer<Stream> & pack_str_body(const char* b, uint32_t l); 00512 00513 /// Packing raw (v4) header and length 00514 /** 00515 * The packed type is raw header and length. 00516 * The minimum byte size length expression is used. 00517 * The format raw (v4) is old MessagePack version4 format. 00518 * You need to call `pack_v4raw_body(const char* b, uint32_t l)` after this function calling with the same `l` value. 00519 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str 00520 * 00521 * @param l The length of string. 00522 * 00523 * @return The reference of `*this`. 00524 */ 00525 packer<Stream> & pack_v4raw(uint32_t l); 00526 00527 /// Packing raw (v4) body 00528 /** 00529 * The format raw (v4) is old MessagePack version4 format. 00530 * You need to call this function just after `pack_v4raw(uint32_t l)` calling. 00531 * The value `l` should be the same as `pack_v4raw(uint32_t l)` argument `l`. 00532 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str 00533 * 00534 * @param l The length of string. 00535 * 00536 * @return The reference of `*this`. 00537 */ 00538 packer<Stream> & pack_v4raw_body(const char* b, uint32_t l); 00539 00540 /// Packing bin header and length 00541 /** 00542 * The packed type is bin header and length. 00543 * The minimum byte size length expression is used. 00544 * You need to call `pack_bin_body(const char* b, uint32_t l)` after this function calling with the same `l` value. 00545 * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family 00546 * 00547 * @param l The length of string. 00548 * 00549 * @return The reference of `*this`. 00550 */ 00551 packer<Stream> & pack_bin(uint32_t l); 00552 00553 /// Packing bin body 00554 /** 00555 * You need to call this function just after `pack_bin(uint32_t l)` calling. 00556 * The value `l` should be the same as `pack_bin(uint32_t l)` argument `l`. 00557 * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family 00558 * 00559 * @param l The length of string. 00560 * 00561 * @return The reference of `*this`. 00562 */ 00563 packer<Stream> & pack_bin_body(const char* b, uint32_t l); 00564 00565 /// Packing ext header, type, and length 00566 /** 00567 * The packed type is ext. 00568 * The minimum byte size length expression is used. 00569 * The length 1, 2, 4, 8, and 16 can be encoded in the header. 00570 * You need to call `pack_ext_body(const char* b, uint32_t l)` after this function calling with the same `l` value. 00571 * See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-ext 00572 * 00573 * @param l The length of string. 00574 * 00575 * @return The reference of `*this`. 00576 */ 00577 packer<Stream> & pack_ext(size_t l, int8_t type); 00578 00579 /// Packing ext body 00580 /** 00581 * You need to call this function just after `pack_ext(size_t l, int8_t type)` calling. 00582 * The value `l` should be the same as `pack_ext(size_t l, int8_t type)` argument `l`. 00583 * See https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family 00584 * 00585 * @param l The length of string. 00586 * 00587 * @return The reference of `*this`. 00588 */ 00589 packer<Stream> & pack_ext_body(const char* b, uint32_t l); 00590 00591 private: 00592 template <typename T> 00593 void pack_imp_uint8(T d); 00594 template <typename T> 00595 void pack_imp_uint16(T d); 00596 template <typename T> 00597 void pack_imp_uint32(T d); 00598 template <typename T> 00599 void pack_imp_uint64(T d); 00600 template <typename T> 00601 void pack_imp_int8(T d); 00602 template <typename T> 00603 void pack_imp_int16(T d); 00604 template <typename T> 00605 void pack_imp_int32(T d); 00606 template <typename T> 00607 void pack_imp_int64(T d); 00608 00609 void append_buffer(const char* buf, size_t len) 00610 { m_stream.write(buf, len); } 00611 00612 private: 00613 Stream& m_stream; 00614 00615 #if defined(MSGPACK_USE_CPP03) 00616 private: 00617 packer (const packer &); 00618 packer & operator=(const packer &); 00619 packer (); 00620 #else // defined(MSGPACK_USE_CPP03) 00621 public: 00622 packer (const packer &) = delete; 00623 packer & operator=(const packer &) = delete; 00624 packer () = delete; 00625 #endif // defined(MSGPACK_USE_CPP03) 00626 }; 00627 00628 00629 /// Pack the value as MessagePack format into the stream 00630 /** 00631 * This function template is left for compatibility. 00632 * Use `void pack(Stream& s, const T& v)` instead of the function template. 00633 * 00634 * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)` 00635 * @tparam T Any type that is adapted to MessagePack 00636 * @param s The pointer to packing destination stream 00637 * @param v Packing value 00638 */ 00639 template <typename Stream, typename T> 00640 inline void pack(Stream* s, const T& v) 00641 { 00642 packer<Stream> (*s).pack(v); 00643 } 00644 00645 /// Pack the value as MessagePack format into the stream 00646 /** 00647 * @tparam Stream Any type that have a member function `Stream write(const char*, size_t s)` 00648 * @tparam T Any type that is adapted to MessagePack 00649 * @param s Packing destination stream 00650 * @param v Packing value 00651 */ 00652 template <typename Stream, typename T> 00653 inline void pack(Stream& s, const T& v) 00654 { 00655 packer<Stream>(s).pack(v); 00656 } 00657 00658 00659 #if MSGPACK_ENDIAN_LITTLE_BYTE 00660 template <typename T> 00661 inline char take8_8(T d) { 00662 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]); 00663 } 00664 template <typename T> 00665 inline char take8_16(T d) { 00666 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]); 00667 } 00668 template <typename T> 00669 inline char take8_32(T d) { 00670 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]); 00671 } 00672 template <typename T> 00673 inline char take8_64(T d) { 00674 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]); 00675 } 00676 00677 #elif MSGPACK_ENDIAN_BIG_BYTE 00678 00679 template <typename T> 00680 inline char take8_8(T d) { 00681 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[0]); 00682 } 00683 template <typename T> 00684 inline char take8_16(T d) { 00685 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[1]); 00686 } 00687 template <typename T> 00688 inline char take8_32(T d) { 00689 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[3]); 00690 } 00691 template <typename T> 00692 inline char take8_64(T d) { 00693 return static_cast<char>(reinterpret_cast<uint8_t*>(&d)[7]); 00694 } 00695 00696 #else 00697 #error msgpack-c supports only big endian and little endian 00698 #endif 00699 00700 template <typename Stream> 00701 inline packer<Stream>::packer (Stream* s) : m_stream(*s) { } 00702 00703 template <typename Stream> 00704 inline packer<Stream>::packer (Stream& s) : m_stream(s) { } 00705 00706 00707 template <typename Stream> 00708 inline packer<Stream> & packer<Stream>::pack_uint8(uint8_t d) 00709 { pack_imp_uint8(d); return *this; } 00710 00711 template <typename Stream> 00712 inline packer<Stream> & packer<Stream>::pack_uint16(uint16_t d) 00713 { pack_imp_uint16(d); return *this; } 00714 00715 template <typename Stream> 00716 inline packer<Stream> & packer<Stream>::pack_uint32(uint32_t d) 00717 { pack_imp_uint32(d); return *this; } 00718 00719 template <typename Stream> 00720 inline packer<Stream> & packer<Stream>::pack_uint64(uint64_t d) 00721 { pack_imp_uint64(d); return *this; } 00722 00723 template <typename Stream> 00724 inline packer<Stream> & packer<Stream>::pack_int8(int8_t d) 00725 { pack_imp_int8(d); return *this; } 00726 00727 template <typename Stream> 00728 inline packer<Stream> & packer<Stream>::pack_int16(int16_t d) 00729 { pack_imp_int16(d); return *this; } 00730 00731 template <typename Stream> 00732 inline packer<Stream> & packer<Stream>::pack_int32(int32_t d) 00733 { pack_imp_int32(d); return *this; } 00734 00735 template <typename Stream> 00736 inline packer<Stream> & packer<Stream>::pack_int64(int64_t d) 00737 { pack_imp_int64(d); return *this;} 00738 00739 00740 template <typename Stream> 00741 inline packer<Stream> & packer<Stream>::pack_fix_uint8(uint8_t d) 00742 { 00743 char buf[2] = {static_cast<char>(0xccu), take8_8(d)}; 00744 append_buffer(buf, 2); 00745 return *this; 00746 } 00747 00748 template <typename Stream> 00749 inline packer<Stream> & packer<Stream>::pack_fix_uint16(uint16_t d) 00750 { 00751 char buf[3]; 00752 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], d); 00753 append_buffer(buf, 3); 00754 return *this; 00755 } 00756 00757 template <typename Stream> 00758 inline packer<Stream> & packer<Stream>::pack_fix_uint32(uint32_t d) 00759 { 00760 char buf[5]; 00761 buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], d); 00762 append_buffer(buf, 5); 00763 return *this; 00764 } 00765 00766 template <typename Stream> 00767 inline packer<Stream> & packer<Stream>::pack_fix_uint64(uint64_t d) 00768 { 00769 char buf[9]; 00770 buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d); 00771 append_buffer(buf, 9); 00772 return *this; 00773 } 00774 00775 template <typename Stream> 00776 inline packer<Stream> & packer<Stream>::pack_fix_int8(int8_t d) 00777 { 00778 char buf[2] = {static_cast<char>(0xd0u), take8_8(d)}; 00779 append_buffer(buf, 2); 00780 return *this; 00781 } 00782 00783 template <typename Stream> 00784 inline packer<Stream> & packer<Stream>::pack_fix_int16(int16_t d) 00785 { 00786 char buf[3]; 00787 buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], d); 00788 append_buffer(buf, 3); 00789 return *this; 00790 } 00791 00792 template <typename Stream> 00793 inline packer<Stream> & packer<Stream>::pack_fix_int32(int32_t d) 00794 { 00795 char buf[5]; 00796 buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], d); 00797 append_buffer(buf, 5); 00798 return *this; 00799 } 00800 00801 template <typename Stream> 00802 inline packer<Stream> & packer<Stream>::pack_fix_int64(int64_t d) 00803 { 00804 char buf[9]; 00805 buf[0] = static_cast<char>(0xd3u); _msgpack_store64(&buf[1], d); 00806 append_buffer(buf, 9); 00807 return *this; 00808 } 00809 00810 00811 template <typename Stream> 00812 inline packer<Stream> & packer<Stream>::pack_char(char d) 00813 { 00814 #if defined(CHAR_MIN) 00815 #if CHAR_MIN < 0 00816 pack_imp_int8(d); 00817 #else 00818 pack_imp_uint8(d); 00819 #endif 00820 #else 00821 #error CHAR_MIN is not defined 00822 #endif 00823 return *this; 00824 } 00825 00826 template <typename Stream> 00827 inline packer<Stream> & packer<Stream>::pack_signed_char(signed char d) 00828 { 00829 pack_imp_int8(d); 00830 return *this; 00831 } 00832 00833 template <typename Stream> 00834 inline packer<Stream> & packer<Stream>::pack_short(short d) 00835 { 00836 #if defined(SIZEOF_SHORT) 00837 #if SIZEOF_SHORT == 2 00838 pack_imp_int16(d); 00839 #elif SIZEOF_SHORT == 4 00840 pack_imp_int32(d); 00841 #else 00842 pack_imp_int64(d); 00843 #endif 00844 00845 #elif defined(SHRT_MAX) 00846 #if SHRT_MAX == 0x7fff 00847 pack_imp_int16(d); 00848 #elif SHRT_MAX == 0x7fffffff 00849 pack_imp_int32(d); 00850 #else 00851 pack_imp_int64(d); 00852 #endif 00853 00854 #else 00855 if(sizeof(short) == 2) { 00856 pack_imp_int16(d); 00857 } else if(sizeof(short) == 4) { 00858 pack_imp_int32(d); 00859 } else { 00860 pack_imp_int64(d); 00861 } 00862 #endif 00863 return *this; 00864 } 00865 00866 template <typename Stream> 00867 inline packer<Stream> & packer<Stream>::pack_int(int d) 00868 { 00869 #if defined(SIZEOF_INT) 00870 #if SIZEOF_INT == 2 00871 pack_imp_int16(d); 00872 #elif SIZEOF_INT == 4 00873 pack_imp_int32(d); 00874 #else 00875 pack_imp_int64(d); 00876 #endif 00877 00878 #elif defined(INT_MAX) 00879 #if INT_MAX == 0x7fff 00880 pack_imp_int16(d); 00881 #elif INT_MAX == 0x7fffffff 00882 pack_imp_int32(d); 00883 #else 00884 pack_imp_int64(d); 00885 #endif 00886 00887 #else 00888 if(sizeof(int) == 2) { 00889 pack_imp_int16(d); 00890 } else if(sizeof(int) == 4) { 00891 pack_imp_int32(d); 00892 } else { 00893 pack_imp_int64(d); 00894 } 00895 #endif 00896 return *this; 00897 } 00898 00899 template <typename Stream> 00900 inline packer<Stream> & packer<Stream>::pack_long(long d) 00901 { 00902 #if defined(SIZEOF_LONG) 00903 #if SIZEOF_LONG == 2 00904 pack_imp_int16(d); 00905 #elif SIZEOF_LONG == 4 00906 pack_imp_int32(d); 00907 #else 00908 pack_imp_int64(d); 00909 #endif 00910 00911 #elif defined(LONG_MAX) 00912 #if LONG_MAX == 0x7fffL 00913 pack_imp_int16(d); 00914 #elif LONG_MAX == 0x7fffffffL 00915 pack_imp_int32(d); 00916 #else 00917 pack_imp_int64(d); 00918 #endif 00919 00920 #else 00921 if(sizeof(long) == 2) { 00922 pack_imp_int16(d); 00923 } else if(sizeof(long) == 4) { 00924 pack_imp_int32(d); 00925 } else { 00926 pack_imp_int64(d); 00927 } 00928 #endif 00929 return *this; 00930 } 00931 00932 template <typename Stream> 00933 inline packer<Stream> & packer<Stream>::pack_long_long(long long d) 00934 { 00935 #if defined(SIZEOF_LONG_LONG) 00936 #if SIZEOF_LONG_LONG == 2 00937 pack_imp_int16(d); 00938 #elif SIZEOF_LONG_LONG == 4 00939 pack_imp_int32(d); 00940 #else 00941 pack_imp_int64(d); 00942 #endif 00943 00944 #elif defined(LLONG_MAX) 00945 #if LLONG_MAX == 0x7fffL 00946 pack_imp_int16(d); 00947 #elif LLONG_MAX == 0x7fffffffL 00948 pack_imp_int32(d); 00949 #else 00950 pack_imp_int64(d); 00951 #endif 00952 00953 #else 00954 if(sizeof(long long) == 2) { 00955 pack_imp_int16(d); 00956 } else if(sizeof(long long) == 4) { 00957 pack_imp_int32(d); 00958 } else { 00959 pack_imp_int64(d); 00960 } 00961 #endif 00962 return *this; 00963 } 00964 00965 00966 template <typename Stream> 00967 inline packer<Stream> & packer<Stream>::pack_unsigned_char(unsigned char d) 00968 { 00969 pack_imp_uint8(d); 00970 return *this; 00971 } 00972 00973 template <typename Stream> 00974 inline packer<Stream> & packer<Stream>::pack_unsigned_short(unsigned short d) 00975 { 00976 #if defined(SIZEOF_SHORT) 00977 #if SIZEOF_SHORT == 2 00978 pack_imp_uint16(d); 00979 #elif SIZEOF_SHORT == 4 00980 pack_imp_uint32(d); 00981 #else 00982 pack_imp_uint64(d); 00983 #endif 00984 00985 #elif defined(USHRT_MAX) 00986 #if USHRT_MAX == 0xffffU 00987 pack_imp_uint16(d); 00988 #elif USHRT_MAX == 0xffffffffU 00989 pack_imp_uint32(d); 00990 #else 00991 pack_imp_uint64(d); 00992 #endif 00993 00994 #else 00995 if(sizeof(unsigned short) == 2) { 00996 pack_imp_uint16(d); 00997 } else if(sizeof(unsigned short) == 4) { 00998 pack_imp_uint32(d); 00999 } else { 01000 pack_imp_uint64(d); 01001 } 01002 #endif 01003 return *this; 01004 } 01005 01006 template <typename Stream> 01007 inline packer<Stream> & packer<Stream>::pack_unsigned_int(unsigned int d) 01008 { 01009 #if defined(SIZEOF_INT) 01010 #if SIZEOF_INT == 2 01011 pack_imp_uint16(d); 01012 #elif SIZEOF_INT == 4 01013 pack_imp_uint32(d); 01014 #else 01015 pack_imp_uint64(d); 01016 #endif 01017 01018 #elif defined(UINT_MAX) 01019 #if UINT_MAX == 0xffffU 01020 pack_imp_uint16(d); 01021 #elif UINT_MAX == 0xffffffffU 01022 pack_imp_uint32(d); 01023 #else 01024 pack_imp_uint64(d); 01025 #endif 01026 01027 #else 01028 if(sizeof(unsigned int) == 2) { 01029 pack_imp_uint16(d); 01030 } else if(sizeof(unsigned int) == 4) { 01031 pack_imp_uint32(d); 01032 } else { 01033 pack_imp_uint64(d); 01034 } 01035 #endif 01036 return *this; 01037 } 01038 01039 template <typename Stream> 01040 inline packer<Stream> & packer<Stream>::pack_unsigned_long(unsigned long d) 01041 { 01042 #if defined(SIZEOF_LONG) 01043 #if SIZEOF_LONG == 2 01044 pack_imp_uint16(d); 01045 #elif SIZEOF_LONG == 4 01046 pack_imp_uint32(d); 01047 #else 01048 pack_imp_uint64(d); 01049 #endif 01050 01051 #elif defined(ULONG_MAX) 01052 #if ULONG_MAX == 0xffffUL 01053 pack_imp_uint16(d); 01054 #elif ULONG_MAX == 0xffffffffUL 01055 pack_imp_uint32(d); 01056 #else 01057 pack_imp_uint64(d); 01058 #endif 01059 01060 #else 01061 if(sizeof(unsigned long) == 2) { 01062 pack_imp_uint16(d); 01063 } else if(sizeof(unsigned long) == 4) { 01064 pack_imp_uint32(d); 01065 } else { 01066 pack_imp_uint64(d); 01067 } 01068 #endif 01069 return *this; 01070 } 01071 01072 template <typename Stream> 01073 inline packer<Stream> & packer<Stream>::pack_unsigned_long_long(unsigned long long d) 01074 { 01075 #if defined(SIZEOF_LONG_LONG) 01076 #if SIZEOF_LONG_LONG == 2 01077 pack_imp_uint16(d); 01078 #elif SIZEOF_LONG_LONG == 4 01079 pack_imp_uint32(d); 01080 #else 01081 pack_imp_uint64(d); 01082 #endif 01083 01084 #elif defined(ULLONG_MAX) 01085 #if ULLONG_MAX == 0xffffUL 01086 pack_imp_uint16(d); 01087 #elif ULLONG_MAX == 0xffffffffUL 01088 pack_imp_uint32(d); 01089 #else 01090 pack_imp_uint64(d); 01091 #endif 01092 01093 #else 01094 if(sizeof(unsigned long long) == 2) { 01095 pack_imp_uint16(d); 01096 } else if(sizeof(unsigned long long) == 4) { 01097 pack_imp_uint32(d); 01098 } else { 01099 pack_imp_uint64(d); 01100 } 01101 #endif 01102 return *this; 01103 } 01104 01105 01106 template <typename Stream> 01107 inline packer<Stream> & packer<Stream>::pack_float(float d) 01108 { 01109 union { float f; uint32_t i; } mem; 01110 mem.f = d; 01111 char buf[5]; 01112 buf[0] = static_cast<char>(0xcau); _msgpack_store32(&buf[1], mem.i); 01113 append_buffer(buf, 5); 01114 return *this; 01115 } 01116 01117 template <typename Stream> 01118 inline packer<Stream> & packer<Stream>::pack_double(double d) 01119 { 01120 union { double f; uint64_t i; } mem; 01121 mem.f = d; 01122 char buf[9]; 01123 buf[0] = static_cast<char>(0xcbu); 01124 01125 #if defined(TARGET_OS_IPHONE) 01126 // ok 01127 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi 01128 // https://github.com/msgpack/msgpack-perl/pull/1 01129 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); 01130 #endif 01131 _msgpack_store64(&buf[1], mem.i); 01132 append_buffer(buf, 9); 01133 return *this; 01134 } 01135 01136 01137 template <typename Stream> 01138 inline packer<Stream> & packer<Stream>::pack_nil() 01139 { 01140 const char d = static_cast<char>(0xc0u); 01141 append_buffer(&d, 1); 01142 return *this; 01143 } 01144 01145 template <typename Stream> 01146 inline packer<Stream> & packer<Stream>::pack_true() 01147 { 01148 const char d = static_cast<char>(0xc3u); 01149 append_buffer(&d, 1); 01150 return *this; 01151 } 01152 01153 template <typename Stream> 01154 inline packer<Stream> & packer<Stream>::pack_false() 01155 { 01156 const char d = static_cast<char>(0xc2u); 01157 append_buffer(&d, 1); 01158 return *this; 01159 } 01160 01161 01162 template <typename Stream> 01163 inline packer<Stream> & packer<Stream>::pack_array(uint32_t n) 01164 { 01165 if(n < 16) { 01166 char d = static_cast<char>(0x90u | n); 01167 append_buffer(&d, 1); 01168 } else if(n < 65536) { 01169 char buf[3]; 01170 buf[0] = static_cast<char>(0xdcu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n)); 01171 append_buffer(buf, 3); 01172 } else { 01173 char buf[5]; 01174 buf[0] = static_cast<char>(0xddu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n)); 01175 append_buffer(buf, 5); 01176 } 01177 return *this; 01178 } 01179 01180 template <typename Stream> 01181 inline packer<Stream> & packer<Stream>::pack_map(uint32_t n) 01182 { 01183 if(n < 16) { 01184 unsigned char d = static_cast<unsigned char>(0x80u | n); 01185 char buf = take8_8(d); 01186 append_buffer(&buf, 1); 01187 } else if(n < 65536) { 01188 char buf[3]; 01189 buf[0] = static_cast<char>(0xdeu); _msgpack_store16(&buf[1], static_cast<uint16_t>(n)); 01190 append_buffer(buf, 3); 01191 } else { 01192 char buf[5]; 01193 buf[0] = static_cast<char>(0xdfu); _msgpack_store32(&buf[1], static_cast<uint32_t>(n)); 01194 append_buffer(buf, 5); 01195 } 01196 return *this; 01197 } 01198 01199 template <typename Stream> 01200 inline packer<Stream> & packer<Stream>::pack_str(uint32_t l) 01201 { 01202 if(l < 32) { 01203 unsigned char d = static_cast<uint8_t>(0xa0u | l); 01204 char buf = take8_8(d); 01205 append_buffer(&buf, 1); 01206 } else if(l < 256) { 01207 char buf[2]; 01208 buf[0] = static_cast<char>(0xd9u); buf[1] = static_cast<uint8_t>(l); 01209 append_buffer(buf, 2); 01210 } else if(l < 65536) { 01211 char buf[3]; 01212 buf[0] = static_cast<char>(0xdau); _msgpack_store16(&buf[1], static_cast<uint16_t>(l)); 01213 append_buffer(buf, 3); 01214 } else { 01215 char buf[5]; 01216 buf[0] = static_cast<char>(0xdbu); _msgpack_store32(&buf[1], static_cast<uint32_t>(l)); 01217 append_buffer(buf, 5); 01218 } 01219 return *this; 01220 } 01221 01222 template <typename Stream> 01223 inline packer<Stream> & packer<Stream>::pack_str_body(const char* b, uint32_t l) 01224 { 01225 append_buffer(b, l); 01226 return *this; 01227 } 01228 01229 // Raw (V4) 01230 01231 template <typename Stream> 01232 inline packer<Stream> & packer<Stream>::pack_v4raw(uint32_t l) 01233 { 01234 if(l < 32) { 01235 unsigned char d = static_cast<uint8_t>(0xa0u | l); 01236 char buf = take8_8(d); 01237 append_buffer(&buf, 1); 01238 } else if(l < 65536) { 01239 char buf[3]; 01240 buf[0] = static_cast<char>(0xdau); _msgpack_store16(&buf[1], static_cast<uint16_t>(l)); 01241 append_buffer(buf, 3); 01242 } else { 01243 char buf[5]; 01244 buf[0] = static_cast<char>(0xdbu); _msgpack_store32(&buf[1], static_cast<uint32_t>(l)); 01245 append_buffer(buf, 5); 01246 } 01247 return *this; 01248 } 01249 01250 template <typename Stream> 01251 inline packer<Stream> & packer<Stream>::pack_v4raw_body(const char* b, uint32_t l) 01252 { 01253 append_buffer(b, l); 01254 return *this; 01255 } 01256 01257 template <typename Stream> 01258 inline packer<Stream> & packer<Stream>::pack_bin(uint32_t l) 01259 { 01260 if(l < 256) { 01261 char buf[2]; 01262 buf[0] = static_cast<char>(0xc4u); buf[1] = static_cast<uint8_t>(l); 01263 append_buffer(buf, 2); 01264 } else if(l < 65536) { 01265 char buf[3]; 01266 buf[0] = static_cast<char>(0xc5u); _msgpack_store16(&buf[1], static_cast<uint16_t>(l)); 01267 append_buffer(buf, 3); 01268 } else { 01269 char buf[5]; 01270 buf[0] = static_cast<char>(0xc6u); _msgpack_store32(&buf[1], static_cast<uint32_t>(l)); 01271 append_buffer(buf, 5); 01272 } 01273 return *this; 01274 } 01275 01276 template <typename Stream> 01277 inline packer<Stream> & packer<Stream>::pack_bin_body(const char* b, uint32_t l) 01278 { 01279 append_buffer(b, l); 01280 return *this; 01281 } 01282 01283 template <typename Stream> 01284 inline packer<Stream> & packer<Stream>::pack_ext(size_t l, int8_t type) 01285 { 01286 switch(l) { 01287 case 1: { 01288 char buf[2]; 01289 buf[0] = static_cast<char>(0xd4u); 01290 buf[1] = static_cast<char>(type); 01291 append_buffer(buf, 2); 01292 } break; 01293 case 2: { 01294 char buf[2]; 01295 buf[0] = static_cast<char>(0xd5u); 01296 buf[1] = static_cast<char>(type); 01297 append_buffer(buf, 2); 01298 } break; 01299 case 4: { 01300 char buf[2]; 01301 buf[0] = static_cast<char>(0xd6u); 01302 buf[1] = static_cast<char>(type); 01303 append_buffer(buf, 2); 01304 } break; 01305 case 8: { 01306 char buf[2]; 01307 buf[0] = static_cast<char>(0xd7u); 01308 buf[1] = static_cast<char>(type); 01309 append_buffer(buf, 2); 01310 } break; 01311 case 16: { 01312 char buf[2]; 01313 buf[0] = static_cast<char>(0xd8u); 01314 buf[1] = static_cast<char>(type); 01315 append_buffer(buf, 2); 01316 } break; 01317 default: 01318 if(l < 256) { 01319 char buf[3]; 01320 buf[0] = static_cast<char>(0xc7u); 01321 buf[1] = static_cast<char>(l); 01322 buf[2] = static_cast<char>(type); 01323 append_buffer(buf, 3); 01324 } else if(l < 65536) { 01325 char buf[4]; 01326 buf[0] = static_cast<char>(0xc8u); 01327 _msgpack_store16(&buf[1], static_cast<uint16_t>(l)); 01328 buf[3] = static_cast<char>(type); 01329 append_buffer(buf, 4); 01330 } else { 01331 char buf[6]; 01332 buf[0] = static_cast<char>(0xc9u); 01333 _msgpack_store32(&buf[1], static_cast<uint32_t>(l)); 01334 buf[5] = static_cast<char>(type); 01335 append_buffer(buf, 6); 01336 } 01337 break; 01338 } 01339 return *this; 01340 } 01341 01342 template <typename Stream> 01343 inline packer<Stream> & packer<Stream>::pack_ext_body(const char* b, uint32_t l) 01344 { 01345 append_buffer(b, l); 01346 return *this; 01347 } 01348 01349 template <typename Stream> 01350 template <typename T> 01351 inline void packer<Stream>::pack_imp_uint8 (T d) 01352 { 01353 if(d < (1<<7)) { 01354 /* fixnum */ 01355 char buf = take8_8(d); 01356 append_buffer(&buf, 1); 01357 } else { 01358 /* unsigned 8 */ 01359 char buf[2] = {static_cast<char>(0xccu), take8_8(d)}; 01360 append_buffer(buf, 2); 01361 } 01362 } 01363 01364 template <typename Stream> 01365 template <typename T> 01366 inline void packer<Stream>::pack_imp_uint16(T d) 01367 { 01368 if(d < (1<<7)) { 01369 /* fixnum */ 01370 char buf = take8_16(d); 01371 append_buffer(&buf, 1); 01372 } else if(d < (1<<8)) { 01373 /* unsigned 8 */ 01374 char buf[2] = {static_cast<char>(0xccu), take8_16(d)}; 01375 append_buffer(buf, 2); 01376 } else { 01377 /* unsigned 16 */ 01378 char buf[3]; 01379 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01380 append_buffer(buf, 3); 01381 } 01382 } 01383 01384 template <typename Stream> 01385 template <typename T> 01386 inline void packer<Stream>::pack_imp_uint32(T d) 01387 { 01388 if(d < (1<<8)) { 01389 if(d < (1<<7)) { 01390 /* fixnum */ 01391 char buf = take8_32(d); 01392 append_buffer(&buf, 1); 01393 } else { 01394 /* unsigned 8 */ 01395 char buf[2] = {static_cast<char>(0xccu), take8_32(d)}; 01396 append_buffer(buf, 2); 01397 } 01398 } else { 01399 if(d < (1<<16)) { 01400 /* unsigned 16 */ 01401 char buf[3]; 01402 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01403 append_buffer(buf, 3); 01404 } else { 01405 /* unsigned 32 */ 01406 char buf[5]; 01407 buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d)); 01408 append_buffer(buf, 5); 01409 } 01410 } 01411 } 01412 01413 template <typename Stream> 01414 template <typename T> 01415 inline void packer<Stream>::pack_imp_uint64(T d) 01416 { 01417 if(d < (1ULL<<8)) { 01418 if(d < (1ULL<<7)) { 01419 /* fixnum */ 01420 char buf = take8_64(d); 01421 append_buffer(&buf, 1); 01422 } else { 01423 /* unsigned 8 */ 01424 char buf[2] = {static_cast<char>(0xccu), take8_64(d)}; 01425 append_buffer(buf, 2); 01426 } 01427 } else { 01428 if(d < (1ULL<<16)) { 01429 /* unsigned 16 */ 01430 char buf[3]; 01431 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01432 append_buffer(buf, 3); 01433 } else if(d < (1ULL<<32)) { 01434 /* unsigned 32 */ 01435 char buf[5]; 01436 buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d)); 01437 append_buffer(buf, 5); 01438 } else { 01439 /* unsigned 64 */ 01440 char buf[9]; 01441 buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d); 01442 append_buffer(buf, 9); 01443 } 01444 } 01445 } 01446 01447 template <typename Stream> 01448 template <typename T> 01449 inline void packer<Stream>::pack_imp_int8(T d) 01450 { 01451 if(d < -(1<<5)) { 01452 /* signed 8 */ 01453 char buf[2] = {static_cast<char>(0xd0u), take8_8(d)}; 01454 append_buffer(buf, 2); 01455 } else { 01456 /* fixnum */ 01457 char buf = take8_8(d); 01458 append_buffer(&buf, 1); 01459 } 01460 } 01461 01462 template <typename Stream> 01463 template <typename T> 01464 inline void packer<Stream>::pack_imp_int16(T d) 01465 { 01466 if(d < -(1<<5)) { 01467 if(d < -(1<<7)) { 01468 /* signed 16 */ 01469 char buf[3]; 01470 buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d)); 01471 append_buffer(buf, 3); 01472 } else { 01473 /* signed 8 */ 01474 char buf[2] = {static_cast<char>(0xd0u), take8_16(d)}; 01475 append_buffer(buf, 2); 01476 } 01477 } else if(d < (1<<7)) { 01478 /* fixnum */ 01479 char buf = take8_16(d); 01480 append_buffer(&buf, 1); 01481 } else { 01482 if(d < (1<<8)) { 01483 /* unsigned 8 */ 01484 char buf[2] = {static_cast<char>(0xccu), take8_16(d)}; 01485 append_buffer(buf, 2); 01486 } else { 01487 /* unsigned 16 */ 01488 char buf[3]; 01489 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01490 append_buffer(buf, 3); 01491 } 01492 } 01493 } 01494 01495 template <typename Stream> 01496 template <typename T> 01497 inline void packer<Stream>::pack_imp_int32(T d) 01498 { 01499 if(d < -(1<<5)) { 01500 if(d < -(1<<15)) { 01501 /* signed 32 */ 01502 char buf[5]; 01503 buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], static_cast<int32_t>(d)); 01504 append_buffer(buf, 5); 01505 } else if(d < -(1<<7)) { 01506 /* signed 16 */ 01507 char buf[3]; 01508 buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d)); 01509 append_buffer(buf, 3); 01510 } else { 01511 /* signed 8 */ 01512 char buf[2] = { static_cast<char>(0xd0u), take8_32(d)}; 01513 append_buffer(buf, 2); 01514 } 01515 } else if(d < (1<<7)) { 01516 /* fixnum */ 01517 char buf = take8_32(d); 01518 append_buffer(&buf, 1); 01519 } else { 01520 if(d < (1<<8)) { 01521 /* unsigned 8 */ 01522 char buf[2] = { static_cast<char>(0xccu), take8_32(d)}; 01523 append_buffer(buf, 2); 01524 } else if(d < (1<<16)) { 01525 /* unsigned 16 */ 01526 char buf[3]; 01527 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01528 append_buffer(buf, 3); 01529 } else { 01530 /* unsigned 32 */ 01531 char buf[5]; 01532 buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d)); 01533 append_buffer(buf, 5); 01534 } 01535 } 01536 } 01537 01538 template <typename Stream> 01539 template <typename T> 01540 inline void packer<Stream>::pack_imp_int64(T d) 01541 { 01542 if(d < -(1LL<<5)) { 01543 if(d < -(1LL<<15)) { 01544 if(d < -(1LL<<31)) { 01545 /* signed 64 */ 01546 char buf[9]; 01547 buf[0] = static_cast<char>(0xd3u); _msgpack_store64(&buf[1], d); 01548 append_buffer(buf, 9); 01549 } else { 01550 /* signed 32 */ 01551 char buf[5]; 01552 buf[0] = static_cast<char>(0xd2u); _msgpack_store32(&buf[1], static_cast<int32_t>(d)); 01553 append_buffer(buf, 5); 01554 } 01555 } else { 01556 if(d < -(1<<7)) { 01557 /* signed 16 */ 01558 char buf[3]; 01559 buf[0] = static_cast<char>(0xd1u); _msgpack_store16(&buf[1], static_cast<int16_t>(d)); 01560 append_buffer(buf, 3); 01561 } else { 01562 /* signed 8 */ 01563 char buf[2] = {static_cast<char>(0xd0u), take8_64(d)}; 01564 append_buffer(buf, 2); 01565 } 01566 } 01567 } else if(d < (1<<7)) { 01568 /* fixnum */ 01569 char buf = take8_64(d); 01570 append_buffer(&buf, 1); 01571 } else { 01572 if(d < (1LL<<16)) { 01573 if(d < (1<<8)) { 01574 /* unsigned 8 */ 01575 char buf[2] = {static_cast<char>(0xccu), take8_64(d)}; 01576 append_buffer(buf, 2); 01577 } else { 01578 /* unsigned 16 */ 01579 char buf[3]; 01580 buf[0] = static_cast<char>(0xcdu); _msgpack_store16(&buf[1], static_cast<uint16_t>(d)); 01581 append_buffer(buf, 3); 01582 } 01583 } else { 01584 if(d < (1LL<<32)) { 01585 /* unsigned 32 */ 01586 char buf[5]; 01587 buf[0] = static_cast<char>(0xceu); _msgpack_store32(&buf[1], static_cast<uint32_t>(d)); 01588 append_buffer(buf, 5); 01589 } else { 01590 /* unsigned 64 */ 01591 char buf[9]; 01592 buf[0] = static_cast<char>(0xcfu); _msgpack_store64(&buf[1], d); 01593 append_buffer(buf, 9); 01594 } 01595 } 01596 } 01597 } 01598 01599 /// @cond 01600 } // MSGPACK_API_VERSION_NAMESPACE(v1) 01601 /// @endcond 01602 01603 } // namespace msgpack 01604 01605 #endif /* msgpack/pack.hpp */
Generated on Tue Jul 12 2022 22:51:46 by 1.7.2