• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #include <algorithm> // copy
4 #include <cstddef> // size_t
5 #include <iterator> // back_inserter
6 #include <memory> // shared_ptr, make_shared
7 #include <string> // basic_string
8 #include <vector> // vector
9 
10 #ifndef JSON_NO_IO
11     #include <ios>      // streamsize
12     #include <ostream>  // basic_ostream
13 #endif  // JSON_NO_IO
14 
15 #include <nlohmann/detail/macro_scope.hpp>
16 
17 namespace nlohmann
18 {
19 namespace detail
20 {
21 /// abstract output adapter interface
22 template<typename CharType> struct output_adapter_protocol
23 {
24     virtual void write_character(CharType c) = 0;
25     virtual void write_characters(const CharType* s, std::size_t length) = 0;
26     virtual ~output_adapter_protocol() = default;
27 
28     output_adapter_protocol() = default;
29     output_adapter_protocol(const output_adapter_protocol&) = default;
30     output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
31     output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
32     output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
33 };
34 
35 /// a type to simplify interfaces
36 template<typename CharType>
37 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
38 
39 /// output adapter for byte vectors
40 template<typename CharType>
41 class output_vector_adapter : public output_adapter_protocol<CharType>
42 {
43   public:
output_vector_adapter(std::vector<CharType> & vec)44     explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
45         : v(vec)
46     {}
47 
write_character(CharType c)48     void write_character(CharType c) override
49     {
50         v.push_back(c);
51     }
52 
53     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)54     void write_characters(const CharType* s, std::size_t length) override
55     {
56         std::copy(s, s + length, std::back_inserter(v));
57     }
58 
59   private:
60     std::vector<CharType>& v;
61 };
62 
63 #ifndef JSON_NO_IO
64 /// output adapter for output streams
65 template<typename CharType>
66 class output_stream_adapter : public output_adapter_protocol<CharType>
67 {
68   public:
output_stream_adapter(std::basic_ostream<CharType> & s)69     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
70         : stream(s)
71     {}
72 
write_character(CharType c)73     void write_character(CharType c) override
74     {
75         stream.put(c);
76     }
77 
78     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)79     void write_characters(const CharType* s, std::size_t length) override
80     {
81         stream.write(s, static_cast<std::streamsize>(length));
82     }
83 
84   private:
85     std::basic_ostream<CharType>& stream;
86 };
87 #endif  // JSON_NO_IO
88 
89 /// output adapter for basic_string
90 template<typename CharType, typename StringType = std::basic_string<CharType>>
91 class output_string_adapter : public output_adapter_protocol<CharType>
92 {
93   public:
output_string_adapter(StringType & s)94     explicit output_string_adapter(StringType& s) noexcept
95         : str(s)
96     {}
97 
write_character(CharType c)98     void write_character(CharType c) override
99     {
100         str.push_back(c);
101     }
102 
103     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)104     void write_characters(const CharType* s, std::size_t length) override
105     {
106         str.append(s, length);
107     }
108 
109   private:
110     StringType& str;
111 };
112 
113 template<typename CharType, typename StringType = std::basic_string<CharType>>
114 class output_adapter
115 {
116   public:
output_adapter(std::vector<CharType> & vec)117     output_adapter(std::vector<CharType>& vec)
118         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
119 
120 #ifndef JSON_NO_IO
output_adapter(std::basic_ostream<CharType> & s)121     output_adapter(std::basic_ostream<CharType>& s)
122         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
123 #endif  // JSON_NO_IO
124 
output_adapter(StringType & s)125     output_adapter(StringType& s)
126         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
127 
operator output_adapter_t<CharType>()128     operator output_adapter_t<CharType>()
129     {
130         return oa;
131     }
132 
133   private:
134     output_adapter_t<CharType> oa = nullptr;
135 };
136 }  // namespace detail
137 }  // namespace nlohmann
138