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
9974e355
Commit
9974e355
authored
Jul 15, 2014
by
miloyip
Browse files
Options
Browse Files
Download
Plain Diff
Merge conflicts and suppress VC warnings
parents
a37a1881
2d732794
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
269 additions
and
73 deletions
+269
-73
encodings.h
include/rapidjson/encodings.h
+1
-0
prettywriter.h
include/rapidjson/prettywriter.h
+17
-14
rapidjson.h
include/rapidjson/rapidjson.h
+37
-11
reader.h
include/rapidjson/reader.h
+1
-0
writer.h
include/rapidjson/writer.h
+82
-45
unittest.h
test/unittest/unittest.h
+18
-0
writertest.cpp
test/unittest/writertest.cpp
+113
-3
No files found.
include/rapidjson/encodings.h
View file @
9974e355
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#ifdef _MSC_VER
#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
4244
)
// conversion from 'type1' to 'type2', possible loss of data
RAPIDJSON_DIAG_OFF
(
4244
)
// conversion from 'type1' to 'type2', possible loss of data
RAPIDJSON_DIAG_OFF
(
4702
)
// unreachable code
#elif defined(__GNUC__)
#elif defined(__GNUC__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
effc
++
)
RAPIDJSON_DIAG_OFF
(
effc
++
)
...
...
include/rapidjson/prettywriter.h
View file @
9974e355
...
@@ -78,13 +78,13 @@ public:
...
@@ -78,13 +78,13 @@ public:
bool
empty
=
Base
::
level_stack_
.
template
Pop
<
typename
Base
::
Level
>
(
1
)
->
valueCount
==
0
;
bool
empty
=
Base
::
level_stack_
.
template
Pop
<
typename
Base
::
Level
>
(
1
)
->
valueCount
==
0
;
if
(
!
empty
)
{
if
(
!
empty
)
{
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
WriteIndent
();
WriteIndent
();
}
}
if
(
!
Base
::
WriteEndObject
())
if
(
!
Base
::
WriteEndObject
())
return
false
;
return
false
;
if
(
Base
::
level_stack_
.
Empty
())
// end of json text
if
(
Base
::
level_stack_
.
Empty
())
// end of json text
Base
::
os_
.
Flush
();
Base
::
os_
->
Flush
();
return
true
;
return
true
;
}
}
...
@@ -101,13 +101,13 @@ public:
...
@@ -101,13 +101,13 @@ public:
bool
empty
=
Base
::
level_stack_
.
template
Pop
<
typename
Base
::
Level
>
(
1
)
->
valueCount
==
0
;
bool
empty
=
Base
::
level_stack_
.
template
Pop
<
typename
Base
::
Level
>
(
1
)
->
valueCount
==
0
;
if
(
!
empty
)
{
if
(
!
empty
)
{
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
WriteIndent
();
WriteIndent
();
}
}
if
(
!
Base
::
WriteEndArray
())
if
(
!
Base
::
WriteEndArray
())
return
false
;
return
false
;
if
(
Base
::
level_stack_
.
Empty
())
// end of json text
if
(
Base
::
level_stack_
.
Empty
())
// end of json text
Base
::
os_
.
Flush
();
Base
::
os_
->
Flush
();
return
true
;
return
true
;
}
}
...
@@ -137,26 +137,26 @@ protected:
...
@@ -137,26 +137,26 @@ protected:
if
(
level
->
inArray
)
{
if
(
level
->
inArray
)
{
if
(
level
->
valueCount
>
0
)
{
if
(
level
->
valueCount
>
0
)
{
Base
::
os_
.
Put
(
','
);
// add comma if it is not the first element in array
Base
::
os_
->
Put
(
','
);
// add comma if it is not the first element in array
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
}
}
else
else
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
WriteIndent
();
WriteIndent
();
}
}
else
{
// in object
else
{
// in object
if
(
level
->
valueCount
>
0
)
{
if
(
level
->
valueCount
>
0
)
{
if
(
level
->
valueCount
%
2
==
0
)
{
if
(
level
->
valueCount
%
2
==
0
)
{
Base
::
os_
.
Put
(
','
);
Base
::
os_
->
Put
(
','
);
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
}
}
else
{
else
{
Base
::
os_
.
Put
(
':'
);
Base
::
os_
->
Put
(
':'
);
Base
::
os_
.
Put
(
' '
);
Base
::
os_
->
Put
(
' '
);
}
}
}
}
else
else
Base
::
os_
.
Put
(
'\n'
);
Base
::
os_
->
Put
(
'\n'
);
if
(
level
->
valueCount
%
2
==
0
)
if
(
level
->
valueCount
%
2
==
0
)
WriteIndent
();
WriteIndent
();
...
@@ -165,13 +165,16 @@ protected:
...
@@ -165,13 +165,16 @@ protected:
RAPIDJSON_ASSERT
(
type
==
kStringType
);
// if it's in object, then even number should be a name
RAPIDJSON_ASSERT
(
type
==
kStringType
);
// if it's in object, then even number should be a name
level
->
valueCount
++
;
level
->
valueCount
++
;
}
}
else
else
{
RAPIDJSON_ASSERT
(
type
==
kObjectType
||
type
==
kArrayType
);
RAPIDJSON_ASSERT
(
type
==
kObjectType
||
type
==
kArrayType
);
RAPIDJSON_ASSERT
(
!
Base
::
hasRoot_
);
// Should only has one and only one root.
Base
::
hasRoot_
=
true
;
}
}
}
void
WriteIndent
()
{
void
WriteIndent
()
{
size_t
count
=
(
Base
::
level_stack_
.
GetSize
()
/
sizeof
(
typename
Base
::
Level
))
*
indentCharCount_
;
size_t
count
=
(
Base
::
level_stack_
.
GetSize
()
/
sizeof
(
typename
Base
::
Level
))
*
indentCharCount_
;
PutN
(
Base
::
os_
,
indentChar_
,
count
);
PutN
(
*
Base
::
os_
,
indentChar_
,
count
);
}
}
Ch
indentChar_
;
Ch
indentChar_
;
...
...
include/rapidjson/rapidjson.h
View file @
9974e355
...
@@ -52,23 +52,49 @@
...
@@ -52,23 +52,49 @@
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
//! Endianness of the machine.
//! Endianness of the machine.
/*! GCC provided macro for detecting endianness of the target machine. But other
/*! GCC
4.6
provided macro for detecting endianness of the target machine. But other
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
Implemented with reference to
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
*/
*/
#ifndef RAPIDJSON_ENDIAN
#ifndef RAPIDJSON_ENDIAN
#ifdef __BYTE_ORDER__
// Detect with GCC 4.6's macro
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# ifdef __BYTE_ORDER__
#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#else
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
#define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#endif // __BYTE_ORDER__
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
#else
# else
#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
#endif
# endif // __BYTE_ORDER__
// Detect with GLIBC's endian.h
# elif defined(__GLIBC__)
# include <endian.h>
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif (__BYTE_ORDER == __BIG_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif // __GLIBC__
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
// Detect with architecture macros
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif
#endif // RAPIDJSON_ENDIAN
#endif // RAPIDJSON_ENDIAN
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ALIGNSIZE
// RAPIDJSON_ALIGNSIZE
...
...
include/rapidjson/reader.h
View file @
9974e355
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#ifdef _MSC_VER
#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
4127
)
// conditional expression is constant
RAPIDJSON_DIAG_OFF
(
4127
)
// conditional expression is constant
RAPIDJSON_DIAG_OFF
(
4702
)
// unreachable code
#endif
#endif
#define RAPIDJSON_NOTHING
/* deliberately empty */
#define RAPIDJSON_NOTHING
/* deliberately empty */
...
...
include/rapidjson/writer.h
View file @
9974e355
...
@@ -41,8 +41,41 @@ public:
...
@@ -41,8 +41,41 @@ public:
\param levelDepth Initial capacity of stack.
\param levelDepth Initial capacity of stack.
*/
*/
Writer
(
OutputStream
&
os
,
Allocator
*
allocator
=
0
,
size_t
levelDepth
=
kDefaultLevelDepth
)
:
Writer
(
OutputStream
&
os
,
Allocator
*
allocator
=
0
,
size_t
levelDepth
=
kDefaultLevelDepth
)
:
os_
(
os
),
level_stack_
(
allocator
,
levelDepth
*
sizeof
(
Level
)),
os_
(
&
os
),
level_stack_
(
allocator
,
levelDepth
*
sizeof
(
Level
)),
doublePrecision_
(
kDefaultDoublePrecision
)
{}
doublePrecision_
(
kDefaultDoublePrecision
),
hasRoot_
(
false
)
{}
//! Reset the writer with a new stream.
/*!
This function reset the writer with a new stream and default settings,
in order to make a Writer object reusable for output multiple JSONs.
\param os New output stream.
\code
Writer<OutputStream> writer(os1);
writer.StartObject();
// ...
writer.EndObject();
writer.Reset(os2);
writer.StartObject();
// ...
writer.EndObject();
\endcode
*/
void
Reset
(
OutputStream
&
os
)
{
os_
=
&
os
;
doublePrecision_
=
kDefaultDoublePrecision
;
hasRoot_
=
false
;
level_stack_
.
Clear
();
}
//! Checks whether the output is a complete JSON.
/*!
A complete JSON has a complete root object or array.
*/
bool
IsComplete
()
const
{
return
hasRoot_
&&
level_stack_
.
Empty
();
}
//! Set the number of significant digits for \c double values
//! Set the number of significant digits for \c double values
/*! When writing a \c double value to the \c OutputStream, the number
/*! When writing a \c double value to the \c OutputStream, the number
...
@@ -103,7 +136,7 @@ public:
...
@@ -103,7 +136,7 @@ public:
level_stack_
.
template
Pop
<
Level
>
(
1
);
level_stack_
.
template
Pop
<
Level
>
(
1
);
bool
ret
=
WriteEndObject
();
bool
ret
=
WriteEndObject
();
if
(
level_stack_
.
Empty
())
// end of json text
if
(
level_stack_
.
Empty
())
// end of json text
os_
.
Flush
();
os_
->
Flush
();
return
ret
;
return
ret
;
}
}
...
@@ -120,7 +153,7 @@ public:
...
@@ -120,7 +153,7 @@ public:
level_stack_
.
template
Pop
<
Level
>
(
1
);
level_stack_
.
template
Pop
<
Level
>
(
1
);
bool
ret
=
WriteEndArray
();
bool
ret
=
WriteEndArray
();
if
(
level_stack_
.
Empty
())
// end of json text
if
(
level_stack_
.
Empty
())
// end of json text
os_
.
Flush
();
os_
->
Flush
();
return
ret
;
return
ret
;
}
}
//@}
//@}
...
@@ -161,22 +194,22 @@ protected:
...
@@ -161,22 +194,22 @@ protected:
static
const
size_t
kDefaultLevelDepth
=
32
;
static
const
size_t
kDefaultLevelDepth
=
32
;
bool
WriteNull
()
{
bool
WriteNull
()
{
os_
.
Put
(
'n'
);
os_
.
Put
(
'u'
);
os_
.
Put
(
'l'
);
os_
.
Put
(
'l'
);
return
true
;
os_
->
Put
(
'n'
);
os_
->
Put
(
'u'
);
os_
->
Put
(
'l'
);
os_
->
Put
(
'l'
);
return
true
;
}
}
bool
WriteBool
(
bool
b
)
{
bool
WriteBool
(
bool
b
)
{
if
(
b
)
{
if
(
b
)
{
os_
.
Put
(
't'
);
os_
.
Put
(
'r'
);
os_
.
Put
(
'u'
);
os_
.
Put
(
'e'
);
os_
->
Put
(
't'
);
os_
->
Put
(
'r'
);
os_
->
Put
(
'u'
);
os_
->
Put
(
'e'
);
}
}
else
{
else
{
os_
.
Put
(
'f'
);
os_
.
Put
(
'a'
);
os_
.
Put
(
'l'
);
os_
.
Put
(
's'
);
os_
.
Put
(
'e'
);
os_
->
Put
(
'f'
);
os_
->
Put
(
'a'
);
os_
->
Put
(
'l'
);
os_
->
Put
(
's'
);
os_
->
Put
(
'e'
);
}
}
return
true
;
return
true
;
}
}
bool
WriteInt
(
int
i
)
{
bool
WriteInt
(
int
i
)
{
if
(
i
<
0
)
{
if
(
i
<
0
)
{
os_
.
Put
(
'-'
);
os_
->
Put
(
'-'
);
i
=
-
i
;
i
=
-
i
;
}
}
return
WriteUint
((
unsigned
)
i
);
return
WriteUint
((
unsigned
)
i
);
...
@@ -192,14 +225,14 @@ protected:
...
@@ -192,14 +225,14 @@ protected:
do
{
do
{
--
p
;
--
p
;
os_
.
Put
(
*
p
);
os_
->
Put
(
*
p
);
}
while
(
p
!=
buffer
);
}
while
(
p
!=
buffer
);
return
true
;
return
true
;
}
}
bool
WriteInt64
(
int64_t
i64
)
{
bool
WriteInt64
(
int64_t
i64
)
{
if
(
i64
<
0
)
{
if
(
i64
<
0
)
{
os_
.
Put
(
'-'
);
os_
->
Put
(
'-'
);
i64
=
-
i64
;
i64
=
-
i64
;
}
}
WriteUint64
((
uint64_t
)
i64
);
WriteUint64
((
uint64_t
)
i64
);
...
@@ -216,7 +249,7 @@ protected:
...
@@ -216,7 +249,7 @@ protected:
do
{
do
{
--
p
;
--
p
;
os_
.
Put
(
*
p
);
os_
->
Put
(
*
p
);
}
while
(
p
!=
buffer
);
}
while
(
p
!=
buffer
);
return
true
;
return
true
;
}
}
...
@@ -233,7 +266,7 @@ protected:
...
@@ -233,7 +266,7 @@ protected:
int
ret
=
RAPIDJSON_SNPRINTF
(
buffer
,
sizeof
(
buffer
),
"%.*g"
,
doublePrecision_
,
d
);
int
ret
=
RAPIDJSON_SNPRINTF
(
buffer
,
sizeof
(
buffer
),
"%.*g"
,
doublePrecision_
,
d
);
RAPIDJSON_ASSERT
(
ret
>=
1
);
RAPIDJSON_ASSERT
(
ret
>=
1
);
for
(
int
i
=
0
;
i
<
ret
;
i
++
)
for
(
int
i
=
0
;
i
<
ret
;
i
++
)
os_
.
Put
(
buffer
[
i
]);
os_
->
Put
(
buffer
[
i
]);
return
true
;
return
true
;
}
}
#undef RAPIDJSON_SNPRINTF
#undef RAPIDJSON_SNPRINTF
...
@@ -252,7 +285,7 @@ protected:
...
@@ -252,7 +285,7 @@ protected:
#undef Z16
#undef Z16
};
};
os_
.
Put
(
'\"'
);
os_
->
Put
(
'\"'
);
GenericStringStream
<
SourceEncoding
>
is
(
str
);
GenericStringStream
<
SourceEncoding
>
is
(
str
);
while
(
is
.
Tell
()
<
length
)
{
while
(
is
.
Tell
()
<
length
)
{
const
Ch
c
=
is
.
Peek
();
const
Ch
c
=
is
.
Peek
();
...
@@ -261,55 +294,55 @@ protected:
...
@@ -261,55 +294,55 @@ protected:
unsigned
codepoint
;
unsigned
codepoint
;
if
(
!
SourceEncoding
::
Decode
(
is
,
&
codepoint
))
if
(
!
SourceEncoding
::
Decode
(
is
,
&
codepoint
))
return
false
;
return
false
;
os_
.
Put
(
'\\'
);
os_
->
Put
(
'\\'
);
os_
.
Put
(
'u'
);
os_
->
Put
(
'u'
);
if
(
codepoint
<=
0xD7FF
||
(
codepoint
>=
0xE000
&&
codepoint
<=
0xFFFF
))
{
if
(
codepoint
<=
0xD7FF
||
(
codepoint
>=
0xE000
&&
codepoint
<=
0xFFFF
))
{
os_
.
Put
(
hexDigits
[(
codepoint
>>
12
)
&
15
]);
os_
->
Put
(
hexDigits
[(
codepoint
>>
12
)
&
15
]);
os_
.
Put
(
hexDigits
[(
codepoint
>>
8
)
&
15
]);
os_
->
Put
(
hexDigits
[(
codepoint
>>
8
)
&
15
]);
os_
.
Put
(
hexDigits
[(
codepoint
>>
4
)
&
15
]);
os_
->
Put
(
hexDigits
[(
codepoint
>>
4
)
&
15
]);
os_
.
Put
(
hexDigits
[(
codepoint
)
&
15
]);
os_
->
Put
(
hexDigits
[(
codepoint
)
&
15
]);
}
}
else
if
(
codepoint
>=
0x010000
&&
codepoint
<=
0x10FFFF
)
{
else
if
(
codepoint
>=
0x010000
&&
codepoint
<=
0x10FFFF
)
{
// Surrogate pair
// Surrogate pair
unsigned
s
=
codepoint
-
0x010000
;
unsigned
s
=
codepoint
-
0x010000
;
unsigned
lead
=
(
s
>>
10
)
+
0xD800
;
unsigned
lead
=
(
s
>>
10
)
+
0xD800
;
unsigned
trail
=
(
s
&
0x3FF
)
+
0xDC00
;
unsigned
trail
=
(
s
&
0x3FF
)
+
0xDC00
;
os_
.
Put
(
hexDigits
[(
lead
>>
12
)
&
15
]);
os_
->
Put
(
hexDigits
[(
lead
>>
12
)
&
15
]);
os_
.
Put
(
hexDigits
[(
lead
>>
8
)
&
15
]);
os_
->
Put
(
hexDigits
[(
lead
>>
8
)
&
15
]);
os_
.
Put
(
hexDigits
[(
lead
>>
4
)
&
15
]);
os_
->
Put
(
hexDigits
[(
lead
>>
4
)
&
15
]);
os_
.
Put
(
hexDigits
[(
lead
)
&
15
]);
os_
->
Put
(
hexDigits
[(
lead
)
&
15
]);
os_
.
Put
(
'\\'
);
os_
->
Put
(
'\\'
);
os_
.
Put
(
'u'
);
os_
->
Put
(
'u'
);
os_
.
Put
(
hexDigits
[(
trail
>>
12
)
&
15
]);
os_
->
Put
(
hexDigits
[(
trail
>>
12
)
&
15
]);
os_
.
Put
(
hexDigits
[(
trail
>>
8
)
&
15
]);
os_
->
Put
(
hexDigits
[(
trail
>>
8
)
&
15
]);
os_
.
Put
(
hexDigits
[(
trail
>>
4
)
&
15
]);
os_
->
Put
(
hexDigits
[(
trail
>>
4
)
&
15
]);
os_
.
Put
(
hexDigits
[(
trail
)
&
15
]);
os_
->
Put
(
hexDigits
[(
trail
)
&
15
]);
}
}
else
else
return
false
;
// invalid code point
return
false
;
// invalid code point
}
}
else
if
((
sizeof
(
Ch
)
==
1
||
(
unsigned
)
c
<
256
)
&&
escape
[(
unsigned
char
)
c
])
{
else
if
((
sizeof
(
Ch
)
==
1
||
(
unsigned
)
c
<
256
)
&&
escape
[(
unsigned
char
)
c
])
{
is
.
Take
();
is
.
Take
();
os_
.
Put
(
'\\'
);
os_
->
Put
(
'\\'
);
os_
.
Put
(
escape
[(
unsigned
char
)
c
]);
os_
->
Put
(
escape
[(
unsigned
char
)
c
]);
if
(
escape
[(
unsigned
char
)
c
]
==
'u'
)
{
if
(
escape
[(
unsigned
char
)
c
]
==
'u'
)
{
os_
.
Put
(
'0'
);
os_
->
Put
(
'0'
);
os_
.
Put
(
'0'
);
os_
->
Put
(
'0'
);
os_
.
Put
(
hexDigits
[(
unsigned
char
)
c
>>
4
]);
os_
->
Put
(
hexDigits
[(
unsigned
char
)
c
>>
4
]);
os_
.
Put
(
hexDigits
[(
unsigned
char
)
c
&
0xF
]);
os_
->
Put
(
hexDigits
[(
unsigned
char
)
c
&
0xF
]);
}
}
}
}
else
else
Transcoder
<
SourceEncoding
,
TargetEncoding
>::
Transcode
(
is
,
os_
);
Transcoder
<
SourceEncoding
,
TargetEncoding
>::
Transcode
(
is
,
*
os_
);
}
}
os_
.
Put
(
'\"'
);
os_
->
Put
(
'\"'
);
return
true
;
return
true
;
}
}
bool
WriteStartObject
()
{
os_
.
Put
(
'{'
);
return
true
;
}
bool
WriteStartObject
()
{
os_
->
Put
(
'{'
);
return
true
;
}
bool
WriteEndObject
()
{
os_
.
Put
(
'}'
);
return
true
;
}
bool
WriteEndObject
()
{
os_
->
Put
(
'}'
);
return
true
;
}
bool
WriteStartArray
()
{
os_
.
Put
(
'['
);
return
true
;
}
bool
WriteStartArray
()
{
os_
->
Put
(
'['
);
return
true
;
}
bool
WriteEndArray
()
{
os_
.
Put
(
']'
);
return
true
;
}
bool
WriteEndArray
()
{
os_
->
Put
(
']'
);
return
true
;
}
void
Prefix
(
Type
type
)
{
void
Prefix
(
Type
type
)
{
(
void
)
type
;
(
void
)
type
;
...
@@ -317,21 +350,25 @@ protected:
...
@@ -317,21 +350,25 @@ protected:
Level
*
level
=
level_stack_
.
template
Top
<
Level
>
();
Level
*
level
=
level_stack_
.
template
Top
<
Level
>
();
if
(
level
->
valueCount
>
0
)
{
if
(
level
->
valueCount
>
0
)
{
if
(
level
->
inArray
)
if
(
level
->
inArray
)
os_
.
Put
(
','
);
// add comma if it is not the first element in array
os_
->
Put
(
','
);
// add comma if it is not the first element in array
else
// in object
else
// in object
os_
.
Put
((
level
->
valueCount
%
2
==
0
)
?
','
:
':'
);
os_
->
Put
((
level
->
valueCount
%
2
==
0
)
?
','
:
':'
);
}
}
if
(
!
level
->
inArray
&&
level
->
valueCount
%
2
==
0
)
if
(
!
level
->
inArray
&&
level
->
valueCount
%
2
==
0
)
RAPIDJSON_ASSERT
(
type
==
kStringType
);
// if it's in object, then even number should be a name
RAPIDJSON_ASSERT
(
type
==
kStringType
);
// if it's in object, then even number should be a name
level
->
valueCount
++
;
level
->
valueCount
++
;
}
}
else
else
{
RAPIDJSON_ASSERT
(
type
==
kObjectType
||
type
==
kArrayType
);
RAPIDJSON_ASSERT
(
type
==
kObjectType
||
type
==
kArrayType
);
RAPIDJSON_ASSERT
(
!
hasRoot_
);
// Should only has one and only one root.
hasRoot_
=
true
;
}
}
}
OutputStream
&
os_
;
OutputStream
*
os_
;
internal
::
Stack
<
Allocator
>
level_stack_
;
internal
::
Stack
<
Allocator
>
level_stack_
;
int
doublePrecision_
;
int
doublePrecision_
;
bool
hasRoot_
;
static
const
int
kDefaultDoublePrecision
=
6
;
static
const
int
kDefaultDoublePrecision
=
6
;
...
...
test/unittest/unittest.h
View file @
9974e355
...
@@ -56,4 +56,22 @@ inline void TempFilename(char *filename) {
...
@@ -56,4 +56,22 @@ inline void TempFilename(char *filename) {
filename
[
i
]
=
filename
[
i
+
1
];
filename
[
i
]
=
filename
[
i
+
1
];
}
}
// Use exception for catching assert
#if _MSC_VER
#pragma warning(disable : 4127)
#endif
class
AssertException
:
public
std
::
exception
{
public
:
AssertException
(
const
char
*
w
)
:
what_
(
w
)
{}
AssertException
(
const
AssertException
&
other
)
:
what_
(
other
.
what_
)
{}
AssertException
&
operator
=
(
const
AssertException
&
rhs
)
{
what_
=
rhs
.
what_
;
return
*
this
;
}
virtual
const
char
*
what
()
const
throw
()
{
return
what_
;
}
private
:
const
char
*
what_
;
};
#define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x))
#endif // UNITTEST_H_
#endif // UNITTEST_H_
test/unittest/writertest.cpp
View file @
9974e355
#include "unittest.h"
#include "unittest.h"
#include "rapidjson/document.h"
#include "rapidjson/document.h"
#include "rapidjson/reader.h"
#include "rapidjson/reader.h"
#include "rapidjson/writer.h"
#include "rapidjson/writer.h"
...
@@ -14,6 +15,7 @@ TEST(Writer, Compact) {
...
@@ -14,6 +15,7 @@ TEST(Writer, Compact) {
reader
.
Parse
<
0
>
(
s
,
writer
);
reader
.
Parse
<
0
>
(
s
,
writer
);
EXPECT_STREQ
(
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3]}"
,
buffer
.
GetString
());
EXPECT_STREQ
(
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3]}"
,
buffer
.
GetString
());
EXPECT_EQ
(
77u
,
buffer
.
GetSize
());
EXPECT_EQ
(
77u
,
buffer
.
GetSize
());
EXPECT_TRUE
(
writer
.
IsComplete
());
}
}
// json -> parse -> writer -> json
// json -> parse -> writer -> json
...
@@ -25,6 +27,7 @@ TEST(Writer, Compact) {
...
@@ -25,6 +27,7 @@ TEST(Writer, Compact) {
Reader
reader
;
\
Reader
reader
;
\
reader
.
Parse
<
0
>
(
s
,
writer
);
\
reader
.
Parse
<
0
>
(
s
,
writer
);
\
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
\
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
\
EXPECT_TRUE
(
writer
.
IsComplete
());
\
}
}
TEST
(
Writer
,
Int
)
{
TEST
(
Writer
,
Int
)
{
...
@@ -80,9 +83,10 @@ TEST(Writer,DoublePrecision) {
...
@@ -80,9 +83,10 @@ TEST(Writer,DoublePrecision) {
reader
.
Parse
<
0
>
(
s
,
writer
.
SetDoublePrecision
(
12
));
reader
.
Parse
<
0
>
(
s
,
writer
.
SetDoublePrecision
(
12
));
EXPECT_EQ
(
writer
.
GetDoublePrecision
(),
12
);
EXPECT_EQ
(
writer
.
GetDoublePrecision
(),
12
);
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
buffer
.
Clear
();
}
}
{
// explicit individual double precisions
{
// explicit individual double precisions
buffer
.
Clear
();
writer
.
Reset
(
buffer
);
writer
.
SetDoublePrecision
(
2
);
writer
.
SetDoublePrecision
(
2
);
writer
.
StartArray
();
writer
.
StartArray
();
writer
.
Double
(
1.2345
,
5
);
writer
.
Double
(
1.2345
,
5
);
...
@@ -93,11 +97,12 @@ TEST(Writer,DoublePrecision) {
...
@@ -93,11 +97,12 @@ TEST(Writer,DoublePrecision) {
EXPECT_EQ
(
writer
.
GetDoublePrecision
(),
2
);
EXPECT_EQ
(
writer
.
GetDoublePrecision
(),
2
);
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
buffer
.
Clear
();
}
}
{
// write with default precision (output with precision loss)
{
// write with default precision (output with precision loss)
Document
d
;
Document
d
;
d
.
Parse
<
0
>
(
json
);
d
.
Parse
<
0
>
(
json
);
buffer
.
Clear
();
writer
.
Reset
(
buffer
);
d
.
Accept
(
writer
.
SetDoublePrecision
());
d
.
Accept
(
writer
.
SetDoublePrecision
());
// parsed again to avoid platform-dependent floating point outputs
// parsed again to avoid platform-dependent floating point outputs
...
@@ -108,7 +113,6 @@ TEST(Writer,DoublePrecision) {
...
@@ -108,7 +113,6 @@ TEST(Writer,DoublePrecision) {
EXPECT_DOUBLE_EQ
(
d
[
1u
].
GetDouble
(),
1.23457
);
EXPECT_DOUBLE_EQ
(
d
[
1u
].
GetDouble
(),
1.23457
);
EXPECT_DOUBLE_EQ
(
d
[
2u
].
GetDouble
(),
0.123457
);
EXPECT_DOUBLE_EQ
(
d
[
2u
].
GetDouble
(),
0.123457
);
EXPECT_DOUBLE_EQ
(
d
[
3u
].
GetDouble
(),
1234570
);
EXPECT_DOUBLE_EQ
(
d
[
3u
].
GetDouble
(),
1234570
);
buffer
.
Clear
();
}
}
}
}
...
@@ -181,3 +185,109 @@ TEST(Writer, OStreamWrapper) {
...
@@ -181,3 +185,109 @@ TEST(Writer, OStreamWrapper) {
std
::
string
actual
=
ss
.
str
();
std
::
string
actual
=
ss
.
str
();
EXPECT_STREQ
(
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3]}"
,
actual
.
c_str
());
EXPECT_STREQ
(
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3]}"
,
actual
.
c_str
());
}
}
TEST
(
Writer
,
AssertRootMustBeArrayOrObject
)
{
#define T(x)\
{
\
StringBuffer
buffer
;
\
Writer
<
StringBuffer
>
writer
(
buffer
);
\
ASSERT_THROW
(
x
,
AssertException
);
\
}
T
(
writer
.
Bool
(
false
));
T
(
writer
.
Bool
(
true
));
T
(
writer
.
Null
());
T
(
writer
.
Int
(
0
));
T
(
writer
.
Uint
(
0
));
T
(
writer
.
Int64
(
0
));
T
(
writer
.
Uint64
(
0
));
T
(
writer
.
Double
(
0
));
T
(
writer
.
String
(
"foo"
));
#undef T
}
TEST
(
Writer
,
AssertIncorrectObjectLevel
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartObject
();
writer
.
EndObject
();
ASSERT_THROW
(
writer
.
EndObject
(),
AssertException
);
}
TEST
(
Writer
,
AssertIncorrectArrayLevel
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartArray
();
writer
.
EndArray
();
ASSERT_THROW
(
writer
.
EndArray
(),
AssertException
);
}
TEST
(
Writer
,
AssertIncorrectEndObject
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartObject
();
ASSERT_THROW
(
writer
.
EndArray
(),
AssertException
);
}
TEST
(
Writer
,
AssertIncorrectEndArray
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartObject
();
ASSERT_THROW
(
writer
.
EndArray
(),
AssertException
);
}
TEST
(
Writer
,
AssertObjectKeyNotString
)
{
#define T(x)\
{
\
StringBuffer
buffer
;
\
Writer
<
StringBuffer
>
writer
(
buffer
);
\
writer
.
StartObject
();
\
ASSERT_THROW
(
x
,
AssertException
);
\
}
T
(
writer
.
Bool
(
false
));
T
(
writer
.
Bool
(
true
));
T
(
writer
.
Null
());
T
(
writer
.
Int
(
0
));
T
(
writer
.
Uint
(
0
));
T
(
writer
.
Int64
(
0
));
T
(
writer
.
Uint64
(
0
));
T
(
writer
.
Double
(
0
));
T
(
writer
.
StartObject
());
T
(
writer
.
StartArray
());
#undef T
}
TEST
(
Writer
,
AssertMultipleRoot
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
writer
.
StartObject
();
writer
.
EndObject
();
ASSERT_THROW
(
writer
.
StartObject
(),
AssertException
);
}
TEST
(
Writer
,
RootObjectIsComplete
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
StartObject
();
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
String
(
"foo"
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
Int
(
1
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
EndObject
();
EXPECT_TRUE
(
writer
.
IsComplete
());
}
TEST
(
Writer
,
RootArrayIsComplete
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
StartArray
();
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
String
(
"foo"
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
Int
(
1
);
EXPECT_FALSE
(
writer
.
IsComplete
());
writer
.
EndArray
();
EXPECT_TRUE
(
writer
.
IsComplete
());
}
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