99#include " ../external/double.hh"
1010#include " ../value.hh"
1111
12+ #include " escape.hh"
13+ #include " value_writer.hh"
14+ #include " write.hh"
15+
1216namespace tao
1317{
1418 namespace json
1519 {
1620 namespace internal
1721 {
18- inline void to_stream ( std::ostream & o, const std::string & s )
22+ template < template < typename ... > class Traits >
23+ void to_stream ( std::ostream & o, const basic_value< Traits > & v )
1924 {
20- static const char * h = " 0123456789abcdef" ;
21-
22- o << ' "' ;
23- const char * p = s.data ();
24- const char * l = p;
25- const char * const e = s.data () + s.size ();
26- while ( p != e ) {
27- const unsigned char c = *p;
28- if ( c == ' \\ ' ) {
29- o.write ( l, p - l );
30- l = ++p;
31- o << " \\\\ " ;
32- }
33- else if ( c == ' "' ) {
34- o.write ( l, p - l );
35- l = ++p;
36- o << " \\\" " ;
37- }
38- else if ( c < 32 ) {
39- o.write ( l, p - l );
40- l = ++p;
41- switch ( c ) {
42- case ' \b ' :
43- o << " \\ b" ;
44- break ;
45- case ' \f ' :
46- o << " \\ f" ;
47- break ;
48- case ' \n ' :
49- o << " \\ n" ;
50- break ;
51- case ' \r ' :
52- o << " \\ r" ;
53- break ;
54- case ' \t ' :
55- o << " \\ t" ;
56- break ;
57- default :
58- o << " \\ u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ];
59- }
60- }
61- else if ( c == 127 ) {
62- o.write ( l, p - l );
63- l = ++p;
64- o << " \\ u007f" ;
65- }
66- else {
67- ++p;
68- }
69- }
70- o.write ( l, p - l );
71- o << ' "' ;
25+ internal::value_writer writer ( o );
26+ internal::write ( v, writer );
7227 }
7328
74- template < template < typename ... > class Traits >
75- void to_stream ( std::ostream & o, const basic_value< Traits > & v );
76-
7729 template < template < typename ... > class Traits >
7830 void to_stream ( std::ostream & o, const basic_value< Traits > & v, const unsigned indent, const unsigned current = 0 );
7931
80- template < template < typename ... > class Traits >
81- void to_stream ( std::ostream & o, const std::vector< basic_value< Traits > > & v )
82- {
83- o << ' [' ;
84- if ( ! v.empty () ) {
85- internal::to_stream ( o, v[ 0 ] );
86- for ( std::size_t i = 1 ; i < v.size (); ++i ) {
87- o << ' ,' ;
88- internal::to_stream ( o, v[ i ] );
89- }
90- }
91- o << ' ]' ;
92- }
93-
9432 template < template < typename ... > class Traits >
9533 void to_stream ( std::ostream & o, const std::vector< basic_value< Traits > > & v, const unsigned indent, unsigned current = 0 )
9634 {
9735 o << ' [' ;
98- current += indent;
99- const std::string padding = std::string ( current, ' ' );
10036 if ( ! v.empty () ) {
37+ current += indent;
38+ const std::string padding = std::string ( current, ' ' );
10139 o << ' \n ' ;
10240 o << padding;
10341 internal::to_stream ( o, v[ 0 ], indent, current );
@@ -112,40 +50,22 @@ namespace tao
11250 o << ' ]' ;
11351 }
11452
115- template < template < typename ... > class Traits >
116- void to_stream ( std::ostream & o, const std::map< std::string, basic_value< Traits > > & v )
117- {
118- o << ' {' ;
119- if ( ! v.empty () ) {
120- internal::to_stream ( o, v.begin ()->first );
121- o << ' :' ;
122- internal::to_stream ( o, v.begin ()->second );
123- for ( auto i = ++v.begin (); i != v.end (); ++i ) {
124- o << ' ,' ;
125- internal::to_stream ( o, i->first );
126- o << ' :' ;
127- internal::to_stream ( o, i->second );
128- }
129- }
130- o << ' }' ;
131- }
132-
13353 template < template < typename ... > class Traits >
13454 void to_stream ( std::ostream & o, const std::map< std::string, basic_value< Traits > > & v, const unsigned indent, unsigned current = 0 )
13555 {
13656 o << ' {' ;
137- current += indent;
138- const std::string padding = std::string ( current, ' ' );
13957 if ( ! v.empty () ) {
58+ current += indent;
59+ const std::string padding = std::string ( current, ' ' );
14060 o << ' \n ' ;
14161 o << padding;
142- internal::to_stream ( o, v.begin ()->first );
62+ internal::escape ( o, v.begin ()->first );
14363 o << " : " ;
14464 internal::to_stream ( o, v.begin ()->second , indent, current );
14565 for ( auto i = ++v.begin (); i != v.end (); ++i ) {
14666 o << " ,\n " ;
14767 o << padding;
148- internal::to_stream ( o, i->first );
68+ internal::escape ( o, i->first );
14969 o << " : " ;
15070 internal::to_stream ( o, i->second , indent, current );
15171 }
@@ -155,52 +75,6 @@ namespace tao
15575 o << ' }' ;
15676 }
15777
158- template < template < typename ... > class Traits >
159- void to_stream ( std::ostream & o, const basic_value< Traits > & v )
160- {
161- switch ( v.type () ) {
162- case type::NULL_:
163- o.write ( " null" , 4 );
164- return ;
165- case type::BOOL:
166- if ( v.unsafe_get_bool () ) {
167- o.write ( " true" , 4 );
168- }
169- else {
170- o.write ( " false" , 5 );
171- }
172- return ;
173- case type::SIGNED:
174- o << v.unsafe_get_signed ();
175- return ;
176- case type::UNSIGNED:
177- o << v.unsafe_get_unsigned ();
178- return ;
179- case type::DOUBLE:
180- // Assumes std::isfinite( v.unsafe_get_double() ).
181- json_double_conversion::Dtostr ( o, v.unsafe_get_double () );
182- return ;
183- case type::STRING:
184- internal::to_stream ( o, v.unsafe_get_string () );
185- return ;
186- case type::ARRAY:
187- internal::to_stream ( o, v.unsafe_get_array () );
188- return ;
189- case type::OBJECT:
190- internal::to_stream ( o, v.unsafe_get_object () );
191- return ;
192- case type::POINTER:
193- if ( const basic_value< Traits > * p = v.unsafe_get_pointer () ) {
194- internal::to_stream ( o, * p );
195- }
196- else {
197- o.write ( " null" , 4 );
198- }
199- return ;
200- }
201- assert ( false ); // LCOV_EXCL_LINE
202- }
203-
20478 template < template < typename ... > class Traits >
20579 void to_stream ( std::ostream & o, const basic_value< Traits > & v, const unsigned indent, const unsigned current )
20680 {
@@ -227,7 +101,7 @@ namespace tao
227101 json_double_conversion::Dtostr ( o, v.unsafe_get_double () );
228102 return ;
229103 case type::STRING:
230- internal::to_stream ( o, v.unsafe_get_string () );
104+ internal::escape ( o, v.unsafe_get_string () );
231105 return ;
232106 case type::ARRAY:
233107 internal::to_stream ( o, v.unsafe_get_array (), indent, current );
0 commit comments