Skip to content

Commit 1ada251

Browse files
committed
Refactor, split out SAX producer and consumer
1 parent 38e9c33 commit 1ada251

File tree

3 files changed

+196
-148
lines changed

3 files changed

+196
-148
lines changed

contrib/nlohmann.cc

Lines changed: 9 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "test.hh"
55

66
#include "nlohmann/json.hpp"
7+
#include "nlohmann/to_value.hh"
8+
#include "nlohmann/traverse_value.hh"
79

810
#include <tao/json/sax/from_string.hh>
911
#include <tao/json/sax/to_stream.hh>
@@ -12,175 +14,34 @@ namespace tao
1214
{
1315
namespace json
1416
{
15-
namespace
16-
{
17-
// SAX consumer to build an nlohmann/json value
18-
class to_nlohmann
19-
{
20-
private:
21-
std::vector< nlohmann::json > stack_;
22-
std::vector< std::string > keys_;
23-
24-
public:
25-
nlohmann::json value;
26-
27-
void null()
28-
{
29-
value = nullptr;
30-
}
31-
32-
void boolean( const bool v )
33-
{
34-
value = v;
35-
}
36-
37-
void number( const std::int64_t v )
38-
{
39-
value = v;
40-
}
41-
42-
void number( const std::uint64_t v )
43-
{
44-
value = v;
45-
}
46-
47-
void number( const double v )
48-
{
49-
value = v;
50-
}
51-
52-
void string( const std::string & v )
53-
{
54-
value = v;
55-
}
56-
57-
void string( std::string && v )
58-
{
59-
value = std::move( v );
60-
}
61-
62-
// array
63-
void begin_array()
64-
{
65-
stack_.push_back( nlohmann::json::array() );
66-
}
67-
68-
void element()
69-
{
70-
stack_.back().push_back( std::move( value ) );
71-
}
72-
73-
void end_array()
74-
{
75-
value = std::move( stack_.back() );
76-
stack_.pop_back();
77-
}
78-
79-
// object
80-
void begin_object()
81-
{
82-
stack_.push_back( nlohmann::json::object() );
83-
}
84-
85-
void key( const std::string & v )
86-
{
87-
keys_.push_back( v );
88-
}
89-
90-
void key( std::string && v )
91-
{
92-
keys_.push_back( std::move( v ) );
93-
}
94-
95-
void member()
96-
{
97-
stack_.back().push_back( nlohmann::json::object_t::value_type( std::move( keys_.back() ), std::move( value ) ) );
98-
keys_.pop_back();
99-
}
100-
101-
void end_object()
102-
{
103-
value = std::move( stack_.back() );
104-
stack_.pop_back();
105-
}
106-
};
107-
108-
// SAX producer for an nlohmann/json value
109-
template< typename Handler >
110-
void traverse_nlohmann( const nlohmann::json & v, Handler & handler )
111-
{
112-
switch( v.type() ) {
113-
case nlohmann::json::value_t::null:
114-
handler.null();
115-
break;
116-
case nlohmann::json::value_t::boolean:
117-
handler.boolean( v.get< bool >() );
118-
break;
119-
case nlohmann::json::value_t::number_integer:
120-
handler.number( v.get< std::int64_t >() );
121-
break;
122-
case nlohmann::json::value_t::number_unsigned:
123-
handler.number( v.get< std::uint64_t >() );
124-
break;
125-
case nlohmann::json::value_t::number_float:
126-
handler.number( v.get< double >() );
127-
break;
128-
case nlohmann::json::value_t::string:
129-
handler.string( v.get_ref< const std::string & >() );
130-
break;
131-
case nlohmann::json::value_t::array:
132-
handler.begin_array();
133-
for( const auto & e : v ) {
134-
traverse_nlohmann( e, handler );
135-
handler.element();
136-
}
137-
handler.end_array();
138-
break;
139-
case nlohmann::json::value_t::object:
140-
handler.begin_object();
141-
for( nlohmann::json::const_iterator it = v.begin(); it != v.end(); ++it ) {
142-
handler.key( it.key() );
143-
traverse_nlohmann( it.value(), handler );
144-
handler.member();
145-
}
146-
handler.end_object();
147-
break;
148-
default:
149-
throw std::logic_error( "invalid value for nohmann::json::type()" ); // LCOV_EXCL_LINE
150-
}
151-
}
152-
153-
} //
154-
15517
void unit_test()
15618
{
157-
// combine a taocpp/json SAX parser (using the PEGTL) with the above
158-
to_nlohmann handler;
159-
sax::from_string( "[ null, true, false, 42, 43.0, \"foo\", [ 1, 2, 3 ], { \"a\" : \"b\", \"c\" : \"d\" } ]", handler );
19+
tao::json::nlohmann::to_value handler;
20+
tao::json::sax::from_string( "[ null, true, false, 42, 43.0, \"foo\", [ 1, 2, 3 ], { \"a\" : \"b\", \"c\" : \"d\" } ]", handler );
16021

16122
const auto & v = handler.value;
16223

163-
TEST_ASSERT( v.type() == nlohmann::json::value_t::array );
24+
TEST_ASSERT( v.type() == ::nlohmann::json::value_t::array );
16425
TEST_ASSERT( v.size() == 8 );
16526
TEST_ASSERT( v[ 0 ] == nullptr );
16627
TEST_ASSERT( v[ 1 ].get< bool >() == true );
16728
TEST_ASSERT( v[ 2 ].get< bool >() == false );
16829
TEST_ASSERT( v[ 3 ] == 42 );
16930
TEST_ASSERT( v[ 4 ] == 43.0 );
17031
TEST_ASSERT( v[ 5 ] == "foo" );
171-
TEST_ASSERT( v[ 6 ].type() == nlohmann::json::value_t::array );
32+
TEST_ASSERT( v[ 6 ].type() == ::nlohmann::json::value_t::array );
17233
TEST_ASSERT( v[ 6 ].size() == 3 );
17334
TEST_ASSERT( v[ 6 ][ 0 ] == 1 );
17435
TEST_ASSERT( v[ 6 ][ 1 ] == 2 );
17536
TEST_ASSERT( v[ 6 ][ 2 ] == 3 );
176-
TEST_ASSERT( v[ 7 ].type() == nlohmann::json::value_t::object );
37+
TEST_ASSERT( v[ 7 ].type() == ::nlohmann::json::value_t::object );
17738
TEST_ASSERT( v[ 7 ].size() == 2 );
17839
TEST_ASSERT( v[ 7 ].at( "a" ) == "b" );
17940
TEST_ASSERT( v[ 7 ].at( "c" ) == "d" );
18041

18142
std::ostringstream oss;
182-
sax::to_stream oss_handler( oss );
183-
traverse_nlohmann( v, oss_handler );
43+
tao::json::sax::to_stream oss_handler( oss );
44+
tao::json::nlohmann::traverse_value( v, oss_handler );
18445

18546
TEST_ASSERT( oss.str() == "[null,true,false,42,43.0,\"foo\",[1,2,3],{\"a\":\"b\",\"c\":\"d\"}]" );
18647
}

contrib/nlohmann/to_value.hh

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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_JSON_NLOHMANN_TO_VALUE_HH
5+
#define TAOCPP_JSON_INCLUDE_JSON_NLOHMANN_TO_VALUE_HH
6+
7+
#include <vector>
8+
#include <string>
9+
#include <cstdint>
10+
#include <utility>
11+
12+
#include "json.hpp"
13+
14+
namespace tao
15+
{
16+
namespace json
17+
{
18+
namespace nlohmann
19+
{
20+
// SAX consumer to build an nlohmann/json value
21+
class to_value
22+
{
23+
private:
24+
std::vector< ::nlohmann::json > stack_;
25+
std::vector< std::string > keys_;
26+
27+
public:
28+
::nlohmann::json value;
29+
30+
void null()
31+
{
32+
value = nullptr;
33+
}
34+
35+
void boolean( const bool v )
36+
{
37+
value = v;
38+
}
39+
40+
void number( const std::int64_t v )
41+
{
42+
value = v;
43+
}
44+
45+
void number( const std::uint64_t v )
46+
{
47+
value = v;
48+
}
49+
50+
void number( const double v )
51+
{
52+
value = v;
53+
}
54+
55+
void string( const std::string & v )
56+
{
57+
value = v;
58+
}
59+
60+
void string( std::string && v )
61+
{
62+
value = std::move( v );
63+
}
64+
65+
// array
66+
void begin_array()
67+
{
68+
stack_.push_back( ::nlohmann::json::array() );
69+
}
70+
71+
void element()
72+
{
73+
stack_.back().push_back( std::move( value ) );
74+
}
75+
76+
void end_array()
77+
{
78+
value = std::move( stack_.back() );
79+
stack_.pop_back();
80+
}
81+
82+
// object
83+
void begin_object()
84+
{
85+
stack_.push_back( ::nlohmann::json::object() );
86+
}
87+
88+
void key( const std::string & v )
89+
{
90+
keys_.push_back( v );
91+
}
92+
93+
void key( std::string && v )
94+
{
95+
keys_.push_back( std::move( v ) );
96+
}
97+
98+
void member()
99+
{
100+
stack_.back().push_back( ::nlohmann::json::object_t::value_type( std::move( keys_.back() ), std::move( value ) ) );
101+
keys_.pop_back();
102+
}
103+
104+
void end_object()
105+
{
106+
value = std::move( stack_.back() );
107+
stack_.pop_back();
108+
}
109+
};
110+
111+
} // nlohmann
112+
113+
} // json
114+
115+
} // tao
116+
117+
#endif

contrib/nlohmann/traverse_value.hh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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_JSON_NLOHMANN_TO_VALUE_HH
5+
#define TAOCPP_JSON_INCLUDE_JSON_NLOHMANN_TO_VALUE_HH
6+
7+
#include <cstdint>
8+
#include <string>
9+
#include <stdexcept>
10+
11+
#include "json.hpp"
12+
13+
namespace tao
14+
{
15+
namespace json
16+
{
17+
namespace nlohmann
18+
{
19+
// SAX producer for an nlohmann/json value
20+
template< typename Handler >
21+
void traverse_nlohmann( const nlohmann::json & v, Handler & handler )
22+
{
23+
switch( v.type() ) {
24+
case nlohmann::json::value_t::null:
25+
handler.null();
26+
break;
27+
case nlohmann::json::value_t::boolean:
28+
handler.boolean( v.get< bool >() );
29+
break;
30+
case nlohmann::json::value_t::number_integer:
31+
handler.number( v.get< std::int64_t >() );
32+
break;
33+
case nlohmann::json::value_t::number_unsigned:
34+
handler.number( v.get< std::uint64_t >() );
35+
break;
36+
case nlohmann::json::value_t::number_float:
37+
handler.number( v.get< double >() );
38+
break;
39+
case nlohmann::json::value_t::string:
40+
handler.string( v.get_ref< const std::string & >() );
41+
break;
42+
case nlohmann::json::value_t::array:
43+
handler.begin_array();
44+
for( const auto & e : v ) {
45+
traverse_nlohmann( e, handler );
46+
handler.element();
47+
}
48+
handler.end_array();
49+
break;
50+
case nlohmann::json::value_t::object:
51+
handler.begin_object();
52+
for( nlohmann::json::const_iterator it = v.begin(); it != v.end(); ++it ) {
53+
handler.key( it.key() );
54+
traverse_nlohmann( it.value(), handler );
55+
handler.member();
56+
}
57+
handler.end_object();
58+
break;
59+
default:
60+
throw std::logic_error( "invalid value for nohmann::json::type()" ); // LCOV_EXCL_LINE
61+
}
62+
}
63+
64+
} // nlohmann
65+
66+
} // json
67+
68+
} // tao
69+
70+
#endif

0 commit comments

Comments
 (0)