diff --git a/Makefile b/Makefile index 1b947462..bf4e5b67 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,8 @@ SRCS = ${SRCDIR}/json.hpp \ ${SRCDIR}/detail/iterators/internal_iterator.hpp \ ${SRCDIR}/detail/iterators/iter_impl.hpp \ ${SRCDIR}/detail/iterators/iteration_proxy.hpp \ - ${SRCDIR}/detail/iterators/json_reverse_iterator.hpp + ${SRCDIR}/detail/iterators/json_reverse_iterator.hpp \ + ${SRCDIR}/detail/parsing/output_adapters.hpp diff --git a/src/detail/parsing/output_adapters.hpp b/src/detail/parsing/output_adapters.hpp new file mode 100644 index 00000000..5cbc11b9 --- /dev/null +++ b/src/detail/parsing/output_adapters.hpp @@ -0,0 +1,114 @@ +#ifndef NLOHMANN_JSON_DETAIL_PARSING_OUTPUT_ADAPTERS_HPP +#define NLOHMANN_JSON_DETAIL_PARSING_OUTPUT_ADAPTERS_HPP + +#include <algorithm> +#include <cstddef> +#include <iosfwd> +#include <iterator> +#include <memory> +#include <vector> + +namespace nlohmann +{ +namespace detail +{ +/// abstract output adapter interface +template<typename CharType> struct output_adapter_protocol +{ + virtual void write_character(CharType c) = 0; + virtual void write_characters(const CharType* s, std::size_t length) = 0; + virtual ~output_adapter_protocol() = default; +}; + +/// a type to simplify interfaces +template<typename CharType> +using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>; + +/// output adapter for byte vectors +template<typename CharType> +class output_vector_adapter : public output_adapter_protocol<CharType> +{ + public: + explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {} + + void write_character(CharType c) override + { + v.push_back(c); + } + + void write_characters(const CharType* s, std::size_t length) override + { + std::copy(s, s + length, std::back_inserter(v)); + } + + private: + std::vector<CharType>& v; +}; + +/// output adapter for output streams +template<typename CharType> +class output_stream_adapter : public output_adapter_protocol<CharType> +{ + public: + explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {} + + void write_character(CharType c) override + { + stream.put(c); + } + + void write_characters(const CharType* s, std::size_t length) override + { + stream.write(s, static_cast<std::streamsize>(length)); + } + + private: + std::basic_ostream<CharType>& stream; +}; + +/// output adapter for basic_string +template<typename CharType> +class output_string_adapter : public output_adapter_protocol<CharType> +{ + public: + explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {} + + void write_character(CharType c) override + { + str.push_back(c); + } + + void write_characters(const CharType* s, std::size_t length) override + { + str.append(s, length); + } + + private: + std::basic_string<CharType>& str; +}; + +template<typename CharType> +class output_adapter +{ + public: + output_adapter(std::vector<CharType>& vec) + : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {} + + output_adapter(std::basic_ostream<CharType>& s) + : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} + + output_adapter(std::basic_string<CharType>& s) + : oa(std::make_shared<output_string_adapter<CharType>>(s)) {} + + operator output_adapter_t<CharType>() + { + return oa; + } + + private: + output_adapter_t<CharType> oa = nullptr; +}; +} +} + +#endif diff --git a/src/json.hpp b/src/json.hpp index 3cf317f7..7d62e412 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -65,6 +65,7 @@ SOFTWARE. #include "detail/iterators/iter_impl.hpp" #include "detail/iterators/iteration_proxy.hpp" #include "detail/iterators/json_reverse_iterator.hpp" +#include "detail/parsing/output_adapters.hpp" /*! @brief namespace for Niels Lohmann @@ -75,107 +76,6 @@ namespace nlohmann { namespace detail { -///////////////////// -// output adapters // -///////////////////// - -/// abstract output adapter interface -template<typename CharType> struct output_adapter_protocol -{ - virtual void write_character(CharType c) = 0; - virtual void write_characters(const CharType* s, std::size_t length) = 0; - virtual ~output_adapter_protocol() = default; -}; - -/// a type to simplify interfaces -template<typename CharType> -using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>; - -/// output adapter for byte vectors -template<typename CharType> -class output_vector_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {} - - void write_character(CharType c) override - { - v.push_back(c); - } - - void write_characters(const CharType* s, std::size_t length) override - { - std::copy(s, s + length, std::back_inserter(v)); - } - - private: - std::vector<CharType>& v; -}; - -/// output adapter for output streams -template<typename CharType> -class output_stream_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {} - - void write_character(CharType c) override - { - stream.put(c); - } - - void write_characters(const CharType* s, std::size_t length) override - { - stream.write(s, static_cast<std::streamsize>(length)); - } - - private: - std::basic_ostream<CharType>& stream; -}; - -/// output adapter for basic_string -template<typename CharType> -class output_string_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {} - - void write_character(CharType c) override - { - str.push_back(c); - } - - void write_characters(const CharType* s, std::size_t length) override - { - str.append(s, length); - } - - private: - std::basic_string<CharType>& str; -}; - -template<typename CharType> -class output_adapter -{ - public: - output_adapter(std::vector<CharType>& vec) - : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {} - - output_adapter(std::basic_ostream<CharType>& s) - : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} - - output_adapter(std::basic_string<CharType>& s) - : oa(std::make_shared<output_string_adapter<CharType>>(s)) {} - - operator output_adapter_t<CharType>() - { - return oa; - } - - private: - output_adapter_t<CharType> oa = nullptr; -}; - ////////////////////////////// // binary reader and writer // //////////////////////////////