Skip to content

Commit 4d78639

Browse files
committed
Switch to SAX writer
1 parent 4117ff1 commit 4d78639

File tree

10 files changed

+351
-146
lines changed

10 files changed

+351
-146
lines changed

include/tao/json/internal/action.hh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ namespace tao
7070
}
7171
};
7272

73+
template<>
74+
struct action< rules::element_separator >
75+
{
76+
template< typename State >
77+
static void apply( const tao_json_pegtl::input &, State & handler )
78+
{
79+
handler.element_separator();
80+
}
81+
};
82+
7383
template<>
7484
struct action< rules::array::end >
7585
{
@@ -100,6 +110,26 @@ namespace tao
100110
}
101111
};
102112

113+
template<>
114+
struct action< rules::name_separator >
115+
{
116+
template< typename State >
117+
static void apply( const tao_json_pegtl::input &, State & handler )
118+
{
119+
handler.name_separator();
120+
}
121+
};
122+
123+
template<>
124+
struct action< rules::value_separator >
125+
{
126+
template< typename State >
127+
static void apply( const tao_json_pegtl::input &, State & handler )
128+
{
129+
handler.value_separator();
130+
}
131+
};
132+
103133
template<>
104134
struct action< rules::object::end >
105135
{
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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_ESCAPE_HH
5+
#define TAOCPP_JSON_INCLUDE_INTERNAL_ESCAPE_HH
6+
7+
#include <ostream>
8+
#include <string>
9+
10+
namespace tao
11+
{
12+
namespace json
13+
{
14+
namespace internal
15+
{
16+
inline void escape( std::ostream & o, const std::string & s )
17+
{
18+
static const char * h = "0123456789abcdef";
19+
20+
o << '"';
21+
const char * p = s.data();
22+
const char * l = p;
23+
const char * const e = s.data() + s.size();
24+
while ( p != e ) {
25+
const unsigned char c = *p;
26+
if ( c == '\\' ) {
27+
o.write( l, p - l );
28+
l = ++p;
29+
o << "\\\\";
30+
}
31+
else if ( c == '"' ) {
32+
o.write( l, p - l );
33+
l = ++p;
34+
o << "\\\"";
35+
}
36+
else if ( c < 32 ) {
37+
o.write( l, p - l );
38+
l = ++p;
39+
switch ( c ) {
40+
case '\b':
41+
o << "\\b";
42+
break;
43+
case '\f':
44+
o << "\\f";
45+
break;
46+
case '\n':
47+
o << "\\n";
48+
break;
49+
case '\r':
50+
o << "\\r";
51+
break;
52+
case '\t':
53+
o << "\\t";
54+
break;
55+
default:
56+
o << "\\u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ];
57+
}
58+
}
59+
else if ( c == 127 ) {
60+
o.write( l, p - l );
61+
l = ++p;
62+
o << "\\u007f";
63+
}
64+
else {
65+
++p;
66+
}
67+
}
68+
o.write( l, p - l );
69+
o << '"';
70+
}
71+
72+
} // internal
73+
74+
} // json
75+
76+
} // tao
77+
78+
#endif

include/tao/json/internal/grammar.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace tao
2727
struct end_object : one< '}' > {};
2828
struct name_separator : pad< one< ':' >, ws > {};
2929
struct value_separator : padr< one< ',' > > {};
30+
struct element_separator : padr< one< ',' > > {};
3031

3132
struct false_ : tao_json_pegtl_string_t( "false" ) {};
3233
struct null : tao_json_pegtl_string_t( "null" ) {};
@@ -92,7 +93,7 @@ namespace tao
9293
struct value;
9394

9495
struct array_element;
95-
struct array_content : opt< list_must< array_element, value_separator > > {};
96+
struct array_content : opt< list_must< array_element, element_separator > > {};
9697
struct array : seq< begin_array, array_content, must< end_array > >
9798
{
9899
using begin = begin_array;

include/tao/json/internal/to_stream.hh

Lines changed: 15 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -9,95 +9,33 @@
99
#include "../external/double.hh"
1010
#include "../value.hh"
1111

12+
#include "escape.hh"
13+
#include "value_writer.hh"
14+
#include "write.hh"
15+
1216
namespace 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

Comments
 (0)