99#include " ../external/double.hh"
1010#include " ../value.hh"
1111
12- #include " escape.hh"
13-
1412namespace tao
1513{
1614 namespace json
@@ -19,7 +17,80 @@ namespace tao
1917 {
2018 inline void to_stream ( std::ostream & o, const std::string & s )
2119 {
22- o << escape ( s ); // TODO: Check whether direct-to-stream is faster.
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+ switch ( const unsigned char c = *p ) {
28+ case ' \b ' :
29+ if ( l != p ) {
30+ o.write ( l, p - l );
31+ }
32+ l = ++p;
33+ o << " \\ b" ;
34+ break ;
35+ case ' \f ' :
36+ if ( l != p ) {
37+ o.write ( l, p - l );
38+ }
39+ l = ++p;
40+ o << " \\ f" ;
41+ break ;
42+ case ' \n ' :
43+ if ( l != p ) {
44+ o.write ( l, p - l );
45+ }
46+ l = ++p;
47+ o << " \\ n" ;
48+ break ;
49+ case ' \r ' :
50+ if ( l != p ) {
51+ o.write ( l, p - l );
52+ }
53+ l = ++p;
54+ o << " \\ r" ;
55+ break ;
56+ case ' \t ' :
57+ if ( l != p ) {
58+ o.write ( l, p - l );
59+ }
60+ l = ++p;
61+ o << " \\ t" ;
62+ break ;
63+ case ' \\ ' :
64+ if ( l != p ) {
65+ o.write ( l, p - l );
66+ }
67+ l = ++p;
68+ o << " \\\\ " ;
69+ break ;
70+ case ' \" ' :
71+ if ( l != p ) {
72+ o.write ( l, p - l );
73+ }
74+ l = ++p;
75+ o << " \\\" " ;
76+ break ;
77+ default :
78+ if ( ( c < 32 ) || ( c == 127 ) ) {
79+ if ( l != p ) {
80+ o.write ( l, p - l );
81+ }
82+ l = ++p;
83+ o << " \\ u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ];
84+ }
85+ else {
86+ ++p;
87+ }
88+ }
89+ }
90+ if ( l != p ) {
91+ o.write ( l, p - l );
92+ }
93+ o << ' "' ;
2394 }
2495
2596 template < template < typename ... > class Traits >
@@ -111,10 +182,15 @@ namespace tao
111182 {
112183 switch ( v.type () ) {
113184 case type::NULL_:
114- o << " null" ;
185+ o. write ( " null" , 4 ) ;
115186 return ;
116187 case type::BOOL:
117- o << ( v.unsafe_get_bool () ? " true" : " false" );
188+ if ( v.unsafe_get_bool () ) {
189+ o.write ( " true" , 4 );
190+ }
191+ else {
192+ o.write ( " false" , 5 );
193+ }
118194 return ;
119195 case type::SIGNED:
120196 o << v.unsafe_get_signed ();
@@ -140,7 +216,7 @@ namespace tao
140216 internal::to_stream ( o, * p );
141217 }
142218 else {
143- o << " null" ;
219+ o. write ( " null" , 4 ) ;
144220 }
145221 return ;
146222 }
@@ -152,10 +228,15 @@ namespace tao
152228 {
153229 switch ( v.type () ) {
154230 case type::NULL_:
155- o << " null" ;
231+ o. write ( " null" , 4 ) ;
156232 return ;
157233 case type::BOOL:
158- o << ( v.unsafe_get_bool () ? " true" : " false" );
234+ if ( v.unsafe_get_bool () ) {
235+ o.write ( " true" , 4 );
236+ }
237+ else {
238+ o.write ( " false" , 5 );
239+ }
159240 return ;
160241 case type::SIGNED:
161242 o << v.unsafe_get_signed ();
@@ -181,7 +262,7 @@ namespace tao
181262 internal::to_stream ( o, * p, indent, current );
182263 }
183264 else {
184- o << " null" ;
265+ o. write ( " null" , 4 ) ;
185266 }
186267 return ;
187268 }
0 commit comments