aboutsummaryrefslogtreecommitdiff
path: root/include/jsoncons_ext/msgpack/msgpack_encoder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/jsoncons_ext/msgpack/msgpack_encoder.hpp')
-rw-r--r--include/jsoncons_ext/msgpack/msgpack_encoder.hpp753
1 files changed, 753 insertions, 0 deletions
diff --git a/include/jsoncons_ext/msgpack/msgpack_encoder.hpp b/include/jsoncons_ext/msgpack/msgpack_encoder.hpp
new file mode 100644
index 0000000..34e882b
--- /dev/null
+++ b/include/jsoncons_ext/msgpack/msgpack_encoder.hpp
@@ -0,0 +1,753 @@
+// Copyright 2018 Daniel Parker
+// Distributed under the Boost license, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See https://github.com/danielaparker/jsoncons for latest version
+
+#ifndef JSONCONS_MSGPACK_MSGPACK_ENCODER_HPP
+#define JSONCONS_MSGPACK_MSGPACK_ENCODER_HPP
+
+#include <string>
+#include <vector>
+#include <limits> // std::numeric_limits
+#include <memory>
+#include <utility> // std::move
+#include <jsoncons/json_exception.hpp>
+#include <jsoncons/json_visitor.hpp>
+#include <jsoncons/config/jsoncons_config.hpp>
+#include <jsoncons/sink.hpp>
+#include <jsoncons/detail/parse_number.hpp>
+#include <jsoncons_ext/msgpack/msgpack_type.hpp>
+#include <jsoncons_ext/msgpack/msgpack_error.hpp>
+#include <jsoncons_ext/msgpack/msgpack_options.hpp>
+
+namespace jsoncons {
+namespace msgpack {
+
+ enum class msgpack_container_type {object, array};
+
+ template<class Sink=jsoncons::binary_stream_sink,class Allocator=std::allocator<char>>
+ class basic_msgpack_encoder final : public basic_json_visitor<char>
+ {
+ enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 };
+
+ static constexpr int64_t nanos_in_milli = 1000000;
+ static constexpr int64_t nanos_in_second = 1000000000;
+ static constexpr int64_t millis_in_second = 1000;
+ public:
+ using allocator_type = Allocator;
+ using char_type = char;
+ using typename basic_json_visitor<char>::string_view_type;
+ using sink_type = Sink;
+
+ private:
+ struct stack_item
+ {
+ msgpack_container_type type_;
+ std::size_t length_;
+ std::size_t count_;
+
+ stack_item(msgpack_container_type type, std::size_t length = 0) noexcept
+ : type_(type), length_(length), count_(0)
+ {
+ }
+
+ std::size_t length() const
+ {
+ return length_;
+ }
+
+ std::size_t count() const
+ {
+ return count_;
+ }
+
+ bool is_object() const
+ {
+ return type_ == msgpack_container_type::object;
+ }
+ };
+
+ Sink sink_;
+ const msgpack_encode_options options_;
+ allocator_type alloc_;
+
+ std::vector<stack_item> stack_;
+ int nesting_depth_;
+
+ // Noncopyable and nonmoveable
+ basic_msgpack_encoder(const basic_msgpack_encoder&) = delete;
+ basic_msgpack_encoder& operator=(const basic_msgpack_encoder&) = delete;
+ public:
+ explicit basic_msgpack_encoder(Sink&& sink,
+ const Allocator& alloc = Allocator())
+ : basic_msgpack_encoder(std::forward<Sink>(sink), msgpack_encode_options(), alloc)
+ {
+ }
+
+ explicit basic_msgpack_encoder(Sink&& sink,
+ const msgpack_encode_options& options,
+ const Allocator& alloc = Allocator())
+ : sink_(std::forward<Sink>(sink)),
+ options_(options),
+ alloc_(alloc),
+ nesting_depth_(0)
+ {
+ }
+
+ ~basic_msgpack_encoder() noexcept
+ {
+ sink_.flush();
+ }
+
+ void reset()
+ {
+ stack_.clear();
+ nesting_depth_ = 0;
+ }
+
+ void reset(Sink&& sink)
+ {
+ sink_ = std::move(sink);
+ reset();
+ }
+
+ private:
+ // Implementing methods
+
+ void visit_flush() override
+ {
+ sink_.flush();
+ }
+
+ bool visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override
+ {
+ ec = msgpack_errc::object_length_required;
+ return false;
+ }
+
+ bool visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
+ {
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
+ {
+ ec = msgpack_errc::max_nesting_depth_exceeded;
+ return false;
+ }
+ stack_.emplace_back(msgpack_container_type::object, length);
+
+ if (length <= 15)
+ {
+ // fixmap
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixmap_base_type | (length & 0xf));
+ }
+ else if (length <= 65535)
+ {
+ // map 16
+ sink_.push_back(jsoncons::msgpack::msgpack_type::map16_type);
+ binary::native_to_big(static_cast<uint16_t>(length),
+ std::back_inserter(sink_));
+ }
+ else if (length <= 4294967295)
+ {
+ // map 32
+ sink_.push_back(jsoncons::msgpack::msgpack_type::map32_type);
+ binary::native_to_big(static_cast<uint32_t>(length),
+ std::back_inserter(sink_));
+ }
+
+ return true;
+ }
+
+ bool visit_end_object(const ser_context&, std::error_code& ec) override
+ {
+ JSONCONS_ASSERT(!stack_.empty());
+ --nesting_depth_;
+
+ if (stack_.back().count() < stack_.back().length())
+ {
+ ec = msgpack_errc::too_few_items;
+ return false;
+ }
+ else if (stack_.back().count() > stack_.back().length())
+ {
+ ec = msgpack_errc::too_many_items;
+ return false;
+ }
+
+ stack_.pop_back();
+ end_value();
+ return true;
+ }
+
+ bool visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override
+ {
+ ec = msgpack_errc::array_length_required;
+ return false;
+ }
+
+ bool visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
+ {
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
+ {
+ ec = msgpack_errc::max_nesting_depth_exceeded;
+ return false;
+ }
+ stack_.emplace_back(msgpack_container_type::array, length);
+ if (length <= 15)
+ {
+ // fixarray
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixarray_base_type | (length & 0xf));
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // array 16
+ sink_.push_back(jsoncons::msgpack::msgpack_type::array16_type);
+ binary::native_to_big(static_cast<uint16_t>(length),std::back_inserter(sink_));
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // array 32
+ sink_.push_back(jsoncons::msgpack::msgpack_type::array32_type);
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
+ }
+ return true;
+ }
+
+ bool visit_end_array(const ser_context&, std::error_code& ec) override
+ {
+ JSONCONS_ASSERT(!stack_.empty());
+
+ --nesting_depth_;
+
+ if (stack_.back().count() < stack_.back().length())
+ {
+ ec = msgpack_errc::too_few_items;
+ return false;
+ }
+ else if (stack_.back().count() > stack_.back().length())
+ {
+ ec = msgpack_errc::too_many_items;
+ return false;
+ }
+
+ stack_.pop_back();
+ end_value();
+ return true;
+ }
+
+ bool visit_key(const string_view_type& name, const ser_context&, std::error_code&) override
+ {
+ write_string_value(name);
+ return true;
+ }
+
+ bool visit_null(semantic_tag, const ser_context&, std::error_code&) override
+ {
+ // nil
+ sink_.push_back(jsoncons::msgpack::msgpack_type::nil_type);
+ end_value();
+ return true;
+ }
+
+ void write_timestamp(int64_t seconds, int64_t nanoseconds)
+ {
+ if ((seconds >> 34) == 0)
+ {
+ uint64_t data64 = (nanoseconds << 34) | seconds;
+ if ((data64 & 0xffffffff00000000L) == 0)
+ {
+ // timestamp 32
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type);
+ sink_.push_back(0xff);
+ binary::native_to_big(static_cast<uint32_t>(data64), std::back_inserter(sink_));
+ }
+ else
+ {
+ // timestamp 64
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type);
+ sink_.push_back(0xff);
+ binary::native_to_big(static_cast<uint64_t>(data64), std::back_inserter(sink_));
+ }
+ }
+ else
+ {
+ // timestamp 96
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type);
+ sink_.push_back(0x0c); // 12
+ sink_.push_back(0xff);
+ binary::native_to_big(static_cast<uint32_t>(nanoseconds), std::back_inserter(sink_));
+ binary::native_to_big(static_cast<uint64_t>(seconds), std::back_inserter(sink_));
+ }
+ }
+
+ bool visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) override
+ {
+ switch (tag)
+ {
+ case semantic_tag::epoch_second:
+ {
+ int64_t seconds;
+ auto result = jsoncons::detail::to_integer(sv.data(), sv.length(), seconds);
+ if (!result)
+ {
+ ec = msgpack_errc::invalid_timestamp;
+ return false;
+ }
+ write_timestamp(seconds, 0);
+ break;
+ }
+ case semantic_tag::epoch_milli:
+ {
+ bigint n = bigint::from_string(sv.data(), sv.length());
+ if (n != 0)
+ {
+ bigint q;
+ bigint rem;
+ n.divide(millis_in_second, q, rem, true);
+ int64_t seconds = static_cast<int64_t>(q);
+ int64_t nanoseconds = static_cast<int64_t>(rem) * nanos_in_milli;
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ case semantic_tag::epoch_nano:
+ {
+ bigint n = bigint::from_string(sv.data(), sv.length());
+ if (n != 0)
+ {
+ bigint q;
+ bigint rem;
+ n.divide(nanos_in_second, q, rem, true);
+ int64_t seconds = static_cast<int64_t>(q);
+ int64_t nanoseconds = static_cast<int64_t>(rem);
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ default:
+ {
+ write_string_value(sv);
+ end_value();
+ break;
+ }
+ }
+ return true;
+ }
+
+ void write_string_value(const string_view_type& sv)
+ {
+ auto sink = unicode_traits::validate(sv.data(), sv.size());
+ if (sink.ec != unicode_traits::conv_errc())
+ {
+ JSONCONS_THROW(ser_error(msgpack_errc::invalid_utf8_text_string));
+ }
+
+ const size_t length = sv.length();
+ if (length <= 31)
+ {
+ // fixstr stores a byte array whose length is upto 31 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixstr_base_type | static_cast<uint8_t>(length));
+ }
+ else if (length <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // str 8 stores a byte array whose length is upto (2^8)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str8_type);
+ sink_.push_back(static_cast<uint8_t>(length));
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // str 16 stores a byte array whose length is upto (2^16)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str16_type);
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // str 32 stores a byte array whose length is upto (2^32)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str32_type);
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
+ }
+
+ for (auto c : sv)
+ {
+ sink_.push_back(c);
+ }
+ }
+
+ bool visit_byte_string(const byte_string_view& b,
+ semantic_tag,
+ const ser_context&,
+ std::error_code&) override
+ {
+
+ const std::size_t length = b.size();
+ if (length <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // bin 8 stores a byte array whose length is upto (2^8)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin8_type);
+ sink_.push_back(static_cast<uint8_t>(length));
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // bin 16 stores a byte array whose length is upto (2^16)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin16_type);
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // bin 32 stores a byte array whose length is upto (2^32)-1 bytes
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin32_type);
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
+ }
+
+ for (auto c : b)
+ {
+ sink_.push_back(c);
+ }
+
+ end_value();
+ return true;
+ }
+
+ bool visit_byte_string(const byte_string_view& b,
+ uint64_t ext_tag,
+ const ser_context&,
+ std::error_code&) override
+ {
+ const std::size_t length = b.size();
+ switch (length)
+ {
+ case 1:
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext1_type);
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ break;
+ case 2:
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext2_type);
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ break;
+ case 4:
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type);
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ break;
+ case 8:
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type);
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ break;
+ case 16:
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext16_type);
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ break;
+ default:
+ if (length <= (std::numeric_limits<uint8_t>::max)())
+ {
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type);
+ sink_.push_back(static_cast<uint8_t>(length));
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ }
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
+ {
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext16_type);
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ }
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
+ {
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext32_type);
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
+ }
+ break;
+ }
+
+ for (auto c : b)
+ {
+ sink_.push_back(c);
+ }
+
+ end_value();
+ return true;
+ }
+
+ bool visit_double(double val,
+ semantic_tag,
+ const ser_context&,
+ std::error_code&) override
+ {
+ float valf = (float)val;
+ if ((double)valf == val)
+ {
+ // float 32
+ sink_.push_back(jsoncons::msgpack::msgpack_type::float32_type);
+ binary::native_to_big(valf,std::back_inserter(sink_));
+ }
+ else
+ {
+ // float 64
+ sink_.push_back(jsoncons::msgpack::msgpack_type::float64_type);
+ binary::native_to_big(val,std::back_inserter(sink_));
+ }
+
+ // write double
+
+ end_value();
+ return true;
+ }
+
+ bool visit_int64(int64_t val,
+ semantic_tag tag,
+ const ser_context&,
+ std::error_code&) override
+ {
+ switch (tag)
+ {
+ case semantic_tag::epoch_second:
+ write_timestamp(val, 0);
+ break;
+ case semantic_tag::epoch_milli:
+ {
+ if (val != 0)
+ {
+ auto dv = std::div(val,millis_in_second);
+ int64_t seconds = dv.quot;
+ int64_t nanoseconds = dv.rem*nanos_in_milli;
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ case semantic_tag::epoch_nano:
+ {
+ if (val != 0)
+ {
+ auto dv = std::div(val,static_cast<int64_t>(nanos_in_second));
+ int64_t seconds = dv.quot;
+ int64_t nanoseconds = dv.rem;
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ default:
+ {
+ if (val >= 0)
+ {
+ if (val <= 0x7f)
+ {
+ // positive fixnum stores 7-bit positive integer
+ sink_.push_back(static_cast<uint8_t>(val));
+ }
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // uint 8 stores a 8-bit unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type);
+ sink_.push_back(static_cast<uint8_t>(val));
+ }
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // uint 16 stores a 16-bit big-endian unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type);
+ binary::native_to_big(static_cast<uint16_t>(val),std::back_inserter(sink_));
+ }
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // uint 32 stores a 32-bit big-endian unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type);
+ binary::native_to_big(static_cast<uint32_t>(val),std::back_inserter(sink_));
+ }
+ else if (val <= (std::numeric_limits<int64_t>::max)())
+ {
+ // int 64 stores a 64-bit big-endian signed integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type);
+ binary::native_to_big(static_cast<uint64_t>(val),std::back_inserter(sink_));
+ }
+ }
+ else
+ {
+ if (val >= -32)
+ {
+ // negative fixnum stores 5-bit negative integer
+ binary::native_to_big(static_cast<int8_t>(val), std::back_inserter(sink_));
+ }
+ else if (val >= (std::numeric_limits<int8_t>::lowest)())
+ {
+ // int 8 stores a 8-bit signed integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int8_type);
+ binary::native_to_big(static_cast<int8_t>(val),std::back_inserter(sink_));
+ }
+ else if (val >= (std::numeric_limits<int16_t>::lowest)())
+ {
+ // int 16 stores a 16-bit big-endian signed integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int16_type);
+ binary::native_to_big(static_cast<int16_t>(val),std::back_inserter(sink_));
+ }
+ else if (val >= (std::numeric_limits<int32_t>::lowest)())
+ {
+ // int 32 stores a 32-bit big-endian signed integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int32_type);
+ binary::native_to_big(static_cast<int32_t>(val),std::back_inserter(sink_));
+ }
+ else if (val >= (std::numeric_limits<int64_t>::lowest)())
+ {
+ // int 64 stores a 64-bit big-endian signed integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int64_type);
+ binary::native_to_big(static_cast<int64_t>(val),std::back_inserter(sink_));
+ }
+ }
+ }
+ break;
+ }
+ end_value();
+ return true;
+ }
+
+ bool visit_uint64(uint64_t val,
+ semantic_tag tag,
+ const ser_context&,
+ std::error_code&) override
+ {
+ switch (tag)
+ {
+ case semantic_tag::epoch_second:
+ write_timestamp(static_cast<int64_t>(val), 0);
+ break;
+ case semantic_tag::epoch_milli:
+ {
+ if (val != 0)
+ {
+ auto dv = std::div(static_cast<int64_t>(val), static_cast<int64_t>(millis_in_second));
+ int64_t seconds = dv.quot;
+ int64_t nanoseconds = dv.rem*nanos_in_milli;
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ case semantic_tag::epoch_nano:
+ {
+ if (val != 0)
+ {
+ auto dv = std::div(static_cast<int64_t>(val), static_cast<int64_t>(nanos_in_second));
+ int64_t seconds = dv.quot;
+ int64_t nanoseconds = dv.rem;
+ if (nanoseconds < 0)
+ {
+ nanoseconds = -nanoseconds;
+ }
+ write_timestamp(seconds, nanoseconds);
+ }
+ else
+ {
+ write_timestamp(0, 0);
+ }
+ break;
+ }
+ default:
+ {
+ if (val <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
+ {
+ // positive fixnum stores 7-bit positive integer
+ sink_.push_back(static_cast<uint8_t>(val));
+ }
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
+ {
+ // uint 8 stores a 8-bit unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type);
+ sink_.push_back(static_cast<uint8_t>(val));
+ }
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
+ {
+ // uint 16 stores a 16-bit big-endian unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type);
+ binary::native_to_big(static_cast<uint16_t>(val),std::back_inserter(sink_));
+ }
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
+ {
+ // uint 32 stores a 32-bit big-endian unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type);
+ binary::native_to_big(static_cast<uint32_t>(val),std::back_inserter(sink_));
+ }
+ else if (val <= (std::numeric_limits<uint64_t>::max)())
+ {
+ // uint 64 stores a 64-bit big-endian unsigned integer
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type);
+ binary::native_to_big(static_cast<uint64_t>(val),std::back_inserter(sink_));
+ }
+ break;
+ }
+ }
+ end_value();
+ return true;
+ }
+
+ bool visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override
+ {
+ // true and false
+ sink_.push_back(static_cast<uint8_t>(val ? jsoncons::msgpack::msgpack_type::true_type : jsoncons::msgpack::msgpack_type::false_type));
+
+ end_value();
+ return true;
+ }
+
+ void end_value()
+ {
+ if (!stack_.empty())
+ {
+ ++stack_.back().count_;
+ }
+ }
+ };
+
+ using msgpack_stream_encoder = basic_msgpack_encoder<jsoncons::binary_stream_sink>;
+ using msgpack_bytes_encoder = basic_msgpack_encoder<jsoncons::bytes_sink<std::vector<uint8_t>>>;
+
+ #if !defined(JSONCONS_NO_DEPRECATED)
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_bytes_encoder") typedef msgpack_bytes_encoder msgpack_bytes_serializer;
+
+ template<class Sink=jsoncons::binary_stream_sink>
+ using basic_msgpack_serializer = basic_msgpack_encoder<Sink>;
+
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_stream_encoder") typedef msgpack_stream_encoder msgpack_encoder;
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_stream_encoder") typedef msgpack_stream_encoder msgpack_serializer;
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_bytes_encoder") typedef msgpack_bytes_encoder msgpack_buffer_serializer;
+ #endif
+
+} // namespace msgpack
+} // namespace jsoncons
+
+#endif