Skip to content

Commit 3a0be14

Browse files
committed
Switch pretty printer to SAX handler API
1 parent 829e2ef commit 3a0be14

File tree

2 files changed

+162
-91
lines changed

2 files changed

+162
-91
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
2+
// Please see LICENSE for license or visit https://github.com/taocpp/json/
3+
4+
#ifndef TAOCPP_JSON_INCLUDE_INTERNAL_PRETTY_WRITER_HH
5+
#define TAOCPP_JSON_INCLUDE_INTERNAL_PRETTY_WRITER_HH
6+
7+
#include <ostream>
8+
9+
#include "escape.hh"
10+
11+
#include "../external/double.hh"
12+
13+
namespace tao
14+
{
15+
namespace json
16+
{
17+
namespace internal
18+
{
19+
class pretty_writer
20+
{
21+
private:
22+
std::ostream & os;
23+
const std::size_t indent;
24+
std::string current;
25+
bool first = true;
26+
bool after_key = false;
27+
28+
void next()
29+
{
30+
if ( after_key ) {
31+
after_key = false;
32+
}
33+
else {
34+
os << current;
35+
}
36+
}
37+
38+
public:
39+
pretty_writer( std::ostream & os, const std::size_t indent )
40+
: os( os ),
41+
indent( indent )
42+
{ }
43+
44+
void null()
45+
{
46+
next();
47+
os.write( "null", 4 );
48+
}
49+
50+
void boolean( const bool v )
51+
{
52+
next();
53+
if ( v ) {
54+
os.write( "true", 4 );
55+
}
56+
else {
57+
os.write( "false", 5 );
58+
}
59+
}
60+
61+
void number( const std::int64_t v )
62+
{
63+
next();
64+
os << v;
65+
}
66+
67+
void number( const std::uint64_t v )
68+
{
69+
next();
70+
os << v;
71+
}
72+
73+
void number( const double v )
74+
{
75+
next();
76+
json_double_conversion::Dtostr( os, v );
77+
}
78+
79+
void string( const std::string & v )
80+
{
81+
next();
82+
internal::escape( os, v );
83+
}
84+
85+
// array
86+
void begin_array()
87+
{
88+
next();
89+
os.put( '[' );
90+
if ( current.empty() ) {
91+
current = '\n';
92+
}
93+
current.resize( current.size() + indent, ' ' );
94+
first = true;
95+
}
96+
97+
void element()
98+
{
99+
os.put( ',' );
100+
first = false;
101+
}
102+
103+
void end_array()
104+
{
105+
current.resize( current.size() - indent );
106+
if ( ! first ) {
107+
os.seekp( -1, std::ios_base::cur );
108+
os << current;
109+
}
110+
os.put( ']' );
111+
first = false;
112+
}
113+
114+
// object
115+
void begin_object()
116+
{
117+
next();
118+
os.put( '{' );
119+
if ( current.empty() ) {
120+
current = '\n';
121+
}
122+
current.resize( current.size() + indent, ' ' );
123+
first = true;
124+
}
125+
126+
void key( const std::string & v )
127+
{
128+
next();
129+
internal::escape( os, v );
130+
os.write( ": ", 2 );
131+
after_key = true;
132+
}
133+
134+
void value()
135+
{
136+
os.put( ',' );
137+
first = false;
138+
}
139+
140+
void end_object()
141+
{
142+
current.resize( current.size() - indent );
143+
if ( ! first ) {
144+
os.seekp( -1, std::ios_base::cur );
145+
os << current;
146+
}
147+
os.put( '}' );
148+
first = false;
149+
}
150+
};
151+
152+
} // internal
153+
154+
} // json
155+
156+
} // tao
157+
158+
#endif

include/tao/json/internal/to_stream.hh

Lines changed: 4 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "escape.hh"
1313
#include "value_writer.hh"
14+
#include "pretty_writer.hh"
1415
#include "write.hh"
1516

1617
namespace tao
@@ -27,98 +28,10 @@ namespace tao
2728
}
2829

2930
template< template< typename ... > class Traits >
30-
void to_stream( std::ostream & o, const basic_value< Traits > & v, const unsigned indent, const unsigned current = 0 );
31-
32-
template< template< typename ... > class Traits >
33-
void to_stream( std::ostream & o, const std::vector< basic_value< Traits > > & v, const unsigned indent, unsigned current = 0 )
34-
{
35-
o << '[';
36-
if ( ! v.empty() ) {
37-
current += indent;
38-
const std::string padding = std::string( current, ' ' );
39-
o << '\n';
40-
o << padding;
41-
internal::to_stream( o, v[ 0 ], indent, current );
42-
for ( std::size_t i = 1; i < v.size(); ++i ) {
43-
o << ",\n";
44-
o << padding;
45-
internal::to_stream( o, v[ i ], indent, current );
46-
}
47-
o << '\n';
48-
o.write( padding.data(), current - indent );
49-
}
50-
o << ']';
51-
}
52-
53-
template< template< typename ... > class Traits >
54-
void to_stream( std::ostream & o, const std::map< std::string, basic_value< Traits > > & v, const unsigned indent, unsigned current = 0 )
31+
void to_stream( std::ostream & o, const basic_value< Traits > & v, const unsigned indent )
5532
{
56-
o << '{';
57-
if ( ! v.empty() ) {
58-
current += indent;
59-
const std::string padding = std::string( current, ' ' );
60-
o << '\n';
61-
o << padding;
62-
internal::escape( o, v.begin()->first );
63-
o << ": ";
64-
internal::to_stream( o, v.begin()->second, indent, current );
65-
for ( auto i = ++v.begin(); i != v.end(); ++i ) {
66-
o << ",\n";
67-
o << padding;
68-
internal::escape( o, i->first );
69-
o << ": ";
70-
internal::to_stream( o, i->second, indent, current );
71-
}
72-
o << '\n';
73-
o.write( padding.data(), current - indent );
74-
}
75-
o << '}';
76-
}
77-
78-
template< template< typename ... > class Traits >
79-
void to_stream( std::ostream & o, const basic_value< Traits > & v, const unsigned indent, const unsigned current )
80-
{
81-
switch ( v.type() ) {
82-
case type::NULL_:
83-
o.write( "null", 4 );
84-
return;
85-
case type::BOOL:
86-
if ( v.unsafe_get_bool() ) {
87-
o.write( "true", 4 );
88-
}
89-
else {
90-
o.write( "false", 5 );
91-
}
92-
return;
93-
case type::SIGNED:
94-
o << v.unsafe_get_signed();
95-
return;
96-
case type::UNSIGNED:
97-
o << v.unsafe_get_unsigned();
98-
return;
99-
case type::DOUBLE:
100-
// Assumes std::isfinite( v.unsafe_get_double() ).
101-
json_double_conversion::Dtostr( o, v.unsafe_get_double() );
102-
return;
103-
case type::STRING:
104-
internal::escape( o, v.unsafe_get_string() );
105-
return;
106-
case type::ARRAY:
107-
internal::to_stream( o, v.unsafe_get_array(), indent, current );
108-
return;
109-
case type::OBJECT:
110-
internal::to_stream( o, v.unsafe_get_object(), indent, current );
111-
return;
112-
case type::POINTER:
113-
if ( const basic_value< Traits > * p = v.unsafe_get_pointer() ) {
114-
internal::to_stream( o, * p, indent, current );
115-
}
116-
else {
117-
o.write( "null", 4 );
118-
}
119-
return;
120-
}
121-
assert( false ); // LCOV_EXCL_LINE
33+
internal::pretty_writer writer( o, indent );
34+
internal::write( v, writer );
12235
}
12336

12437
} // internal

0 commit comments

Comments
 (0)