Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
3ff94553
Unverified
Commit
3ff94553
authored
Feb 26, 2018
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
🔨
added a SAX-DOM-Parser
parent
21352c4d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
177 additions
and
44 deletions
+177
-44
json_sax.hpp
include/nlohmann/detail/input/json_sax.hpp
+9
-6
lexer.hpp
include/nlohmann/detail/input/lexer.hpp
+1
-1
parser.hpp
include/nlohmann/detail/input/parser.hpp
+5
-5
json.hpp
include/nlohmann/json.hpp
+4
-4
json.hpp
single_include/nlohmann/json.hpp
+19
-16
unit-class_parser.cpp
test/src/unit-class_parser.cpp
+133
-6
unit-deserialization.cpp
test/src/unit-deserialization.cpp
+6
-6
No files found.
include/nlohmann/detail/input/json_sax.hpp
View file @
3ff94553
...
...
@@ -20,6 +20,9 @@ struct json_sax
/// type for floating-point numbers
using
number_float_t
=
typename
BasicJsonType
::
number_float_t
;
/// constant to indicate that no size limit is given for array or object
static
constexpr
auto
no_limit
=
std
::
size_t
(
-
1
);
/*!
@brief a null value was read
@return whether parsing should proceed
...
...
@@ -60,22 +63,22 @@ struct json_sax
@param[in] val string value
@return whether parsing should proceed
*/
virtual
bool
string
(
const
std
::
string
&
val
)
=
0
;
virtual
bool
string
(
std
::
string
&
&
val
)
=
0
;
/*!
@brief the beginning of an object was read
@param[in] elements number of object elements or
-1
if unknown
@param[in] elements number of object elements or
no_limit
if unknown
@return whether parsing should proceed
@note binary formats may report the number of elements
*/
virtual
bool
start_object
(
std
::
size_t
elements
)
=
0
;
virtual
bool
start_object
(
std
::
size_t
elements
=
no_limit
)
=
0
;
/*!
@brief an object key was read
@param[in] val object key
@return whether parsing should proceed
*/
virtual
bool
key
(
const
std
::
string
&
val
)
=
0
;
virtual
bool
key
(
std
::
string
&
&
val
)
=
0
;
/*!
@brief the end of an object was read
...
...
@@ -85,11 +88,11 @@ struct json_sax
/*!
@brief the beginning of an array was read
@param[in] elements number of array elements or
-1
if unknown
@param[in] elements number of array elements or
no_limit
if unknown
@return whether parsing should proceed
@note binary formats may report the number of elements
*/
virtual
bool
start_array
(
std
::
size_t
elements
)
=
0
;
virtual
bool
start_array
(
std
::
size_t
elements
=
no_limit
)
=
0
;
/*!
@brief the end of an array was read
...
...
include/nlohmann/detail/input/lexer.hpp
View file @
3ff94553
...
...
@@ -1130,7 +1130,7 @@ scan_number_done:
}
/// return current string value (implicitly resets the token; useful only once)
std
::
string
move_string
()
std
::
string
&&
move_string
()
{
return
std
::
move
(
token_buffer
);
}
...
...
include/nlohmann/detail/input/parser.hpp
View file @
3ff94553
...
...
@@ -53,7 +53,7 @@ class parser
value
};
using
json_sax
=
json_sax
<
BasicJsonType
>
;
using
json_sax
_t
=
json_sax
<
BasicJsonType
>
;
using
parser_callback_t
=
std
::
function
<
bool
(
int
depth
,
parse_event_t
event
,
BasicJsonType
&
parsed
)
>
;
...
...
@@ -65,7 +65,7 @@ class parser
:
callback
(
cb
),
m_lexer
(
adapter
),
allow_exceptions
(
allow_exceptions_
)
{}
parser
(
detail
::
input_adapter_t
adapter
,
json_sax
*
s
)
parser
(
detail
::
input_adapter_t
adapter
,
json_sax
_t
*
s
)
:
m_lexer
(
adapter
),
sax
(
s
)
{}
...
...
@@ -541,7 +541,7 @@ class parser
{
case
token_type
:
:
begin_object
:
{
if
(
not
sax
->
start_object
(
std
::
size_t
(
-
1
)
))
if
(
not
sax
->
start_object
())
{
return
false
;
}
...
...
@@ -610,7 +610,7 @@ class parser
case
token_type
:
:
begin_array
:
{
if
(
not
sax
->
start_array
(
std
::
size_t
(
-
1
)
))
if
(
not
sax
->
start_array
())
{
return
false
;
}
...
...
@@ -772,7 +772,7 @@ class parser
/// whether to throw exceptions in case of errors
const
bool
allow_exceptions
=
true
;
/// associated SAX parse event receiver
json_sax
*
sax
=
nullptr
;
json_sax
_t
*
sax
=
nullptr
;
};
}
}
include/nlohmann/json.hpp
View file @
3ff94553
...
...
@@ -1105,7 +1105,7 @@ class basic_json
*/
using
parser_callback_t
=
typename
parser
::
parser_callback_t
;
using
json_sax
=
typename
parser
::
json_sax
;
using
json_sax
_t
=
typename
parser
::
json_sax_t
;
//////////////////
// constructors //
...
...
@@ -5926,12 +5926,12 @@ class basic_json
return
parser
(
i
).
accept
(
true
);
}
static
bool
sax_parse
(
detail
::
input_adapter
i
,
json_sax
*
sax
)
static
bool
sax_parse
(
detail
::
input_adapter
i
,
json_sax
_t
*
sax
)
{
return
parser
(
i
,
sax
).
sax_parse
();
}
static
bool
sax_parse
(
detail
::
input_adapter
&
i
,
json_sax
*
sax
)
static
bool
sax_parse
(
detail
::
input_adapter
&
i
,
json_sax
_t
*
sax
)
{
return
parser
(
i
,
sax
).
sax_parse
();
}
...
...
@@ -6009,7 +6009,7 @@ class basic_json
std
::
is_base_of
<
std
::
random_access_iterator_tag
,
typename
std
::
iterator_traits
<
IteratorType
>::
iterator_category
>::
value
,
int
>::
type
=
0
>
static
bool
sax_parse
(
IteratorType
first
,
IteratorType
last
,
json_sax
*
sax
)
static
bool
sax_parse
(
IteratorType
first
,
IteratorType
last
,
json_sax
_t
*
sax
)
{
return
parser
(
detail
::
input_adapter
(
first
,
last
),
sax
).
sax_parse
();
}
...
...
single_include/nlohmann/json.hpp
View file @
3ff94553
...
...
@@ -2969,7 +2969,7 @@ scan_number_done:
}
/// return current string value (implicitly resets the token; useful only once)
std
::
string
move_string
()
std
::
string
&&
move_string
()
{
return
std
::
move
(
token_buffer
);
}
...
...
@@ -3154,6 +3154,9 @@ struct json_sax
/// type for floating-point numbers
using
number_float_t
=
typename
BasicJsonType
::
number_float_t
;
/// constant to indicate that no size limit is given for array or object
static
constexpr
auto
no_limit
=
std
::
size_t
(
-
1
);
/*!
@brief a null value was read
@return whether parsing should proceed
...
...
@@ -3194,22 +3197,22 @@ struct json_sax
@param[in] val string value
@return whether parsing should proceed
*/
virtual
bool
string
(
const
std
::
string
&
val
)
=
0
;
virtual
bool
string
(
std
::
string
&
&
val
)
=
0
;
/*!
@brief the beginning of an object was read
@param[in] elements number of object elements or
-1
if unknown
@param[in] elements number of object elements or
no_limit
if unknown
@return whether parsing should proceed
@note binary formats may report the number of elements
*/
virtual
bool
start_object
(
std
::
size_t
elements
)
=
0
;
virtual
bool
start_object
(
std
::
size_t
elements
=
no_limit
)
=
0
;
/*!
@brief an object key was read
@param[in] val object key
@return whether parsing should proceed
*/
virtual
bool
key
(
const
std
::
string
&
val
)
=
0
;
virtual
bool
key
(
std
::
string
&
&
val
)
=
0
;
/*!
@brief the end of an object was read
...
...
@@ -3219,11 +3222,11 @@ struct json_sax
/*!
@brief the beginning of an array was read
@param[in] elements number of array elements or
-1
if unknown
@param[in] elements number of array elements or
no_limit
if unknown
@return whether parsing should proceed
@note binary formats may report the number of elements
*/
virtual
bool
start_array
(
std
::
size_t
elements
)
=
0
;
virtual
bool
start_array
(
std
::
size_t
elements
=
no_limit
)
=
0
;
/*!
@brief the end of an array was read
...
...
@@ -3297,7 +3300,7 @@ class parser
value
};
using
json_sax
=
json_sax
<
BasicJsonType
>
;
using
json_sax
_t
=
json_sax
<
BasicJsonType
>
;
using
parser_callback_t
=
std
::
function
<
bool
(
int
depth
,
parse_event_t
event
,
BasicJsonType
&
parsed
)
>
;
...
...
@@ -3309,7 +3312,7 @@ class parser
:
callback
(
cb
),
m_lexer
(
adapter
),
allow_exceptions
(
allow_exceptions_
)
{}
parser
(
detail
::
input_adapter_t
adapter
,
json_sax
*
s
)
parser
(
detail
::
input_adapter_t
adapter
,
json_sax
_t
*
s
)
:
m_lexer
(
adapter
),
sax
(
s
)
{}
...
...
@@ -3785,7 +3788,7 @@ class parser
{
case
token_type
:
:
begin_object
:
{
if
(
not
sax
->
start_object
(
std
::
size_t
(
-
1
)
))
if
(
not
sax
->
start_object
())
{
return
false
;
}
...
...
@@ -3854,7 +3857,7 @@ class parser
case
token_type
:
:
begin_array
:
{
if
(
not
sax
->
start_array
(
std
::
size_t
(
-
1
)
))
if
(
not
sax
->
start_array
())
{
return
false
;
}
...
...
@@ -4016,7 +4019,7 @@ class parser
/// whether to throw exceptions in case of errors
const
bool
allow_exceptions
=
true
;
/// associated SAX parse event receiver
json_sax
*
sax
=
nullptr
;
json_sax
_t
*
sax
=
nullptr
;
};
}
}
...
...
@@ -11013,7 +11016,7 @@ class basic_json
*/
using
parser_callback_t
=
typename
parser
::
parser_callback_t
;
using
json_sax
=
typename
parser
::
json_sax
;
using
json_sax
_t
=
typename
parser
::
json_sax_t
;
//////////////////
// constructors //
...
...
@@ -15834,12 +15837,12 @@ class basic_json
return
parser
(
i
).
accept
(
true
);
}
static
bool
sax_parse
(
detail
::
input_adapter
i
,
json_sax
*
sax
)
static
bool
sax_parse
(
detail
::
input_adapter
i
,
json_sax
_t
*
sax
)
{
return
parser
(
i
,
sax
).
sax_parse
();
}
static
bool
sax_parse
(
detail
::
input_adapter
&
i
,
json_sax
*
sax
)
static
bool
sax_parse
(
detail
::
input_adapter
&
i
,
json_sax
_t
*
sax
)
{
return
parser
(
i
,
sax
).
sax_parse
();
}
...
...
@@ -15917,7 +15920,7 @@ class basic_json
std
::
is_base_of
<
std
::
random_access_iterator_tag
,
typename
std
::
iterator_traits
<
IteratorType
>::
iterator_category
>::
value
,
int
>::
type
=
0
>
static
bool
sax_parse
(
IteratorType
first
,
IteratorType
last
,
json_sax
*
sax
)
static
bool
sax_parse
(
IteratorType
first
,
IteratorType
last
,
json_sax
_t
*
sax
)
{
return
parser
(
detail
::
input_adapter
(
first
,
last
),
sax
).
sax_parse
();
}
...
...
test/src/unit-class_parser.cpp
View file @
3ff94553
...
...
@@ -34,7 +34,7 @@ using nlohmann::json;
#include <valarray>
class
SaxEventLogger
:
public
nlohmann
::
json
::
json_sax
class
SaxEventLogger
:
public
nlohmann
::
json
::
json_sax
_t
{
public
:
bool
null
()
override
...
...
@@ -67,7 +67,7 @@ class SaxEventLogger : public nlohmann::json::json_sax
return
true
;
}
bool
string
(
const
std
::
string
&
val
)
override
bool
string
(
std
::
string
&
&
val
)
override
{
events
.
push_back
(
"string("
+
val
+
")"
);
return
true
;
...
...
@@ -75,7 +75,7 @@ class SaxEventLogger : public nlohmann::json::json_sax
bool
start_object
(
std
::
size_t
elements
)
override
{
if
(
elements
==
std
::
size_t
(
-
1
)
)
if
(
elements
==
no_limit
)
{
events
.
push_back
(
"start_object()"
);
}
...
...
@@ -86,13 +86,13 @@ class SaxEventLogger : public nlohmann::json::json_sax
return
true
;
}
bool
key
(
const
std
::
string
&
val
)
override
bool
key
(
std
::
string
&
&
val
)
override
{
events
.
push_back
(
"key("
+
val
+
")"
);
return
true
;
}
bool
end_object
()
override
bool
end_object
()
override
{
events
.
push_back
(
"end_object()"
);
return
true
;
...
...
@@ -100,7 +100,7 @@ class SaxEventLogger : public nlohmann::json::json_sax
bool
start_array
(
std
::
size_t
elements
)
override
{
if
(
elements
==
std
::
size_t
(
-
1
)
)
if
(
elements
==
no_limit
)
{
events
.
push_back
(
"start_array()"
);
}
...
...
@@ -134,6 +134,129 @@ class SaxEventLogger : public nlohmann::json::json_sax
bool
errored
=
false
;
};
class
SaxDomParser
:
public
nlohmann
::
json
::
json_sax_t
{
public
:
bool
null
()
override
{
handle_value
(
nullptr
);
return
true
;
}
bool
boolean
(
bool
val
)
override
{
handle_value
(
val
);
return
true
;
}
bool
number_integer
(
json
::
number_integer_t
val
)
override
{
handle_value
(
val
);
return
true
;
}
bool
number_unsigned
(
json
::
number_unsigned_t
val
)
override
{
handle_value
(
val
);
return
true
;
}
bool
number_float
(
json
::
number_float_t
val
,
const
std
::
string
&
)
override
{
handle_value
(
val
);
return
true
;
}
bool
string
(
std
::
string
&&
val
)
override
{
handle_value
(
val
);
return
true
;
}
bool
start_object
(
std
::
size_t
)
override
{
ref_stack
.
push_back
(
handle_value
(
json
::
value_t
::
object
));
return
true
;
}
bool
key
(
std
::
string
&&
val
)
override
{
last_key
=
val
;
return
true
;
}
bool
end_object
()
override
{
ref_stack
.
pop_back
();
return
true
;
}
bool
start_array
(
std
::
size_t
)
override
{
ref_stack
.
push_back
(
handle_value
(
json
::
value_t
::
array
));
return
true
;
}
bool
end_array
()
override
{
ref_stack
.
pop_back
();
return
true
;
}
bool
binary
(
const
std
::
vector
<
uint8_t
>&
)
override
{
return
true
;
}
bool
parse_error
(
std
::
size_t
position
,
const
std
::
string
&
)
override
{
return
false
;
}
json
&
get_value
()
{
return
root
;
}
private
:
/// the parsed JSON value
json
root
;
/// stack to model hierarchy of values
std
::
vector
<
json
*>
ref_stack
;
/// helper variable for object keys
std
::
string
last_key
;
/*!
@invariant If the ref stack is empty, then the passed value will be the new
root.
@invariant If the ref stack contains a value, then it is an array or an
object to which we can add elements
*/
json
*
handle_value
(
json
&&
j
)
{
if
(
ref_stack
.
empty
())
{
assert
(
root
.
is_null
());
root
=
j
;
return
&
root
;
}
else
{
assert
(
ref_stack
.
back
()
->
is_array
()
or
ref_stack
.
back
()
->
is_object
());
if
(
ref_stack
.
back
()
->
is_array
())
{
ref_stack
.
back
()
->
push_back
(
j
);
return
&
(
ref_stack
.
back
()
->
back
());
}
else
{
json
&
r
=
ref_stack
.
back
()
->
operator
[](
last_key
)
=
j
;
return
&
r
;
}
}
}
};
json
parser_helper
(
const
std
::
string
&
s
);
bool
accept_helper
(
const
std
::
string
&
s
);
...
...
@@ -148,6 +271,10 @@ json parser_helper(const std::string& s)
CHECK_NOTHROW
(
json
::
parser
(
nlohmann
::
detail
::
input_adapter
(
s
),
nullptr
,
false
).
parse
(
true
,
j_nothrow
));
CHECK
(
j_nothrow
==
j
);
SaxDomParser
sdp
;
json
::
sax_parse
(
s
,
&
sdp
);
CHECK
(
sdp
.
get_value
()
==
j
);
return
j
;
}
...
...
test/src/unit-deserialization.cpp
View file @
3ff94553
...
...
@@ -34,7 +34,7 @@ using nlohmann::json;
#include <iostream>
#include <valarray>
struct
SaxEventLogger
:
public
nlohmann
::
json
::
json_sax
struct
SaxEventLogger
:
public
nlohmann
::
json
::
json_sax
_t
{
bool
null
()
override
{
...
...
@@ -66,7 +66,7 @@ struct SaxEventLogger : public nlohmann::json::json_sax
return
true
;
}
bool
string
(
const
std
::
string
&
val
)
override
bool
string
(
std
::
string
&
&
val
)
override
{
events
.
push_back
(
"string("
+
val
+
")"
);
return
true
;
...
...
@@ -85,7 +85,7 @@ struct SaxEventLogger : public nlohmann::json::json_sax
return
true
;
}
bool
key
(
const
std
::
string
&
val
)
override
bool
key
(
std
::
string
&
&
val
)
override
{
events
.
push_back
(
"key("
+
val
+
")"
);
return
true
;
...
...
@@ -135,7 +135,7 @@ struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
{
bool
start_object
(
std
::
size_t
elements
)
override
{
if
(
elements
==
std
::
size_t
(
-
1
)
)
if
(
elements
==
no_limit
)
{
events
.
push_back
(
"start_object()"
);
}
...
...
@@ -149,7 +149,7 @@ struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
struct
SaxEventLoggerExitAfterKey
:
public
SaxEventLogger
{
bool
key
(
const
std
::
string
&
val
)
override
bool
key
(
std
::
string
&
&
val
)
override
{
events
.
push_back
(
"key("
+
val
+
")"
);
return
false
;
...
...
@@ -160,7 +160,7 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
{
bool
start_array
(
std
::
size_t
elements
)
override
{
if
(
elements
==
std
::
size_t
(
-
1
)
)
if
(
elements
==
no_limit
)
{
events
.
push_back
(
"start_array()"
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment