// Copyright 2020 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_CONVERTER_HPP #define JSONCONS_CONVERTER_HPP #include // std::error_code #include #include #include #include #include // from_integer namespace jsoncons { template class converter { }; // Into list like of bytes template class converter::value && type_traits::is_back_insertable_byte_container::value) || type_traits::is_basic_byte_string::value>::type> { using value_type = typename Into::value_type; using allocator_type = typename Into::allocator_type; public: JSONCONS_CPP14_CONSTEXPR Into from(const byte_string_view& bstr, semantic_tag tag, std::error_code& ec) const { Into bytes; from_(bytes, bstr, tag, ec); return bytes; } JSONCONS_CPP14_CONSTEXPR Into from(const byte_string_view& bstr, semantic_tag tag, const allocator_type& alloc, std::error_code& ec) const { Into bytes(alloc); from_(bytes, bstr, tag, ec); return bytes; } template JSONCONS_CPP14_CONSTEXPR Into from(const jsoncons::basic_string_view& s, semantic_tag tag, std::error_code& ec) const { Into bytes; from_(bytes, s, tag, ec); return bytes; } template JSONCONS_CPP14_CONSTEXPR Into from(const jsoncons::basic_string_view& s, semantic_tag tag, const allocator_type& alloc, std::error_code& ec) const { Into bytes(alloc); from_(bytes, s, tag, ec); return bytes; } private: JSONCONS_CPP14_CONSTEXPR void from_(Into& bytes, const byte_string_view& bstr, semantic_tag, std::error_code&) const { for (auto ch : bstr) { bytes.push_back(static_cast(ch)); } } template JSONCONS_CPP14_CONSTEXPR typename std::enable_if::value>::type from_(Into& bytes, const jsoncons::basic_string_view& s, semantic_tag tag, std::error_code& ec) const { switch (tag) { case semantic_tag::base16: { auto res = decode_base16(s.begin(), s.end(), bytes); if (res.ec != conv_errc::success) { ec = conv_errc::not_byte_string; } break; } case semantic_tag::base64: { decode_base64(s.begin(), s.end(), bytes); break; } case semantic_tag::base64url: { decode_base64url(s.begin(), s.end(), bytes); break; } default: { ec = conv_errc::not_byte_string; break; } } } template typename std::enable_if::value>::type from_(Into& bytes, const jsoncons::basic_string_view& s, semantic_tag tag, std::error_code& ec) const { std::string u; auto retval = unicode_traits::convert(s.data(), s.size(), u); if (retval.ec != unicode_traits::conv_errc()) { ec = conv_errc::not_utf8; return; } from_(bytes, jsoncons::string_view(u), tag, ec); } }; // Into string template class converter::value>::type> { using char_type = typename Into::value_type; using allocator_type = typename Into::allocator_type; int dummy_; public: explicit converter(int dummy = int()) : dummy_(dummy) {} template JSONCONS_CPP14_CONSTEXPR typename std::enable_if::value,Into>::type from(Integer val, semantic_tag, std::error_code&) const { Into s; jsoncons::detail::from_integer(val, s); return s; } template JSONCONS_CPP14_CONSTEXPR typename std::enable_if::value,Into>::type from(Integer val, semantic_tag, const allocator_type& alloc, std::error_code&) const { Into s(alloc); jsoncons::detail::from_integer(val, s); return s; } Into from(double val, semantic_tag, std::error_code&) const { Into s; jsoncons::detail::write_double f{float_chars_format::general,0}; f(val, s); return s; } Into from(double val, semantic_tag, const allocator_type& alloc, std::error_code&) const { Into s(alloc); jsoncons::detail::write_double f{float_chars_format::general,0}; f(val, s); return s; } Into from(half_arg_t, uint16_t val, semantic_tag, std::error_code&) const { Into s; jsoncons::detail::write_double f{float_chars_format::general,0}; double x = binary::decode_half(val); f(x, s); return s; } Into from(half_arg_t, uint16_t val, semantic_tag, const allocator_type& alloc, std::error_code&) const { Into s(alloc); jsoncons::detail::write_double f{float_chars_format::general,0}; double x = binary::decode_half(val); f(x, s); return s; } template JSONCONS_CPP14_CONSTEXPR Into from(const byte_string_view& bytes, semantic_tag tag, std::error_code& ec) const { Into s; from_(s, bytes, tag, ec); return s; } template JSONCONS_CPP14_CONSTEXPR Into from(const byte_string_view& bytes, semantic_tag tag, const allocator_type& alloc, std::error_code& ec) const { Into s(alloc); from_(s, bytes, tag, ec); return s; } constexpr Into from(const jsoncons::basic_string_view& s, semantic_tag, std::error_code&) const { return Into(s.data(), s.size()); } constexpr Into from(const jsoncons::basic_string_view& s, semantic_tag, const allocator_type& alloc, std::error_code&) const { return Into(s.data(), s.size(), alloc); } JSONCONS_CPP14_CONSTEXPR Into from(bool val, semantic_tag, std::error_code&) const { constexpr const char_type* true_constant = JSONCONS_CSTRING_CONSTANT(char_type,"true"); constexpr const char_type* false_constant = JSONCONS_CSTRING_CONSTANT(char_type,"false"); return val ? Into(true_constant,4) : Into(false_constant,5); } JSONCONS_CPP14_CONSTEXPR Into from(bool val, semantic_tag, const allocator_type& alloc, std::error_code&) const { constexpr const char_type* true_constant = JSONCONS_CSTRING_CONSTANT(char_type,"true"); constexpr const char_type* false_constant = JSONCONS_CSTRING_CONSTANT(char_type,"false"); return val ? Into(true_constant,4,alloc) : Into(false_constant,5,alloc); } JSONCONS_CPP14_CONSTEXPR Into from(null_type, semantic_tag, std::error_code&) const { constexpr const char_type* null_constant = JSONCONS_CSTRING_CONSTANT(char_type,"null"); return Into(null_constant,4); } JSONCONS_CPP14_CONSTEXPR Into from(null_type, semantic_tag, const allocator_type& alloc, std::error_code&) const { constexpr const char_type* null_constant = JSONCONS_CSTRING_CONSTANT(char_type,"null"); return Into(null_constant,4,alloc); } private: template JSONCONS_CPP14_CONSTEXPR typename std::enable_if::value>::type from_(Into& s, const byte_string_view& bytes, semantic_tag tag, std::error_code&) const { switch (tag) { case semantic_tag::base64: encode_base64(bytes.begin(), bytes.end(), s); break; case semantic_tag::base16: encode_base16(bytes.begin(), bytes.end(), s); break; default: encode_base64url(bytes.begin(), bytes.end(), s); break; } } template typename std::enable_if::value>::type from_(Into& s, const byte_string_view& bytes, semantic_tag tag, std::error_code& ec) const { converter convert{ dummy_ }; std::string u = convert.from(bytes, tag, ec); auto retval = unicode_traits::convert(u.data(), u.size(), s); if (retval.ec != unicode_traits::conv_errc()) { ec = conv_errc::not_wide_char; } } }; } // namespace jsoncons #endif