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
8d70a8d0
Commit
8d70a8d0
authored
Jul 12, 2014
by
Milo Yip
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
e7865423
cb3f2131
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
150 additions
and
80 deletions
+150
-80
document.h
include/rapidjson/document.h
+19
-17
en.h
include/rapidjson/error/en.h
+3
-1
error.h
include/rapidjson/error/error.h
+78
-2
reader.h
include/rapidjson/reader.h
+50
-60
No files found.
include/rapidjson/document.h
View file @
8d70a8d0
...
...
@@ -1211,7 +1211,7 @@ public:
/*! \param allocator Optional allocator for allocating stack memory.
\param stackCapacity Initial capacity of stack in bytes.
*/
GenericDocument
(
Allocator
*
allocator
=
0
,
size_t
stackCapacity
=
kDefaultStackCapacity
)
:
stack_
(
allocator
,
stackCapacity
),
parse
ErrorCode_
(
kParseErrorNone
),
errorOffset_
(
0
)
{}
GenericDocument
(
Allocator
*
allocator
=
0
,
size_t
stackCapacity
=
kDefaultStackCapacity
)
:
stack_
(
allocator
,
stackCapacity
),
parse
Result_
(
)
{}
//!@name Parse from stream
//!@{
...
...
@@ -1227,16 +1227,11 @@ public:
GenericDocument
&
ParseStream
(
InputStream
&
is
)
{
ValueType
::
SetNull
();
// Remove existing root if exist
GenericReader
<
SourceEncoding
,
Encoding
,
Allocator
>
reader
(
&
GetAllocator
());
if
(
reader
.
template
Parse
<
parseFlags
>
(
is
,
*
this
))
{
ClearStackOnExit
scope
(
*
this
);
parseResult_
=
reader
.
template
Parse
<
parseFlags
>
(
is
,
*
this
);
if
(
parseResult_
)
{
RAPIDJSON_ASSERT
(
stack_
.
GetSize
()
==
sizeof
(
ValueType
));
// Got one and only one root object
this
->
RawAssign
(
*
stack_
.
template
Pop
<
ValueType
>
(
1
));
// Add this-> to prevent issue 13.
parseErrorCode_
=
kParseErrorNone
;
errorOffset_
=
0
;
}
else
{
parseErrorCode_
=
reader
.
GetParseErrorCode
();
errorOffset_
=
reader
.
GetErrorOffset
();
ClearStack
();
}
return
*
this
;
}
...
...
@@ -1332,14 +1327,14 @@ public:
//!@name Handling parse errors
//!@{
//! Whether a parse error
w
as occured in the last parsing.
bool
HasParseError
()
const
{
return
parse
ErrorCode_
!=
kParseErrorNone
;
}
//! Whether a parse error
h
as occured in the last parsing.
bool
HasParseError
()
const
{
return
parse
Result_
.
IsError
()
;
}
//! Get the
message of parsing error
.
ParseErrorCode
GetParseError
()
const
{
return
parse
ErrorCode_
;
}
//! Get the
\ref ParseErrorCode of last parsing
.
ParseErrorCode
GetParseError
()
const
{
return
parse
Result_
.
Code
()
;
}
//! Get the
offset in character of the parsing error
.
size_t
GetErrorOffset
()
const
{
return
errorOffset_
;
}
//! Get the
position of last parsing error in input, 0 otherwise
.
size_t
GetErrorOffset
()
const
{
return
parseResult_
.
Offset
()
;
}
//!@}
...
...
@@ -1350,6 +1345,14 @@ public:
size_t
GetStackCapacity
()
const
{
return
stack_
.
GetCapacity
();
}
private
:
// clear stack on any exit from ParseStream, e.g. due to exception
struct
ClearStackOnExit
{
explicit
ClearStackOnExit
(
GenericDocument
&
d
)
:
d_
(
d
)
{}
~
ClearStackOnExit
()
{
d_
.
ClearStack
();
}
private
:
GenericDocument
&
d_
;
};
// callers of the following private Handler functions
template
<
typename
,
typename
,
typename
>
friend
class
GenericReader
;
// for parsing
friend
class
GenericValue
<
Encoding
,
Allocator
>
;
// for deep copying
...
...
@@ -1401,8 +1404,7 @@ private:
static
const
size_t
kDefaultStackCapacity
=
1024
;
internal
::
Stack
<
Allocator
>
stack_
;
ParseErrorCode
parseErrorCode_
;
size_t
errorOffset_
;
ParseResult
parseResult_
;
};
//! GenericDocument with UTF8 encoding
...
...
include/rapidjson/error/en.h
View file @
8d70a8d0
...
...
@@ -32,12 +32,14 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
case
kParseErrorStringUnicodeSurrogateInvalid
:
return
RAPIDJSON_ERROR_STRING
(
"The surrogate pair in string is invalid."
);
case
kParseErrorStringEscapeInvalid
:
return
RAPIDJSON_ERROR_STRING
(
"Invalid escape character in string."
);
case
kParseErrorStringMissQuotationMark
:
return
RAPIDJSON_ERROR_STRING
(
"Missing a closing quotation mark in string."
);
case
kParseErrorStringInvalidEncoding
:
return
RAPIDJSON_ERROR_STRING
(
"Invalid enco
id
ng in string."
);
case
kParseErrorStringInvalidEncoding
:
return
RAPIDJSON_ERROR_STRING
(
"Invalid enco
di
ng in string."
);
case
kParseErrorNumberTooBig
:
return
RAPIDJSON_ERROR_STRING
(
"Number too big to be stored in double."
);
case
kParseErrorNumberMissFraction
:
return
RAPIDJSON_ERROR_STRING
(
"Miss fraction part in number."
);
case
kParseErrorNumberMissExponent
:
return
RAPIDJSON_ERROR_STRING
(
"Miss exponent in number."
);
case
kParseErrorTermination
:
return
RAPIDJSON_ERROR_STRING
(
"Terminate parsing due to Handler error."
);
default
:
return
RAPIDJSON_ERROR_STRING
(
"Unknown error."
);
}
...
...
include/rapidjson/error/error.h
View file @
8d70a8d0
#ifndef RAPIDJSON_ERROR_ERROR_H__
#define RAPIDJSON_ERROR_ERROR_H__
#include "../reader.h" // ParseErrorCode
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_CHARTYPE
...
...
@@ -29,6 +27,84 @@
namespace
rapidjson
{
///////////////////////////////////////////////////////////////////////////////
// ParseErrorCode
//! Error code of parsing.
/*! \see GenericReader::Parse, GenericReader::GetParseErrorCode
*/
enum
ParseErrorCode
{
kParseErrorNone
=
0
,
//!< No error.
kParseErrorDocumentEmpty
,
//!< The document is empty.
kParseErrorDocumentRootNotObjectOrArray
,
//!< The document root must be either object or array.
kParseErrorDocumentRootNotSingular
,
//!< The document root must not follow by other values.
kParseErrorValueInvalid
,
//!< Invalid value.
kParseErrorObjectMissName
,
//!< Missing a name for object member.
kParseErrorObjectMissColon
,
//!< Missing a colon after a name of object member.
kParseErrorObjectMissCommaOrCurlyBracket
,
//!< Missing a comma or '}' after an object member.
kParseErrorArrayMissCommaOrSquareBracket
,
//!< Missing a comma or ']' after an array element.
kParseErrorStringUnicodeEscapeInvalidHex
,
//!< Incorrect hex digit after \\u escape in string.
kParseErrorStringUnicodeSurrogateInvalid
,
//!< The surrogate pair in string is invalid.
kParseErrorStringEscapeInvalid
,
//!< Invalid escape character in string.
kParseErrorStringMissQuotationMark
,
//!< Missing a closing quotation mark in string.
kParseErrorStringInvalidEncoding
,
//!< Invalid encoding in string.
kParseErrorNumberTooBig
,
//!< Number too big to be stored in double.
kParseErrorNumberMissFraction
,
//!< Miss fraction part in number.
kParseErrorNumberMissExponent
,
//!< Miss exponent in number.
kParseErrorTermination
//!< Parsing was terminated.
};
//! Result of parsing (wraps ParseErrorCode)
/*!
\code
Document doc;
ParseResult ok = doc.Parse("[42]");
if (!ok) {
fprintf(stderr, "JSON parse error: %s (%u)",
GetParseError_En(ok.Code()), ok.Offset());
exit(EXIT_FAILURE);
}
\endcode
\see GenericReader::Parse, GenericDocument::Parse
*/
struct
ParseResult
{
//! Default constructor, no error.
ParseResult
()
:
code_
(
kParseErrorNone
),
offset_
(
0
)
{}
//! Constructor to set an error.
ParseResult
(
ParseErrorCode
code
,
size_t
offset
)
:
code_
(
code
),
offset_
(
offset
)
{}
//! Get the error code.
ParseErrorCode
Code
()
const
{
return
code_
;
}
//! Get the error offset, if \ref IsError(), 0 otherwise.
size_t
Offset
()
const
{
return
offset_
;
}
//! Conversion to \c bool, returns \c true, iff !\ref IsError().
operator
bool
()
const
{
return
!
IsError
();
}
//! Whether the result is an error.
bool
IsError
()
const
{
return
code_
!=
kParseErrorNone
;
}
bool
operator
==
(
const
ParseResult
&
that
)
const
{
return
code_
==
that
.
code_
;
}
bool
operator
==
(
ParseErrorCode
code
)
const
{
return
code_
==
code
;
}
friend
bool
operator
==
(
ParseErrorCode
code
,
const
ParseResult
&
err
)
{
return
code
==
err
.
code_
;
}
//! Reset error code.
void
Clear
()
{
Set
(
kParseErrorNone
);
}
//! Update error code and offset.
void
Set
(
ParseErrorCode
code
,
size_t
offset
=
0
)
{
code_
=
code
;
offset_
=
offset
;
}
private
:
ParseErrorCode
code_
;
size_t
offset_
;
};
//! Function pointer type of GetParseError().
/*! This is the prototype for GetParseError_X(), where X is a locale.
User can dynamically change locale in runtime, e.g.:
...
...
include/rapidjson/reader.h
View file @
8d70a8d0
...
...
@@ -24,12 +24,21 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
4127
)
// conditional expression is constant
#endif
#define RAPIDJSON_NOTHING
/* deliberately empty */
#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
RAPIDJSON_MULTILINEMACRO_BEGIN
\
if
(
HasParseError
())
{
return
value
;
}
\
RAPIDJSON_MULTILINEMACRO_END
#endif
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
RAPIDJSON_PARSE_ERROR_EARLY_RETURN
(
RAPIDJSON_NOTHING
)
#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN
\
RAPIDJSON_ASSERT
(
!
HasParseError
());
/* Error can only be assigned once */
\
parseErrorCode_
=
parseErrorCode
;
\
errorOffset_
=
offset
;
\
parseResult_
.
Set
(
parseErrorCode
,
offset
);
\
RAPIDJSON_MULTILINEMACRO_END
#endif
...
...
@@ -37,10 +46,12 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN
\
RAPIDJSON_PARSE_ERROR_NORETURN
(
parseErrorCode
,
offset
);
\
return
;
\
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
\
RAPIDJSON_MULTILINEMACRO_END
#endif
#include "error/error.h" // ParseErrorCode, ParseResult
namespace
rapidjson
{
///////////////////////////////////////////////////////////////////////////////
...
...
@@ -55,35 +66,6 @@ enum ParseFlag {
kParseValidateEncodingFlag
=
2
//!< Validate encoding of JSON strings.
};
//! Error code of parsing.
enum
ParseErrorCode
{
kParseErrorNone
=
0
,
//!< No error.
kParseErrorDocumentEmpty
,
//!< The document is empty.
kParseErrorDocumentRootNotObjectOrArray
,
//!< The document root must be either object or array.
kParseErrorDocumentRootNotSingular
,
//!< The document root must not follow by other values.
kParseErrorValueInvalid
,
//!< Invalid value.
kParseErrorObjectMissName
,
//!< Missing a name for object member.
kParseErrorObjectMissColon
,
//!< Missing a colon after a name of object member.
kParseErrorObjectMissCommaOrCurlyBracket
,
//!< Missing a comma or '}' after an object member.
kParseErrorArrayMissCommaOrSquareBracket
,
//!< Missing a comma or ']' after an array element.
kParseErrorStringUnicodeEscapeInvalidHex
,
//!< Incorrect hex digit after \\u escape in string.
kParseErrorStringUnicodeSurrogateInvalid
,
//!< The surrogate pair in string is invalid.
kParseErrorStringEscapeInvalid
,
//!< Invalid escape character in string.
kParseErrorStringMissQuotationMark
,
//!< Missing a closing quotation mark in string.
kParseErrorStringInvalidEncoding
,
//!< Invalid encoidng in string.
kParseErrorNumberTooBig
,
//!< Number too big to be stored in double.
kParseErrorNumberMissFraction
,
//!< Miss fraction part in number.
kParseErrorNumberMissExponent
,
//!< Miss exponent in number.
kParseErrorTermination
//!< Parsing was terminated.
};
///////////////////////////////////////////////////////////////////////////////
// Handler
...
...
@@ -292,7 +274,7 @@ public:
/*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
\param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
*/
GenericReader
(
Allocator
*
allocator
=
0
,
size_t
stackCapacity
=
kDefaultStackCapacity
)
:
stack_
(
allocator
,
stackCapacity
),
parse
ErrorCode_
(
kParseErrorNone
),
errorOffset_
(
0
)
{}
GenericReader
(
Allocator
*
allocator
=
0
,
size_t
stackCapacity
=
kDefaultStackCapacity
)
:
stack_
(
allocator
,
stackCapacity
),
parse
Result_
(
)
{}
//! Parse JSON text.
/*! \tparam parseFlags Combination of \ref ParseFlag.
...
...
@@ -303,32 +285,33 @@ public:
\return Whether the parsing is successful.
*/
template
<
unsigned
parseFlags
,
typename
InputStream
,
typename
Handler
>
bool
Parse
(
InputStream
&
is
,
Handler
&
handler
)
{
parseErrorCode_
=
kParseErrorNone
;
errorOffset_
=
0
;
ParseResult
Parse
(
InputStream
&
is
,
Handler
&
handler
)
{
parseResult_
.
Clear
();
ClearStackOnExit
scope
(
*
this
);
SkipWhitespace
(
is
);
if
(
is
.
Peek
()
==
'\0'
)
if
(
is
.
Peek
()
==
'\0'
)
{
RAPIDJSON_PARSE_ERROR_NORETURN
(
kParseErrorDocumentEmpty
,
is
.
Tell
());
RAPIDJSON_PARSE_ERROR_EARLY_RETURN
(
parseResult_
);
}
else
{
switch
(
is
.
Peek
())
{
case
'{'
:
ParseObject
<
parseFlags
>
(
is
,
handler
);
break
;
case
'['
:
ParseArray
<
parseFlags
>
(
is
,
handler
);
break
;
default
:
RAPIDJSON_PARSE_ERROR_NORETURN
(
kParseErrorDocumentRootNotObjectOrArray
,
is
.
Tell
());
}
if
(
HasParseError
())
goto
out
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN
(
parseResult_
);
SkipWhitespace
(
is
);
if
(
is
.
Peek
()
!=
'\0'
)
if
(
is
.
Peek
()
!=
'\0'
)
{
RAPIDJSON_PARSE_ERROR_NORETURN
(
kParseErrorDocumentRootNotSingular
,
is
.
Tell
());
RAPIDJSON_PARSE_ERROR_EARLY_RETURN
(
parseResult_
);
}
}
out
:
stack_
.
Clear
();
return
!
HasParseError
();
return
parseResult_
;
}
//! Parse JSON text (with \ref kParseDefaultFlags)
...
...
@@ -339,21 +322,34 @@ public:
\return Whether the parsing is successful.
*/
template
<
typename
InputStream
,
typename
Handler
>
bool
Parse
(
InputStream
&
is
,
Handler
&
handler
)
{
ParseResult
Parse
(
InputStream
&
is
,
Handler
&
handler
)
{
return
Parse
<
kParseDefaultFlags
>
(
is
,
handler
);
}
bool
HasParseError
()
const
{
return
parseErrorCode_
!=
kParseErrorNone
;
}
//! Whether a parse error has occured in the last parsing.
bool
HasParseError
()
const
{
return
parseResult_
.
IsError
();
}
ParseErrorCode
GetParseErrorCode
()
const
{
return
parseErrorCode_
;
}
//! Get the \ref ParseErrorCode of last parsing.
ParseErrorCode
GetParseErrorCode
()
const
{
return
parseResult_
.
Code
();
}
size_t
GetErrorOffset
()
const
{
return
errorOffset_
;
}
//! Get the position of last parsing error in input, 0 otherwise.
size_t
GetErrorOffset
()
const
{
return
parseResult_
.
Offset
();
}
private
:
// Prohibit copy constructor & assignment operator.
GenericReader
(
const
GenericReader
&
);
GenericReader
&
operator
=
(
const
GenericReader
&
);
void
ClearStack
()
{
stack_
.
Clear
();
}
// clear stack on any exit from ParseStream, e.g. due to exception
struct
ClearStackOnExit
{
explicit
ClearStackOnExit
(
GenericReader
&
r
)
:
r_
(
r
)
{}
~
ClearStackOnExit
()
{
r_
.
ClearStack
();
}
private
:
GenericReader
&
r_
;
};
// Parse object: { string : value, ... }
template
<
unsigned
parseFlags
,
typename
InputStream
,
typename
Handler
>
void
ParseObject
(
InputStream
&
is
,
Handler
&
handler
)
{
...
...
@@ -377,8 +373,7 @@ private:
RAPIDJSON_PARSE_ERROR
(
kParseErrorObjectMissName
,
is
.
Tell
());
ParseString
<
parseFlags
>
(
is
,
handler
);
if
(
HasParseError
())
return
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
SkipWhitespace
(
is
);
...
...
@@ -388,8 +383,7 @@ private:
SkipWhitespace
(
is
);
ParseValue
<
parseFlags
>
(
is
,
handler
);
if
(
HasParseError
())
return
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
SkipWhitespace
(
is
);
...
...
@@ -427,8 +421,7 @@ private:
for
(
SizeType
elementCount
=
0
;;)
{
ParseValue
<
parseFlags
>
(
is
,
handler
);
if
(
HasParseError
())
return
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
++
elementCount
;
SkipWhitespace
(
is
);
...
...
@@ -500,7 +493,7 @@ private:
codepoint
-=
'a'
-
10
;
else
{
RAPIDJSON_PARSE_ERROR_NORETURN
(
kParseErrorStringUnicodeEscapeInvalidHex
,
is
.
Tell
()
-
1
);
return
0
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN
(
0
)
;
}
}
return
codepoint
;
...
...
@@ -532,8 +525,7 @@ private:
if
(
parseFlags
&
kParseInsituFlag
)
{
typename
InputStream
::
Ch
*
head
=
s
.
PutBegin
();
ParseStringToStream
<
parseFlags
,
SourceEncoding
,
SourceEncoding
>
(
s
,
s
);
if
(
HasParseError
())
return
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
size_t
length
=
s
.
PutEnd
(
head
)
-
1
;
RAPIDJSON_ASSERT
(
length
<=
0xFFFFFFFF
);
if
(
!
handler
.
String
((
typename
TargetEncoding
::
Ch
*
)
head
,
SizeType
(
length
),
false
))
...
...
@@ -542,8 +534,7 @@ private:
else
{
StackStream
stackStream
(
stack_
);
ParseStringToStream
<
parseFlags
,
SourceEncoding
,
TargetEncoding
>
(
s
,
stackStream
);
if
(
HasParseError
())
return
;
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID
;
if
(
!
handler
.
String
(
stack_
.
template
Pop
<
typename
TargetEncoding
::
Ch
>
(
stackStream
.
length_
),
stackStream
.
length_
-
1
,
true
))
RAPIDJSON_PARSE_ERROR
(
kParseErrorTermination
,
s
.
Tell
());
}
...
...
@@ -794,8 +785,7 @@ private:
static
const
size_t
kDefaultStackCapacity
=
256
;
//!< Default stack capacity in bytes for storing a single decoded string.
internal
::
Stack
<
Allocator
>
stack_
;
//!< A stack for storing decoded string temporarily during non-destructive parsing.
ParseErrorCode
parseErrorCode_
;
size_t
errorOffset_
;
ParseResult
parseResult_
;
};
// class GenericReader
//! Reader with UTF8 encoding and default allocator.
...
...
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