Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
465fab45
Commit
465fab45
authored
Mar 16, 2017
by
Milo Yip
Committed by
GitHub
Mar 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #897 from StilesCrisis/issue-889-pretty-writer
Issue 889 pretty writer
parents
266870df
d5d18cf6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
101 additions
and
102 deletions
+101
-102
lookaheadparser.cpp
example/lookaheadparser/lookaheadparser.cpp
+83
-82
prettywriter.h
include/rapidjson/prettywriter.h
+4
-20
prettywritertest.cpp
test/unittest/prettywritertest.cpp
+14
-0
No files found.
example/lookaheadparser/lookaheadparser.cpp
View file @
465fab45
...
...
@@ -19,15 +19,15 @@
//
// After calling EnterObject, you retrieve keys via NextObjectKey() and values via
// the normal getters. When NextObjectKey() returns null, you have exited the
// object, or you can call
Exit
Object() to skip to the end of the object
// object, or you can call
Skip
Object() to skip to the end of the object
// immediately. If you fetch the entire object (i.e. NextObjectKey() returned null),
// you should not call
Exit
Object().
// you should not call
Skip
Object().
//
// After calling EnterArray(), you must alternate between calling NextArrayValue()
// to see if the array has more data, and then retrieving values via the normal
// getters. You can call
Exit
Array() to skip to the end of the array immediately.
// getters. You can call
Skip
Array() to skip to the end of the array immediately.
// If you fetch the entire array (i.e. NextArrayValue() returned null),
// you should not call
Exit
Array().
// you should not call
Skip
Array().
//
// This parser uses in-situ strings, so the JSON buffer will be altered during the
// parse.
...
...
@@ -37,15 +37,15 @@ using namespace rapidjson;
class
LookaheadParserHandler
{
public
:
bool
Null
()
{
st_
=
kHas
Value
;
v_
.
SetNull
();
return
true
;
}
bool
Bool
(
bool
b
)
{
st_
=
kHas
Value
;
v_
.
SetBool
(
b
);
return
true
;
}
bool
Int
(
int
i
)
{
st_
=
kHas
Value
;
v_
.
SetInt
(
i
);
return
true
;
}
bool
Uint
(
unsigned
u
)
{
st_
=
kHas
Value
;
v_
.
SetUint
(
u
);
return
true
;
}
bool
Int64
(
int64_t
i
)
{
st_
=
kHas
Value
;
v_
.
SetInt64
(
i
);
return
true
;
}
bool
Uint64
(
uint64_t
u
)
{
st_
=
kHas
Value
;
v_
.
SetUint64
(
u
);
return
true
;
}
bool
Double
(
double
d
)
{
st_
=
kHas
Value
;
v_
.
SetDouble
(
d
);
return
true
;
}
bool
Null
()
{
st_
=
kHas
Null
;
v_
.
SetNull
();
return
true
;
}
bool
Bool
(
bool
b
)
{
st_
=
kHas
Bool
;
v_
.
SetBool
(
b
);
return
true
;
}
bool
Int
(
int
i
)
{
st_
=
kHas
Number
;
v_
.
SetInt
(
i
);
return
true
;
}
bool
Uint
(
unsigned
u
)
{
st_
=
kHas
Number
;
v_
.
SetUint
(
u
);
return
true
;
}
bool
Int64
(
int64_t
i
)
{
st_
=
kHas
Number
;
v_
.
SetInt64
(
i
);
return
true
;
}
bool
Uint64
(
uint64_t
u
)
{
st_
=
kHas
Number
;
v_
.
SetUint64
(
u
);
return
true
;
}
bool
Double
(
double
d
)
{
st_
=
kHas
Number
;
v_
.
SetDouble
(
d
);
return
true
;
}
bool
RawNumber
(
const
char
*
,
SizeType
,
bool
)
{
return
false
;
}
bool
String
(
const
char
*
str
,
SizeType
length
,
bool
)
{
st_
=
kHas
Value
;
v_
.
SetString
(
str
,
length
);
return
true
;
}
bool
String
(
const
char
*
str
,
SizeType
length
,
bool
)
{
st_
=
kHas
String
;
v_
.
SetString
(
str
,
length
);
return
true
;
}
bool
StartObject
()
{
st_
=
kEnteringObject
;
return
true
;
}
bool
Key
(
const
char
*
str
,
SizeType
length
,
bool
)
{
st_
=
kHasKey
;
v_
.
SetString
(
str
,
length
);
return
true
;
}
bool
EndObject
(
SizeType
)
{
st_
=
kExitingObject
;
return
true
;
}
...
...
@@ -58,8 +58,12 @@ protected:
protected
:
enum
LookaheadParsingState
{
kInit
,
kError
,
kHasValue
,
kHasNull
,
kHasBool
,
kHasNumber
,
kHasString
,
kHasKey
,
kEnteringObject
,
kExitingObject
,
...
...
@@ -75,7 +79,7 @@ protected:
static
const
int
parseFlags
=
kParseDefaultFlags
|
kParseInsituFlag
;
};
LookaheadParserHandler
::
LookaheadParserHandler
(
char
*
str
)
:
ss_
(
str
)
{
LookaheadParserHandler
::
LookaheadParserHandler
(
char
*
str
)
:
v_
(),
st_
(
kInit
),
r_
(),
ss_
(
str
)
{
r_
.
IterativeParseInit
();
ParseNext
();
}
...
...
@@ -93,10 +97,8 @@ class LookaheadParser : protected LookaheadParserHandler {
public
:
LookaheadParser
(
char
*
str
)
:
LookaheadParserHandler
(
str
)
{}
void
EnterObject
();
void
EnterArray
();
void
ExitObject
();
void
ExitArray
();
bool
EnterObject
();
bool
EnterArray
();
const
char
*
NextObjectKey
();
bool
NextArrayValue
();
int
GetInt
();
...
...
@@ -105,57 +107,52 @@ public:
bool
GetBool
();
void
GetNull
();
void
SkipObject
();
void
SkipArray
();
void
SkipValue
();
Value
*
PeekValue
();
int
PeekType
();
// returns a rapidjson::Type, or -1 for no value (at end of object/array)
bool
IsValid
()
{
return
st_
!=
kError
;
}
protected
:
void
SkipOut
(
int
depth
);
};
void
LookaheadParser
::
EnterObject
()
{
bool
LookaheadParser
::
EnterObject
()
{
if
(
st_
!=
kEnteringObject
)
{
st_
=
kError
;
return
;
return
false
;
}
ParseNext
();
return
true
;
}
void
LookaheadParser
::
EnterArray
()
{
bool
LookaheadParser
::
EnterArray
()
{
if
(
st_
!=
kEnteringArray
)
{
st_
=
kError
;
return
;
return
false
;
}
ParseNext
();
}
void
LookaheadParser
::
ExitObject
()
{
while
(
NextObjectKey
())
{
SkipValue
();
}
}
void
LookaheadParser
::
ExitArray
()
{
while
(
NextArrayValue
())
{
SkipValue
();
}
return
true
;
}
const
char
*
LookaheadParser
::
NextObjectKey
()
{
if
(
st_
==
kExitingObject
)
{
if
(
st_
==
kHasKey
)
{
const
char
*
result
=
v_
.
GetString
();
ParseNext
();
return
0
;
return
result
;
}
if
(
st_
!=
k
HasKey
||
!
v_
.
IsString
()
)
{
if
(
st_
!=
k
ExitingObject
)
{
st_
=
kError
;
return
0
;
}
const
char
*
result
=
v_
.
GetString
();
ParseNext
();
return
result
;
return
0
;
}
bool
LookaheadParser
::
NextArrayValue
()
{
...
...
@@ -164,11 +161,16 @@ bool LookaheadParser::NextArrayValue() {
return
false
;
}
if
(
st_
==
kError
||
st_
==
kExitingObject
||
st_
==
kHasKey
)
{
st_
=
kError
;
return
false
;
}
return
true
;
}
int
LookaheadParser
::
GetInt
()
{
if
(
st_
!=
kHas
Value
||
!
v_
.
IsInt
())
{
if
(
st_
!=
kHas
Number
||
!
v_
.
IsInt
())
{
st_
=
kError
;
return
0
;
}
...
...
@@ -179,7 +181,7 @@ int LookaheadParser::GetInt() {
}
double
LookaheadParser
::
GetDouble
()
{
if
(
st_
!=
kHas
Value
||
!
v_
.
IsNumber
()
)
{
if
(
st_
!=
kHas
Number
)
{
st_
=
kError
;
return
0.
;
}
...
...
@@ -190,7 +192,7 @@ double LookaheadParser::GetDouble() {
}
bool
LookaheadParser
::
GetBool
()
{
if
(
st_
!=
kHas
Value
||
!
v_
.
IsBool
()
)
{
if
(
st_
!=
kHas
Bool
)
{
st_
=
kError
;
return
false
;
}
...
...
@@ -201,7 +203,7 @@ bool LookaheadParser::GetBool() {
}
void
LookaheadParser
::
GetNull
()
{
if
(
st_
!=
kHas
Value
||
!
v_
.
IsNull
()
)
{
if
(
st_
!=
kHas
Null
)
{
st_
=
kError
;
return
;
}
...
...
@@ -210,7 +212,7 @@ void LookaheadParser::GetNull() {
}
const
char
*
LookaheadParser
::
GetString
()
{
if
(
st_
!=
kHas
Value
||
!
v_
.
IsString
()
)
{
if
(
st_
!=
kHas
String
)
{
st_
=
kError
;
return
0
;
}
...
...
@@ -220,34 +222,37 @@ const char* LookaheadParser::GetString() {
return
result
;
}
void
LookaheadParser
::
SkipValue
()
{
int
depth
=
0
;
void
LookaheadParser
::
SkipOut
(
int
depth
)
{
do
{
switch
(
st_
)
{
case
kEnteringArray
:
case
kEnteringObject
:
++
depth
;
break
;
case
kExitingArray
:
case
kExitingObject
:
--
depth
;
break
;
case
kError
:
return
;
case
kHasKey
:
case
kHasValue
:
break
;
if
(
st_
==
kEnteringArray
||
st_
==
kEnteringObject
)
{
++
depth
;
}
else
if
(
st_
==
kExitingArray
||
st_
==
kExitingObject
)
{
--
depth
;
}
else
if
(
st_
==
kError
)
{
return
;
}
ParseNext
();
}
while
(
depth
>
0
);
}
void
LookaheadParser
::
SkipValue
()
{
SkipOut
(
0
);
}
void
LookaheadParser
::
SkipArray
()
{
SkipOut
(
1
);
}
void
LookaheadParser
::
SkipObject
()
{
SkipOut
(
1
);
}
Value
*
LookaheadParser
::
PeekValue
()
{
if
(
st_
==
kHasValue
||
st_
=
=
kHasKey
)
{
if
(
st_
>=
kHasNull
&&
st_
<
=
kHasKey
)
{
return
&
v_
;
}
...
...
@@ -255,23 +260,19 @@ Value* LookaheadParser::PeekValue() {
}
int
LookaheadParser
::
PeekType
()
{
switch
(
st_
)
{
case
kHasValue
:
case
kHasKey
:
return
v_
.
GetType
();
case
kEnteringArray
:
return
kArrayType
;
case
kEnteringObject
:
return
kObjectType
;
case
kExitingArray
:
case
kExitingObject
:
case
kError
:
default
:
return
-
1
;
if
(
st_
>=
kHasNull
&&
st_
<=
kHasKey
)
{
return
v_
.
GetType
();
}
if
(
st_
==
kEnteringArray
)
{
return
kArrayType
;
}
if
(
st_
==
kEnteringObject
)
{
return
kObjectType
;
}
return
-
1
;
}
//-------------------------------------------------------------------------
...
...
@@ -325,7 +326,7 @@ int main() {
cout
<<
r
.
GetString
()
<<
" "
;
}
else
{
r
.
Exit
Array
();
r
.
Skip
Array
();
break
;
}
}
...
...
include/rapidjson/prettywriter.h
View file @
465fab45
...
...
@@ -107,8 +107,7 @@ public:
return
Base
::
WriteString
(
str
,
length
);
}
template
<
typename
T
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
String
(
const
T
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
bool
String
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
RAPIDJSON_ASSERT
(
str
!=
0
);
(
void
)
copy
;
PrettyPrefix
(
kStringType
);
...
...
@@ -127,8 +126,7 @@ public:
return
Base
::
WriteStartObject
();
}
template
<
typename
T
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
Key
(
const
T
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
return
String
(
str
,
length
,
copy
);
}
bool
Key
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
return
String
(
str
,
length
,
copy
);
}
#if RAPIDJSON_HAS_STDSTRING
bool
Key
(
const
std
::
basic_string
<
Ch
>&
str
)
{
...
...
@@ -186,22 +184,8 @@ public:
//@{
//! Simpler but slower overload.
template
<
typename
T
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
String
(
const
T
*
const
&
str
)
{
return
String
(
str
,
internal
::
StrLen
(
str
));
}
template
<
typename
T
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
Key
(
const
T
*
const
&
str
)
{
return
Key
(
str
,
internal
::
StrLen
(
str
));
}
//! The compiler can give us the length of quoted strings for free.
template
<
typename
T
,
size_t
N
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
String
(
const
T
(
&
str
)[
N
])
{
RAPIDJSON_ASSERT
(
str
[
N
-
1
]
==
'\0'
);
// you must pass in a null-terminated string (quoted constant strings are always null-terminated)
return
String
(
str
,
N
-
1
);
}
template
<
typename
T
,
size_t
N
>
RAPIDJSON_ENABLEIF_RETURN
((
internal
::
IsSame
<
Ch
,
T
>
),
(
bool
))
Key
(
const
T
(
&
str
)[
N
])
{
RAPIDJSON_ASSERT
(
str
[
N
-
1
]
==
'\0'
);
// you must pass in a null-terminated string (quoted constant strings are always null-terminated)
return
Key
(
str
,
N
-
1
);
}
bool
String
(
const
Ch
*
str
)
{
return
String
(
str
,
internal
::
StrLen
(
str
));
}
bool
Key
(
const
Ch
*
str
)
{
return
Key
(
str
,
internal
::
StrLen
(
str
));
}
//@}
...
...
test/unittest/prettywritertest.cpp
View file @
465fab45
...
...
@@ -258,6 +258,20 @@ TEST(PrettyWriter, InvalidEventSequence) {
}
}
TEST
(
PrettyWriter
,
Issue_889
)
{
char
buf
[
100
]
=
"Hello"
;
StringBuffer
buffer
;
PrettyWriter
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartArray
();
writer
.
String
(
buf
);
writer
.
EndArray
();
EXPECT_STREQ
(
"[
\n
\"
Hello
\"\n
]"
,
buffer
.
GetString
());
EXPECT_TRUE
(
writer
.
IsComplete
());
\
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
static
PrettyWriter
<
StringBuffer
>
WriterGen
(
StringBuffer
&
target
)
{
...
...
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