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
62a9a6b0
Commit
62a9a6b0
authored
Mar 31, 2016
by
Milo Yip
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #589 from jnicholls/rawnumber
RawNumber Improvements / Clang Test Fix / Whitespace Cleanup
parents
4fdcb10c
926d7ffc
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
168 additions
and
96 deletions
+168
-96
reader.h
include/rapidjson/reader.h
+61
-55
CMakeLists.txt
test/unittest/CMakeLists.txt
+5
-0
readertest.cpp
test/unittest/readertest.cpp
+102
-41
No files found.
include/rapidjson/reader.h
View file @
62a9a6b0
// Tencent is pleased to support the open source community by making RapidJSON available.
//
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
...
...
@@ -7,9 +7,9 @@
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_READER_H_
...
...
@@ -127,7 +127,7 @@ RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// ParseFlag
/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
\ingroup RAPIDJSON_CONFIG
\brief User-defined kParseDefaultFlags definition.
...
...
@@ -158,7 +158,7 @@ enum ParseFlag {
/*! \class rapidjson::Handler
\brief Concept for receiving events from GenericReader upon parsing.
The functions return true if no error occurs. If they return false,
The functions return true if no error occurs. If they return false,
the event publisher should terminate the process.
\code
concept Handler {
...
...
@@ -425,7 +425,7 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
#ifdef RAPIDJSON_SIMD
//! Template function specialization for InsituStringStream
template
<>
inline
void
SkipWhitespace
(
InsituStringStream
&
is
)
{
template
<>
inline
void
SkipWhitespace
(
InsituStringStream
&
is
)
{
is
.
src_
=
const_cast
<
char
*>
(
SkipWhitespace_SIMD
(
is
.
src_
));
}
...
...
@@ -443,17 +443,17 @@ template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>&
// GenericReader
//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
/*! GenericReader parses JSON text from a stream, and send events synchronously to an
/*! GenericReader parses JSON text from a stream, and send events synchronously to an
object implementing Handler concept.
It needs to allocate a stack for storing a single decoded string during
It needs to allocate a stack for storing a single decoded string during
non-destructive parsing.
For in-situ parsing, the decoded string is directly written to the source
For in-situ parsing, the decoded string is directly written to the source
text string, no temporary buffer is required.
A GenericReader object can be reused for parsing multiple JSON text.
\tparam SourceEncoding Encoding of the input stream.
\tparam TargetEncoding Encoding of the parse output.
\tparam StackAllocator Allocator type for stack.
...
...
@@ -525,7 +525,7 @@ public:
//! Whether a parse error has occured in the last parsing.
bool
HasParseError
()
const
{
return
parseResult_
.
IsError
();
}
//! Get the \ref ParseErrorCode of last parsing.
ParseErrorCode
GetParseErrorCode
()
const
{
return
parseResult_
.
Code
();
}
...
...
@@ -585,7 +585,7 @@ private:
void
ParseObject
(
InputStream
&
is
,
Handler
&
handler
)
{
RAPIDJSON_ASSERT
(
is
.
Peek
()
==
'{'
);
is
.
Take
();
// Skip '{'
if
(
RAPIDJSON_UNLIKELY
(
!
handler
.
StartObject
()))
RAPIDJSON_PARSE_ERROR
(
kParseErrorTermination
,
is
.
Tell
());
...
...
@@ -628,12 +628,12 @@ private:
SkipWhitespaceAndComments
<
parseFlags
>
(
is
);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
break
;
case
'}'
:
case
'}'
:
is
.
Take
();
if
(
RAPIDJSON_UNLIKELY
(
!
handler
.
EndObject
(
memberCount
)))
RAPIDJSON_PARSE_ERROR
(
kParseErrorTermination
,
is
.
Tell
());
return
;
default
:
default
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorObjectMissCommaOrCurlyBracket
,
is
.
Tell
());
break
;
}
...
...
@@ -654,10 +654,10 @@ private:
void
ParseArray
(
InputStream
&
is
,
Handler
&
handler
)
{
RAPIDJSON_ASSERT
(
is
.
Peek
()
==
'['
);
is
.
Take
();
// Skip '['
if
(
RAPIDJSON_UNLIKELY
(
!
handler
.
StartArray
()))
RAPIDJSON_PARSE_ERROR
(
kParseErrorTermination
,
is
.
Tell
());
SkipWhitespaceAndComments
<
parseFlags
>
(
is
);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
...
...
@@ -780,7 +780,7 @@ private:
*
stack_
.
template
Push
<
Ch
>
()
=
c
;
++
length_
;
}
RAPIDJSON_FORCEINLINE
void
*
Push
(
SizeType
count
)
{
length_
+=
count
;
return
stack_
.
template
Push
<
Ch
>
(
count
);
...
...
@@ -838,10 +838,10 @@ private:
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
static
const
char
escape
[
256
]
=
{
Z16
,
Z16
,
0
,
0
,
'\"'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'/'
,
Z16
,
Z16
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'\\'
,
0
,
0
,
0
,
0
,
0
,
'\b'
,
0
,
0
,
0
,
'\f'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'\n'
,
0
,
0
,
0
,
'\r'
,
0
,
'\t'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
Z16
,
Z16
,
0
,
0
,
'\"'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'/'
,
Z16
,
Z16
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'\\'
,
0
,
0
,
0
,
0
,
0
,
'\b'
,
0
,
0
,
0
,
'\f'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
'\n'
,
0
,
0
,
0
,
'\r'
,
0
,
'\t'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
Z16
,
Z16
,
Z16
,
Z16
,
Z16
,
Z16
,
Z16
,
Z16
};
#undef Z16
...
...
@@ -893,8 +893,8 @@ private:
}
else
{
size_t
offset
=
is
.
Tell
();
if
(
RAPIDJSON_UNLIKELY
((
parseFlags
&
kParseValidateEncodingFlag
?
!
Transcoder
<
SEncoding
,
TEncoding
>::
Validate
(
is
,
os
)
:
if
(
RAPIDJSON_UNLIKELY
((
parseFlags
&
kParseValidateEncodingFlag
?
!
Transcoder
<
SEncoding
,
TEncoding
>::
Validate
(
is
,
os
)
:
!
Transcoder
<
SEncoding
,
TEncoding
>::
Transcode
(
is
,
os
))))
RAPIDJSON_PARSE_ERROR
(
kParseErrorStringInvalidEncoding
,
offset
);
}
...
...
@@ -954,7 +954,7 @@ private:
}
_mm_storeu_si128
(
reinterpret_cast
<
__m128i
*>
(
os
.
Push
(
16
)),
s
);
}
is
.
src_
=
p
;
}
...
...
@@ -977,7 +977,7 @@ private:
if
(
RAPIDJSON_UNLIKELY
(
*
p
==
'\"'
)
||
RAPIDJSON_UNLIKELY
(
*
p
==
'\\'
)
||
RAPIDJSON_UNLIKELY
(
static_cast
<
unsigned
>
(
*
p
)
<
0x20
))
{
is
.
src_
=
p
;
is
.
dst_
=
q
;
return
;
return
;
}
else
*
q
++
=
*
p
++
;
...
...
@@ -1063,11 +1063,11 @@ private:
}
#endif
template
<
typename
InputStream
,
bool
backup
>
template
<
typename
InputStream
,
bool
backup
,
bool
pushOnTake
>
class
NumberStream
;
template
<
typename
InputStream
>
class
NumberStream
<
InputStream
,
false
>
{
class
NumberStream
<
InputStream
,
false
,
false
>
{
public
:
typedef
typename
InputStream
::
Ch
Ch
;
...
...
@@ -1090,10 +1090,10 @@ private:
};
template
<
typename
InputStream
>
class
NumberStream
<
InputStream
,
true
>
:
public
NumberStream
<
InputStream
,
false
>
{
typedef
NumberStream
<
InputStream
,
false
>
Base
;
class
NumberStream
<
InputStream
,
true
,
false
>
:
public
NumberStream
<
InputStream
,
false
,
false
>
{
typedef
NumberStream
<
InputStream
,
false
,
false
>
Base
;
public
:
NumberStream
(
GenericReader
&
reader
,
InputStream
&
is
)
:
NumberStream
<
InputStream
,
false
>
(
reader
,
is
),
stackStream
(
reader
.
stack_
)
{}
NumberStream
(
GenericReader
&
reader
,
InputStream
&
is
)
:
Base
(
reader
,
is
),
stackStream
(
reader
.
stack_
)
{}
~
NumberStream
()
{}
RAPIDJSON_FORCEINLINE
Ch
TakePush
()
{
...
...
@@ -1101,9 +1101,9 @@ private:
return
Base
::
is
.
Take
();
}
RAPIDJSON_FORCEINLINE
void
Push
(
char
c
)
{
stackStream
.
Put
(
c
);
}
RAPIDJSON_FORCEINLINE
void
Push
(
char
c
)
{
stackStream
.
Put
(
c
);
}
size_t
Length
()
{
return
stackStream
.
Length
();
}
...
...
@@ -1116,13 +1116,25 @@ private:
StackStream
<
char
>
stackStream
;
};
template
<
typename
InputStream
>
class
NumberStream
<
InputStream
,
true
,
true
>
:
public
NumberStream
<
InputStream
,
true
,
false
>
{
typedef
NumberStream
<
InputStream
,
true
,
false
>
Base
;
public
:
NumberStream
(
GenericReader
&
reader
,
InputStream
&
is
)
:
Base
(
reader
,
is
)
{}
~
NumberStream
()
{}
RAPIDJSON_FORCEINLINE
Ch
Take
()
{
return
Base
::
TakePush
();
}
};
template
<
unsigned
parseFlags
,
typename
InputStream
,
typename
Handler
>
void
ParseNumber
(
InputStream
&
is
,
Handler
&
handler
)
{
internal
::
StreamLocalCopy
<
InputStream
>
copy
(
is
);
NumberStream
<
InputStream
,
((
parseFlags
&
kParseNumbersAsStringsFlag
)
!=
0
)
?
((
parseFlags
&
kParseInsituFlag
)
==
0
)
:
((
parseFlags
&
kParseFullPrecisionFlag
)
!=
0
)
>
s
(
*
this
,
copy
.
s
);
((
parseFlags
&
kParseFullPrecisionFlag
)
!=
0
),
(
parseFlags
&
kParseNumbersAsStringsFlag
)
!=
0
&&
(
parseFlags
&
kParseInsituFlag
)
==
0
>
s
(
*
this
,
copy
.
s
);
size_t
startOffset
=
s
.
Tell
();
...
...
@@ -1173,7 +1185,7 @@ private:
bool
useDouble
=
false
;
double
d
=
0
.
0
;
if
(
use64bit
)
{
if
(
minus
)
if
(
minus
)
while
(
RAPIDJSON_LIKELY
(
s
.
Peek
()
>=
'0'
&&
s
.
Peek
()
<=
'9'
))
{
if
(
RAPIDJSON_UNLIKELY
(
i64
>=
RAPIDJSON_UINT64_C2
(
0x0CCCCCCC
,
0xCCCCCCCC
)))
// 2^63 = 9223372036854775808
if
(
RAPIDJSON_LIKELY
(
i64
!=
RAPIDJSON_UINT64_C2
(
0x0CCCCCCC
,
0xCCCCCCCC
)
||
s
.
Peek
()
>
'8'
))
{
...
...
@@ -1210,9 +1222,6 @@ private:
int
expFrac
=
0
;
size_t
decimalPosition
;
if
(
Consume
(
s
,
'.'
))
{
if
(((
parseFlags
&
kParseNumbersAsStringsFlag
)
!=
0
)
&&
((
parseFlags
&
kParseInsituFlag
)
==
0
))
{
s
.
Push
(
'.'
);
}
decimalPosition
=
s
.
Length
();
if
(
RAPIDJSON_UNLIKELY
(
!
(
s
.
Peek
()
>=
'0'
&&
s
.
Peek
()
<=
'9'
)))
...
...
@@ -1223,7 +1232,7 @@ private:
// Use i64 to store significand in 64-bit architecture
if
(
!
use64bit
)
i64
=
i
;
while
(
RAPIDJSON_LIKELY
(
s
.
Peek
()
>=
'0'
&&
s
.
Peek
()
<=
'9'
))
{
if
(
i64
>
RAPIDJSON_UINT64_C2
(
0x1FFFFF
,
0xFFFFFFFF
))
// 2^53 - 1 for fast path
break
;
...
...
@@ -1260,11 +1269,7 @@ private:
// Parse exp = e [ minus / plus ] 1*DIGIT
int
exp
=
0
;
if
(
Consume
(
s
,
'e'
)
||
Consume
(
s
,
'E'
))
{
if
(
((
parseFlags
&
kParseNumbersAsStringsFlag
)
!=
0
)
&&
((
parseFlags
&
kParseInsituFlag
)
==
0
)
)
{
s
.
Push
(
'e'
);
}
if
(
!
useDouble
)
{
if
(
!
useDouble
)
{
d
=
static_cast
<
double
>
(
use64bit
?
i64
:
i
);
useDouble
=
true
;
}
...
...
@@ -1316,14 +1321,15 @@ private:
cont
=
handler
.
RawNumber
(
str
,
SizeType
(
length
),
false
);
}
else
{
StackStream
<
typename
TargetEncoding
::
Ch
>
stackStream
(
stack_
);
SizeType
numCharsToCopy
=
static_cast
<
SizeType
>
(
s
.
Length
());
StringStream
srcStream
(
s
.
Pop
());
StackStream
<
typename
TargetEncoding
::
Ch
>
dstStream
(
stack_
);
while
(
numCharsToCopy
--
)
{
Transcoder
<
SourceEncoding
,
TargetEncoding
>::
Transcode
(
is
,
stack
Stream
);
Transcoder
<
UTF8
<>
,
TargetEncoding
>::
Transcode
(
srcStream
,
dst
Stream
);
}
stack
Stream
.
Put
(
'\0'
);
const
typename
TargetEncoding
::
Ch
*
str
=
stack
Stream
.
Pop
();
const
SizeType
length
=
static_cast
<
SizeType
>
(
stack
Stream
.
Length
())
-
1
;
dst
Stream
.
Put
(
'\0'
);
const
typename
TargetEncoding
::
Ch
*
str
=
dst
Stream
.
Pop
();
const
SizeType
length
=
static_cast
<
SizeType
>
(
dst
Stream
.
Length
())
-
1
;
cont
=
handler
.
RawNumber
(
str
,
SizeType
(
length
),
true
);
}
}
...
...
@@ -1369,10 +1375,10 @@ private:
case
'"'
:
ParseString
<
parseFlags
>
(
is
,
handler
);
break
;
case
'{'
:
ParseObject
<
parseFlags
>
(
is
,
handler
);
break
;
case
'['
:
ParseArray
<
parseFlags
>
(
is
,
handler
);
break
;
default
:
default
:
ParseNumber
<
parseFlags
>
(
is
,
handler
);
break
;
}
}
...
...
@@ -1444,7 +1450,7 @@ private:
#undef N
#undef N16
//!@endcond
if
(
sizeof
(
Ch
)
==
1
||
static_cast
<
unsigned
>
(
c
)
<
256
)
return
static_cast
<
Token
>
(
tokenMap
[
static_cast
<
unsigned
char
>
(
c
)]);
else
...
...
@@ -1775,7 +1781,7 @@ private:
// Error flag has been set.
return
;
}
switch
(
src
)
{
case
IterativeParsingStartState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorDocumentEmpty
,
is
.
Tell
());
return
;
case
IterativeParsingFinishState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorDocumentRootNotSingular
,
is
.
Tell
());
return
;
...
...
@@ -1788,7 +1794,7 @@ private:
case
IterativeParsingElementDelimiterState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorValueInvalid
,
is
.
Tell
());
return
;
case
IterativeParsingElementState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorArrayMissCommaOrSquareBracket
,
is
.
Tell
());
return
;
default
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorUnspecificSyntaxError
,
is
.
Tell
());
return
;
}
}
}
template
<
unsigned
parseFlags
,
typename
InputStream
,
typename
Handler
>
...
...
test/unittest/CMakeLists.txt
View file @
62a9a6b0
...
...
@@ -38,6 +38,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal"
)
elseif
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything"
)
# If the user is running a newer version of Clang that includes the
# -Wdouble-promotion, we will ignore that warning.
if
(
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.7
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wno-double-promotion"
)
endif
()
elseif
(
"
${
CMAKE_CXX_COMPILER_ID
}
"
STREQUAL
"MSVC"
)
add_definitions
(
-D_CRT_SECURE_NO_WARNINGS=1
)
endif
()
...
...
test/unittest/readertest.cpp
View file @
62a9a6b0
// Tencent is pleased to support the open source community by making RapidJSON available.
//
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
...
...
@@ -7,9 +7,9 @@
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#include "unittest.h"
...
...
@@ -241,13 +241,13 @@ static void TestParseDouble() {
TEST_DOUBLE
(
fullPrecision
,
"0.017976931348623157e+310"
,
1.7976931348623157e+308
);
// Max double in another form
// Since
// abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... 10^-324
// abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... 10 ^ -324
// abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599...
��
10^-324
// abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044...
��
10 ^ -324
// So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
TEST_DOUBLE
(
fullPrecision
,
"2.2250738585072012e-308"
,
2.2250738585072014e-308
);
// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
// More closer to normal/subnormal boundary
// boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... 10^-308
// boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648...
��
10^-308
TEST_DOUBLE
(
fullPrecision
,
"2.22507385850720113605740979670913197593481954635164564e-308"
,
2.2250738585072009e-308
);
TEST_DOUBLE
(
fullPrecision
,
"2.22507385850720113605740979670913197593481954635164565e-308"
,
2.2250738585072014e-308
);
...
...
@@ -297,7 +297,7 @@ static void TestParseDouble() {
}
// Cover trimming
TEST_DOUBLE
(
fullPrecision
,
TEST_DOUBLE
(
fullPrecision
,
"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
...
...
@@ -306,7 +306,7 @@ static void TestParseDouble() {
"5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
"2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
"7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
"e-308"
,
"e-308"
,
2.2250738585072014e-308
);
{
...
...
@@ -457,12 +457,12 @@ template <typename Encoding>
struct
ParseStringHandler
:
BaseReaderHandler
<
Encoding
,
ParseStringHandler
<
Encoding
>
>
{
ParseStringHandler
()
:
str_
(
0
),
length_
(
0
),
copy_
()
{}
~
ParseStringHandler
()
{
EXPECT_TRUE
(
str_
!=
0
);
if
(
copy_
)
free
(
const_cast
<
typename
Encoding
::
Ch
*>
(
str_
));
}
ParseStringHandler
(
const
ParseStringHandler
&
);
ParseStringHandler
&
operator
=
(
const
ParseStringHandler
&
);
bool
Default
()
{
ADD_FAILURE
();
return
false
;
}
bool
String
(
const
typename
Encoding
::
Ch
*
str
,
size_t
length
,
bool
copy
)
{
bool
String
(
const
typename
Encoding
::
Ch
*
str
,
size_t
length
,
bool
copy
)
{
EXPECT_EQ
(
0
,
str_
);
if
(
copy
)
{
str_
=
static_cast
<
typename
Encoding
::
Ch
*>
(
malloc
((
length
+
1
)
*
sizeof
(
typename
Encoding
::
Ch
)));
...
...
@@ -470,7 +470,7 @@ struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encod
}
else
str_
=
str
;
length_
=
length
;
length_
=
length
;
copy_
=
copy
;
return
true
;
}
...
...
@@ -499,7 +499,7 @@ TEST(Reader, ParseString) {
EXPECT_EQ(StrLen(e), h2.length_); \
}
// String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
// String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
// And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
// In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
// Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
...
...
@@ -650,7 +650,7 @@ TEST(Reader, ParseString_Error) {
// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
// 3 Malformed sequences
// 3 Malformed sequences
// 3.1 Unexpected continuation bytes
{
...
...
@@ -684,19 +684,19 @@ TEST(Reader, ParseString_Error) {
}
}
// 4 Overlong sequences
// 4 Overlong sequences
// 4.1 Examples of an overlong ASCII character
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xC0u
,
0xAFu
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xE0u
,
0x80u
,
0xAFu
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xF0u
,
0x80u
,
0x80u
,
0xAFu
,
'\"'
,
']'
,
'\0'
));
// 4.2 Maximum overlong sequences
// 4.2 Maximum overlong sequences
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xC1u
,
0xBFu
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xE0u
,
0x9Fu
,
0xBFu
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xF0u
,
0x8Fu
,
0xBFu
,
0xBFu
,
'\"'
,
']'
,
'\0'
));
// 4.3 Overlong representation of the NUL character
// 4.3 Overlong representation of the NUL character
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xC0u
,
0x80u
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xE0u
,
0x80u
,
0x80u
,
'\"'
,
']'
,
'\0'
));
TEST_STRINGENCODING_ERROR
(
UTF8
<>
,
UTF16
<>
,
unsigned
char
,
ARRAY
(
'['
,
'\"'
,
0xF0u
,
0x80u
,
0x80u
,
0x80u
,
'\"'
,
']'
,
'\0'
));
...
...
@@ -790,14 +790,14 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
bool
Default
()
{
ADD_FAILURE
();
return
false
;
}
bool
Null
()
{
EXPECT_EQ
(
8u
,
step_
);
step_
++
;
return
true
;
}
bool
Bool
(
bool
b
)
{
bool
Bool
(
bool
b
)
{
switch
(
step_
)
{
case
4
:
EXPECT_TRUE
(
b
);
step_
++
;
return
true
;
case
6
:
EXPECT_FALSE
(
b
);
step_
++
;
return
true
;
default
:
ADD_FAILURE
();
return
false
;
}
}
bool
Int
(
int
i
)
{
bool
Int
(
int
i
)
{
switch
(
step_
)
{
case
10
:
EXPECT_EQ
(
123
,
i
);
step_
++
;
return
true
;
case
15
:
EXPECT_EQ
(
1
,
i
);
step_
++
;
return
true
;
...
...
@@ -808,7 +808,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
}
bool
Uint
(
unsigned
i
)
{
return
Int
(
static_cast
<
int
>
(
i
));
}
bool
Double
(
double
d
)
{
EXPECT_EQ
(
12u
,
step_
);
EXPECT_DOUBLE_EQ
(
3.1416
,
d
);
step_
++
;
return
true
;
}
bool
String
(
const
char
*
str
,
size_t
,
bool
)
{
bool
String
(
const
char
*
str
,
size_t
,
bool
)
{
switch
(
step_
)
{
case
1
:
EXPECT_STREQ
(
"hello"
,
str
);
step_
++
;
return
true
;
case
2
:
EXPECT_STREQ
(
"world"
,
str
);
step_
++
;
return
true
;
...
...
@@ -1045,7 +1045,7 @@ struct StreamTraits<CustomStringStream<Encoding> > {
};
} // namespace rapidjson
#endif
#endif
TEST
(
Reader
,
CustomStringStream
)
{
const
char
*
json
=
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
: true ,
\"
f
\"
: false,
\"
n
\"
: null,
\"
i
\"
:123,
\"
pi
\"
: 3.1416,
\"
a
\"
:[1, 2, 3] } "
;
...
...
@@ -1069,7 +1069,7 @@ public:
return
c
==
std
::
char_traits
<
char
>::
eof
()
?
'\0'
:
static_cast
<
Ch
>
(
c
);
}
Ch
Take
()
{
Ch
Take
()
{
int
c
=
is_
.
get
();
return
c
==
std
::
char_traits
<
char
>::
eof
()
?
'\0'
:
static_cast
<
Ch
>
(
c
);
}
...
...
@@ -1097,7 +1097,7 @@ TEST(Reader, Parse_IStreamWrapper_StringStream) {
Reader
reader
;
ParseArrayHandler
<
4
>
h
;
reader
.
Parse
(
is
,
h
);
EXPECT_FALSE
(
reader
.
HasParseError
());
EXPECT_FALSE
(
reader
.
HasParseError
());
}
// Test iterative parsing.
...
...
@@ -1195,7 +1195,7 @@ struct IterativeParsingReaderHandler {
bool
StartObject
()
{
RAPIDJSON_ASSERT
(
LogCount
<
LogCapacity
);
Logs
[
LogCount
++
]
=
LOG_STARTOBJECT
;
return
true
;
}
bool
Key
(
const
Ch
*
,
SizeType
,
bool
)
{
RAPIDJSON_ASSERT
(
LogCount
<
LogCapacity
);
Logs
[
LogCount
++
]
=
LOG_KEY
;
return
true
;
}
bool
EndObject
(
SizeType
c
)
{
RAPIDJSON_ASSERT
(
LogCount
<
LogCapacity
);
Logs
[
LogCount
++
]
=
LOG_ENDOBJECT
;
...
...
@@ -1446,7 +1446,7 @@ TEST(Reader, ParseEmptyOnelineComment) {
}
TEST
(
Reader
,
ParseMultipleCommentsInARow
)
{
const
char
*
json
=
const
char
*
json
=
"{/* first comment *//* second */
\n
"
"/* third */ /*fourth*/// last one
\n
"
"
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
: true,
\"
f
\"
: false,
\"
n
\"
: null,
\"
i
\"
:123,
\"
pi
\"
: 3.1416,
\"
a
\"
:[1, 2, 3] }"
;
...
...
@@ -1541,7 +1541,8 @@ struct NumbersAsStringsHandler {
// 'str' is not null-terminated
bool
RawNumber
(
const
char
*
str
,
SizeType
length
,
bool
)
{
EXPECT_TRUE
(
str
!=
0
);
EXPECT_TRUE
(
strncmp
(
str
,
"3.1416"
,
length
)
==
0
);
EXPECT_TRUE
(
expected_len_
==
length
);
EXPECT_TRUE
(
strncmp
(
str
,
expected_
,
length
)
==
0
);
return
true
;
}
bool
String
(
const
char
*
,
SizeType
,
bool
)
{
return
true
;
}
...
...
@@ -1550,24 +1551,84 @@ struct NumbersAsStringsHandler {
bool
EndObject
(
SizeType
)
{
return
true
;
}
bool
StartArray
()
{
return
true
;
}
bool
EndArray
(
SizeType
)
{
return
true
;
}
NumbersAsStringsHandler
(
const
char
*
expected
)
:
expected_
(
expected
)
,
expected_len_
(
strlen
(
expected
))
{}
const
char
*
expected_
;
size_t
expected_len_
;
};
TEST
(
Reader
,
NumbersAsStrings
)
{
{
const
char
*
json
=
"{
\"
pi
\"
: 3.1416 } "
;
StringStream
s
(
json
);
NumbersAsStringsHandler
h
;
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
{
char
*
json
=
StrDup
(
"{
\"
pi
\"
: 3.1416 } "
);
InsituStringStream
s
(
json
);
NumbersAsStringsHandler
h
;
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseInsituFlag
|
kParseNumbersAsStringsFlag
>
(
s
,
h
));
free
(
json
);
}
{
const
char
*
json
=
"{
\"
pi
\"
: 3.1416 } "
;
StringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"3.1416"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
{
char
*
json
=
StrDup
(
"{
\"
pi
\"
: 3.1416 } "
);
InsituStringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"3.1416"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseInsituFlag
|
kParseNumbersAsStringsFlag
>
(
s
,
h
));
free
(
json
);
}
{
const
char
*
json
=
"{
\"
gigabyte
\"
: 1.0e9 } "
;
StringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"1.0e9"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
{
char
*
json
=
StrDup
(
"{
\"
gigabyte
\"
: 1.0e9 } "
);
InsituStringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"1.0e9"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseInsituFlag
|
kParseNumbersAsStringsFlag
>
(
s
,
h
));
free
(
json
);
}
{
const
char
*
json
=
"{
\"
pi
\"
: 314.159e-2 } "
;
StringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"314.159e-2"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
{
char
*
json
=
StrDup
(
"{
\"
gigabyte
\"
: 314.159e-2 } "
);
InsituStringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"314.159e-2"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseInsituFlag
|
kParseNumbersAsStringsFlag
>
(
s
,
h
));
free
(
json
);
}
{
const
char
*
json
=
"{
\"
negative
\"
: -1.54321 } "
;
StringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"-1.54321"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
{
char
*
json
=
StrDup
(
"{
\"
negative
\"
: -1.54321 } "
);
InsituStringStream
s
(
json
);
NumbersAsStringsHandler
h
(
"-1.54321"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseInsituFlag
|
kParseNumbersAsStringsFlag
>
(
s
,
h
));
free
(
json
);
}
{
const
char
*
json
=
"{
\"
pi
\"
: 314.159e-2 } "
;
std
::
stringstream
ss
(
json
);
IStreamWrapper
s
(
ss
);
NumbersAsStringsHandler
h
(
"314.159e-2"
);
Reader
reader
;
EXPECT_TRUE
(
reader
.
Parse
<
kParseNumbersAsStringsFlag
>
(
s
,
h
));
}
}
template
<
unsigned
extraFlags
>
...
...
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