messagepack implementation for embedded systems (mbed / arduino)

Dependents:   hello_message_pack

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pack.hpp Source File

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 */