TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
GenericReader< SourceEncoding, TargetEncoding, StackAllocator > Class Template Reference

SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator. More...

#include <reader.h>

Classes

struct  ClearStackOnExit
 
singleton  NumberStream
 
class  NumberStream< InputStream, false >
 
class  NumberStream< InputStream, true >
 
class  StackStream
 

Public Types

typedef SourceEncoding::Ch Ch
 SourceEncoding character type. More...
 

Public Member Functions

 GenericReader (StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
 Constructor. More...
 
template<unsigned parseFlags, typename InputStream , typename Handler >
ParseResult Parse (InputStream &is, Handler &handler)
 Parse JSON text. More...
 
template<typename InputStream , typename Handler >
ParseResult Parse (InputStream &is, Handler &handler)
 Parse JSON text (with kParseDefaultFlags) More...
 
bool HasParseError () const
 Whether a parse error has occured in the last parsing. More...
 
ParseErrorCode GetParseErrorCode () const
 Get the ParseErrorCode of last parsing. More...
 
size_t GetErrorOffset () const
 Get the position of last parsing error in input, 0 otherwise. More...
 

Protected Member Functions

void SetParseError (ParseErrorCode code, size_t offset)
 

Private Types

enum  IterativeParsingState {
  IterativeParsingStartState = 0, IterativeParsingFinishState, IterativeParsingErrorState, IterativeParsingObjectInitialState,
  IterativeParsingMemberKeyState, IterativeParsingKeyValueDelimiterState, IterativeParsingMemberValueState, IterativeParsingMemberDelimiterState,
  IterativeParsingObjectFinishState, IterativeParsingArrayInitialState, IterativeParsingElementState, IterativeParsingElementDelimiterState,
  IterativeParsingArrayFinishState, IterativeParsingValueState, cIterativeParsingStateCount
}
 
enum  Token {
  LeftBracketToken = 0, RightBracketToken, LeftCurlyBracketToken, RightCurlyBracketToken,
  CommaToken, ColonToken, StringToken, FalseToken,
  TrueToken, NullToken, NumberToken, kTokenCount
}
 

Private Member Functions

 GenericReader (const GenericReader &)
 
GenericReaderoperator= (const GenericReader &)
 
void ClearStack ()
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseObject (InputStream &is, Handler &handler)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseArray (InputStream &is, Handler &handler)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseNull (InputStream &is, Handler &handler)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseTrue (InputStream &is, Handler &handler)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseFalse (InputStream &is, Handler &handler)
 
template<typename InputStream >
unsigned ParseHex4 (InputStream &is)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseString (InputStream &is, Handler &handler, bool isKey=false)
 
template<unsigned parseFlags, typename SEncoding , typename TEncoding , typename InputStream , typename OutputStream >
RAPIDJSON_FORCEINLINE void ParseStringToStream (InputStream &is, OutputStream &os)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseNumber (InputStream &is, Handler &handler)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
void ParseValue (InputStream &is, Handler &handler)
 
RAPIDJSON_FORCEINLINE Token Tokenize (Ch c)
 
RAPIDJSON_FORCEINLINE
IterativeParsingState 
Predict (IterativeParsingState state, Token token)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
RAPIDJSON_FORCEINLINE
IterativeParsingState 
Transit (IterativeParsingState src, Token token, IterativeParsingState dst, InputStream &is, Handler &handler)
 
template<typename InputStream >
void HandleError (IterativeParsingState src, InputStream &is)
 
template<unsigned parseFlags, typename InputStream , typename Handler >
ParseResult IterativeParse (InputStream &is, Handler &handler)
 

Private Attributes

internal::Stack< StackAllocator > stack_
 A stack for storing decoded string temporarily during non-destructive parsing. More...
 
ParseResult parseResult_
 

Static Private Attributes

static const size_t kDefaultStackCapacity = 256
 Default stack capacity in bytes for storing a single decoded string. More...
 

Detailed Description

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
class GenericReader< SourceEncoding, TargetEncoding, StackAllocator >

SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.

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 non-destructive parsing.

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.

Template Parameters
SourceEncodingEncoding of the input stream.
TargetEncodingEncoding of the parse output.
StackAllocatorAllocator type for stack.

Member Typedef Documentation

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
typedef SourceEncoding::Ch GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Ch

SourceEncoding character type.

Member Enumeration Documentation

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
enum GenericReader::IterativeParsingState
private
Enumerator
IterativeParsingStartState 
IterativeParsingFinishState 
IterativeParsingErrorState 
IterativeParsingObjectInitialState 
IterativeParsingMemberKeyState 
IterativeParsingKeyValueDelimiterState 
IterativeParsingMemberValueState 
IterativeParsingMemberDelimiterState 
IterativeParsingObjectFinishState 
IterativeParsingArrayInitialState 
IterativeParsingElementState 
IterativeParsingElementDelimiterState 
IterativeParsingArrayFinishState 
IterativeParsingValueState 
cIterativeParsingStateCount 
1002  {
1006 
1007  // Object states
1014 
1015  // Array states
1020 
1021  // Single value state
1023 
1025  };
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
enum GenericReader::Token
private
Enumerator
LeftBracketToken 
RightBracketToken 
LeftCurlyBracketToken 
RightCurlyBracketToken 
CommaToken 
ColonToken 
StringToken 
FalseToken 
TrueToken 
NullToken 
NumberToken 
kTokenCount 
1028  {
1029  LeftBracketToken = 0,
1031 
1034 
1035  CommaToken,
1036  ColonToken,
1037 
1038  StringToken,
1039  FalseToken,
1040  TrueToken,
1041  NullToken,
1042  NumberToken,
1043 
1044  kTokenCount
1045  };
Definition: reader.h:1036
Definition: reader.h:1033
Definition: reader.h:1032
Definition: reader.h:1029
Definition: reader.h:1044
Definition: reader.h:1035
Definition: reader.h:1042
Definition: reader.h:1040
Definition: reader.h:1038
Definition: reader.h:1039
Definition: reader.h:1030
Definition: reader.h:1041

Constructor & Destructor Documentation

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::GenericReader ( StackAllocator *  stackAllocator = 0,
size_t  stackCapacity = kDefaultStackCapacity 
)
inline

Constructor.

Parameters
stackAllocatorOptional allocator for allocating stack memory. (Only use for non-destructive parsing)
stackCapacitystack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
382 : stack_(stackAllocator, stackCapacity), parseResult_() {}
ParseResult parseResult_
Definition: reader.h:1436
internal::Stack< StackAllocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:1435
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::GenericReader ( const GenericReader< SourceEncoding, TargetEncoding, StackAllocator > &  )
private

Member Function Documentation

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ClearStack ( )
inlineprivate
453 { stack_.Clear(); }
void Clear()
Definition: stack.h:84
internal::Stack< StackAllocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:1435

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
size_t GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::GetErrorOffset ( ) const
inline

Get the position of last parsing error in input, 0 otherwise.

443 { return parseResult_.Offset(); }
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:111
ParseResult parseResult_
Definition: reader.h:1436
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
ParseErrorCode GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::GetParseErrorCode ( ) const
inline

Get the ParseErrorCode of last parsing.

440 { return parseResult_.Code(); }
ParseResult parseResult_
Definition: reader.h:1436
ParseErrorCode Code() const
Get the error code.
Definition: error.h:109
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<typename InputStream >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::HandleError ( IterativeParsingState  src,
InputStream &  is 
)
inlineprivate
1383  {
1384  if (HasParseError()) {
1385  // Error flag has been set.
1386  return;
1387  }
1388 
1389  switch (src) {
1398  }
1399  }
Missing a comma or '}' after an object member.
Definition: error.h:69
The document is empty.
Definition: error.h:62
Missing a comma or ']' after an array element.
Definition: error.h:71
Missing a name for object member.
Definition: error.h:67
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:437
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
Unspecific syntax error.
Definition: error.h:84
Missing a colon after a name of object member.
Definition: error.h:68
The document root must not follow by other values.
Definition: error.h:63

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
bool GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::HasParseError ( ) const
inline

Whether a parse error has occured in the last parsing.

437 { return parseResult_.IsError(); }
ParseResult parseResult_
Definition: reader.h:1436
bool IsError() const
Whether the result is an error.
Definition: error.h:116

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
ParseResult GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::IterativeParse ( InputStream &  is,
Handler &  handler 
)
inlineprivate
1402  {
1403  parseResult_.Clear();
1404  ClearStackOnExit scope(*this);
1406 
1407  SkipWhitespace(is);
1408  while (is.Peek() != '\0') {
1409  Token t = Tokenize(is.Peek());
1410  IterativeParsingState n = Predict(state, t);
1411  IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1412 
1413  if (d == IterativeParsingErrorState) {
1414  HandleError(state, is);
1415  break;
1416  }
1417 
1418  state = d;
1419 
1420  // Do not further consume streams if a root JSON has been parsed.
1421  if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1422  break;
1423 
1424  SkipWhitespace(is);
1425  }
1426 
1427  // Handle the end of file.
1428  if (state != IterativeParsingFinishState)
1429  HandleError(state, is);
1430 
1431  return parseResult_;
1432  }
void HandleError(IterativeParsingState src, InputStream &is)
Definition: reader.h:1383
ParseResult parseResult_
Definition: reader.h:1436
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token)
Definition: reader.h:1074
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c)
Definition: reader.h:1047
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:141
IterativeParsingState
Definition: reader.h:1002
Token
Definition: reader.h:1028
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:247
void Clear()
Reset error code.
Definition: error.h:123
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
GenericReader& GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::operator= ( const GenericReader< SourceEncoding, TargetEncoding, StackAllocator > &  )
private
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
ParseResult GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Parse ( InputStream &  is,
Handler &  handler 
)
inline

Parse JSON text.

Template Parameters
parseFlagsCombination of ParseFlag.
InputStreamType of input stream, implementing Stream concept.
HandlerType of handler, implementing Handler concept.
Parameters
isInput stream to be parsed.
handlerThe handler to receive events.
Returns
Whether the parsing is successful.
393  {
394  if (parseFlags & kParseIterativeFlag)
395  return IterativeParse<parseFlags>(is, handler);
396 
398 
399  ClearStackOnExit scope(*this);
400 
401  SkipWhitespace(is);
402 
403  if (is.Peek() == '\0') {
405  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
406  }
407  else {
408  ParseValue<parseFlags>(is, handler);
409  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
410 
411  if (!(parseFlags & kParseStopWhenDoneFlag)) {
412  SkipWhitespace(is);
413 
414  if (is.Peek() != '\0') {
416  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
417  }
418  }
419  }
420 
421  return parseResult_;
422  }
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:140
ParseResult parseResult_
Definition: reader.h:1436
The document is empty.
Definition: error.h:62
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:90
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:141
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:247
void Clear()
Reset error code.
Definition: error.h:123
The document root must not follow by other values.
Definition: error.h:63
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<typename InputStream , typename Handler >
ParseResult GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Parse ( InputStream &  is,
Handler &  handler 
)
inline

Parse JSON text (with kParseDefaultFlags)

Template Parameters
InputStreamType of input stream, implementing Stream concept
HandlerType of handler, implementing Handler concept.
Parameters
isInput stream to be parsed.
handlerThe handler to receive events.
Returns
Whether the parsing is successful.
432  {
433  return Parse<kParseDefaultFlags>(is, handler);
434  }
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseArray ( InputStream &  is,
Handler &  handler 
)
inlineprivate
517  {
518  RAPIDJSON_ASSERT(is.Peek() == '[');
519  is.Take(); // Skip '['
520 
521  if (!handler.StartArray())
523 
524  SkipWhitespace(is);
525 
526  if (is.Peek() == ']') {
527  is.Take();
528  if (!handler.EndArray(0)) // empty array
530  return;
531  }
532 
533  for (SizeType elementCount = 0;;) {
534  ParseValue<parseFlags>(is, handler);
535  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
536 
537  ++elementCount;
538  SkipWhitespace(is);
539 
540  switch (is.Take()) {
541  case ',': SkipWhitespace(is); break;
542  case ']':
543  if (!handler.EndArray(elementCount))
545  return;
547  }
548  }
549  }
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
Missing a comma or ']' after an array element.
Definition: error.h:71
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:247
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseFalse ( InputStream &  is,
Handler &  handler 
)
inlineprivate
578  {
579  RAPIDJSON_ASSERT(is.Peek() == 'f');
580  is.Take();
581 
582  if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') {
583  if (!handler.Bool(false))
585  }
586  else
588  }
Invalid value.
Definition: error.h:65
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<typename InputStream >
unsigned GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseHex4 ( InputStream &  is)
inlineprivate
592  {
593  unsigned codepoint = 0;
594  for (int i = 0; i < 4; i++) {
595  Ch c = is.Take();
596  codepoint <<= 4;
597  codepoint += static_cast<unsigned>(c);
598  if (c >= '0' && c <= '9')
599  codepoint -= '0';
600  else if (c >= 'A' && c <= 'F')
601  codepoint -= 'A' - 10;
602  else if (c >= 'a' && c <= 'f')
603  codepoint -= 'a' - 10;
604  else {
606  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
607  }
608  }
609  return codepoint;
610  }
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:90
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:376
Incorrect hex digit after \u escape in string.
Definition: error.h:73

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseNull ( InputStream &  is,
Handler &  handler 
)
inlineprivate
552  {
553  RAPIDJSON_ASSERT(is.Peek() == 'n');
554  is.Take();
555 
556  if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') {
557  if (!handler.Null())
559  }
560  else
562  }
Invalid value.
Definition: error.h:65
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseNumber ( InputStream &  is,
Handler &  handler 
)
inlineprivate
772  {
774  NumberStream<InputStream, (parseFlags & kParseFullPrecisionFlag) != 0> s(*this, copy.s);
775 
776  // Parse minus
777  bool minus = false;
778  if (s.Peek() == '-') {
779  minus = true;
780  s.Take();
781  }
782 
783  // Parse int: zero / ( digit1-9 *DIGIT )
784  unsigned i = 0;
785  uint64_t i64 = 0;
786  bool use64bit = false;
787  int significandDigit = 0;
788  if (s.Peek() == '0') {
789  i = 0;
790  s.TakePush();
791  }
792  else if (s.Peek() >= '1' && s.Peek() <= '9') {
793  i = static_cast<unsigned>(s.TakePush() - '0');
794 
795  if (minus)
796  while (s.Peek() >= '0' && s.Peek() <= '9') {
797  if (i >= 214748364) { // 2^31 = 2147483648
798  if (i != 214748364 || s.Peek() > '8') {
799  i64 = i;
800  use64bit = true;
801  break;
802  }
803  }
804  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
805  significandDigit++;
806  }
807  else
808  while (s.Peek() >= '0' && s.Peek() <= '9') {
809  if (i >= 429496729) { // 2^32 - 1 = 4294967295
810  if (i != 429496729 || s.Peek() > '5') {
811  i64 = i;
812  use64bit = true;
813  break;
814  }
815  }
816  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
817  significandDigit++;
818  }
819  }
820  else
822 
823  // Parse 64bit int
824  bool useDouble = false;
825  double d = 0.0;
826  if (use64bit) {
827  if (minus)
828  while (s.Peek() >= '0' && s.Peek() <= '9') {
829  if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808
830  if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') {
831  d = i64;
832  useDouble = true;
833  break;
834  }
835  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
836  significandDigit++;
837  }
838  else
839  while (s.Peek() >= '0' && s.Peek() <= '9') {
840  if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615
841  if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') {
842  d = i64;
843  useDouble = true;
844  break;
845  }
846  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
847  significandDigit++;
848  }
849  }
850 
851  // Force double for big integer
852  if (useDouble) {
853  while (s.Peek() >= '0' && s.Peek() <= '9') {
854  if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0
856  d = d * 10 + (s.TakePush() - '0');
857  }
858  }
859 
860  // Parse frac = decimal-point 1*DIGIT
861  int expFrac = 0;
862  size_t decimalPosition;
863  if (s.Peek() == '.') {
864  s.Take();
865  decimalPosition = s.Length();
866 
867  if (!(s.Peek() >= '0' && s.Peek() <= '9'))
869 
870  if (!useDouble) {
871 #if RAPIDJSON_64BIT
872  // Use i64 to store significand in 64-bit architecture
873  if (!use64bit)
874  i64 = i;
875 
876  while (s.Peek() >= '0' && s.Peek() <= '9') {
877  if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
878  break;
879  else {
880  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
881  --expFrac;
882  if (i64 != 0)
883  significandDigit++;
884  }
885  }
886 
887  d = (double)i64;
888 #else
889  // Use double to store significand in 32-bit architecture
890  d = use64bit ? (double)i64 : (double)i;
891 #endif
892  useDouble = true;
893  }
894 
895  while (s.Peek() >= '0' && s.Peek() <= '9') {
896  if (significandDigit < 17) {
897  d = d * 10.0 + (s.TakePush() - '0');
898  --expFrac;
899  if (d > 0.0)
900  significandDigit++;
901  }
902  else
903  s.TakePush();
904  }
905  }
906  else
907  decimalPosition = s.Length(); // decimal position at the end of integer.
908 
909  // Parse exp = e [ minus / plus ] 1*DIGIT
910  int exp = 0;
911  if (s.Peek() == 'e' || s.Peek() == 'E') {
912  if (!useDouble) {
913  d = use64bit ? i64 : i;
914  useDouble = true;
915  }
916  s.Take();
917 
918  bool expMinus = false;
919  if (s.Peek() == '+')
920  s.Take();
921  else if (s.Peek() == '-') {
922  s.Take();
923  expMinus = true;
924  }
925 
926  if (s.Peek() >= '0' && s.Peek() <= '9') {
927  exp = s.Take() - '0';
928  if (expMinus) {
929  while (s.Peek() >= '0' && s.Peek() <= '9') {
930  exp = exp * 10 + (s.Take() - '0');
931  if (exp >= 214748364) { // Issue #313: prevent overflow exponent
932  while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent
933  s.Take();
934  }
935  }
936  }
937  else { // positive exp
938  int maxExp = 308 - expFrac;
939  while (s.Peek() >= '0' && s.Peek() <= '9') {
940  exp = exp * 10 + (s.Take() - '0');
941  if (exp > maxExp)
943  }
944  }
945  }
946  else
948 
949  if (expMinus)
950  exp = -exp;
951  }
952 
953  // Finish parsing, call event according to the type of number.
954  bool cont = true;
955  size_t length = s.Length();
956  const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
957 
958  if (useDouble) {
959  int p = exp + expFrac;
960  if (parseFlags & kParseFullPrecisionFlag)
961  d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
962  else
964 
965  cont = handler.Double(minus ? -d : d);
966  }
967  else {
968  if (use64bit) {
969  if (minus)
970  cont = handler.Int64(-(int64_t)i64);
971  else
972  cont = handler.Uint64(i64);
973  }
974  else {
975  if (minus)
976  cont = handler.Int(-(int)i);
977  else
978  cont = handler.Uint(i);
979  }
980  }
981  if (!cont)
983  }
Quat exp(const Quat &q)
Definition: Quat.h:729
Invalid value.
Definition: error.h:65
double StrtodFullPrecision(double d, int p, const char *decimals, size_t length, size_t decimalPosition, int exp)
Definition: strtod.h:225
Parsing was terminated.
Definition: error.h:83
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:261
signed __int64 int64_t
Definition: stdint.h:89
Number too big to be stored in double.
Definition: error.h:79
Parse number in full precision (but slower).
Definition: reader.h:142
double StrtodNormalPrecision(double d, int p)
Definition: strtod.h:36
unsigned __int64 uint64_t
Definition: stdint.h:90
Miss exponent in number.
Definition: error.h:81
float length(float v)
Definition: vectorMath.h:208
Miss fraction part in number.
Definition: error.h:80
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
Definition: reader.h:208
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseObject ( InputStream &  is,
Handler &  handler 
)
inlineprivate
467  {
468  RAPIDJSON_ASSERT(is.Peek() == '{');
469  is.Take(); // Skip '{'
470 
471  if (!handler.StartObject())
473 
474  SkipWhitespace(is);
475 
476  if (is.Peek() == '}') {
477  is.Take();
478  if (!handler.EndObject(0)) // empty object
480  return;
481  }
482 
483  for (SizeType memberCount = 0;;) {
484  if (is.Peek() != '"')
486 
487  ParseString<parseFlags>(is, handler, true);
488  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
489 
490  SkipWhitespace(is);
491 
492  if (is.Take() != ':')
494 
495  SkipWhitespace(is);
496 
497  ParseValue<parseFlags>(is, handler);
498  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
499 
500  SkipWhitespace(is);
501 
502  ++memberCount;
503 
504  switch (is.Take()) {
505  case ',': SkipWhitespace(is); break;
506  case '}':
507  if (!handler.EndObject(memberCount))
509  return;
511  }
512  }
513  }
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
Missing a comma or '}' after an object member.
Definition: error.h:69
Missing a name for object member.
Definition: error.h:67
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:247
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
Missing a colon after a name of object member.
Definition: error.h:68
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseString ( InputStream &  is,
Handler &  handler,
bool  isKey = false 
)
inlineprivate
637  {
639  InputStream& s(copy.s);
640 
641  bool success = false;
642  if (parseFlags & kParseInsituFlag) {
643  typename InputStream::Ch *head = s.PutBegin();
644  ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
645  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
646  size_t length = s.PutEnd(head) - 1;
647  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
648  const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head;
649  success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
650  }
651  else {
652  StackStream<typename TargetEncoding::Ch> stackStream(stack_);
653  ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
654  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
655  SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
656  const typename TargetEncoding::Ch* const str = stackStream.Pop();
657  success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
658  }
659  if (!success)
661  }
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
float length(float v)
Definition: vectorMath.h:208
internal::Stack< StackAllocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:1435
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
Definition: reader.h:208
In-situ(destructive) parsing.
Definition: reader.h:138
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename SEncoding , typename TEncoding , typename InputStream , typename OutputStream >
RAPIDJSON_FORCEINLINE void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseStringToStream ( InputStream &  is,
OutputStream &  os 
)
inlineprivate
666  {
668 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
669  static const char escape[256] = {
670  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
671  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
672  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
673  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
674  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
675  };
676 #undef Z16
677 
679  RAPIDJSON_ASSERT(is.Peek() == '\"');
680  is.Take(); // Skip '\"'
681 
682  for (;;) {
683  Ch c = is.Peek();
684  if (c == '\\') { // Escape
685  is.Take();
686  Ch e = is.Take();
687  if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) {
688  os.Put(escape[(unsigned char)e]);
689  }
690  else if (e == 'u') { // Unicode
691  unsigned codepoint = ParseHex4(is);
692  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
693  if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
694  // Handle UTF-16 surrogate pair
695  if (is.Take() != '\\' || is.Take() != 'u')
697  unsigned codepoint2 = ParseHex4(is);
698  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
699  if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
701  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
702  }
703  TEncoding::Encode(os, codepoint);
704  }
705  else
707  }
708  else if (c == '"') { // Closing double quote
709  is.Take();
710  os.Put('\0'); // null-terminate the string
711  return;
712  }
713  else if (c == '\0')
715  else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
717  else {
718  if (parseFlags & kParseValidateEncodingFlag ?
722  }
723  }
724  }
Encoding conversion.
Definition: encodings.h:586
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:376
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the outp...
Definition: encodings.h:589
Invalid escape character in string.
Definition: error.h:75
Invalid encoding in string.
Definition: error.h:77
unsigned ParseHex4(InputStream &is)
Definition: reader.h:592
#define Z16
static std::string escape(const std::string &string)
Definition: TextOutput.cpp:77
Validate encoding of JSON strings.
Definition: reader.h:139
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
The surrogate pair in string is invalid.
Definition: error.h:74
Missing a closing quotation mark in string.
Definition: error.h:76
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseTrue ( InputStream &  is,
Handler &  handler 
)
inlineprivate
565  {
566  RAPIDJSON_ASSERT(is.Peek() == 't');
567  is.Take();
568 
569  if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') {
570  if (!handler.Bool(true))
572  }
573  else
575  }
Invalid value.
Definition: error.h:65
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:109
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::ParseValue ( InputStream &  is,
Handler &  handler 
)
inlineprivate
987  {
988  switch (is.Peek()) {
989  case 'n': ParseNull <parseFlags>(is, handler); break;
990  case 't': ParseTrue <parseFlags>(is, handler); break;
991  case 'f': ParseFalse <parseFlags>(is, handler); break;
992  case '"': ParseString<parseFlags>(is, handler); break;
993  case '{': ParseObject<parseFlags>(is, handler); break;
994  case '[': ParseArray <parseFlags>(is, handler); break;
995  default : ParseNumber<parseFlags>(is, handler);
996  }
997  }
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
RAPIDJSON_FORCEINLINE IterativeParsingState GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Predict ( IterativeParsingState  state,
Token  token 
)
inlineprivate
1074  {
1075  // current state x one lookahead token -> new state
1076  static const char G[cIterativeParsingStateCount][kTokenCount] = {
1077  // Start
1078  {
1079  IterativeParsingArrayInitialState, // Left bracket
1080  IterativeParsingErrorState, // Right bracket
1081  IterativeParsingObjectInitialState, // Left curly bracket
1082  IterativeParsingErrorState, // Right curly bracket
1083  IterativeParsingErrorState, // Comma
1084  IterativeParsingErrorState, // Colon
1085  IterativeParsingValueState, // String
1086  IterativeParsingValueState, // False
1089  IterativeParsingValueState // Number
1090  },
1091  // Finish(sink state)
1092  {
1095  IterativeParsingErrorState
1096  },
1097  // Error(sink state)
1098  {
1101  IterativeParsingErrorState
1102  },
1103  // ObjectInitial
1104  {
1105  IterativeParsingErrorState, // Left bracket
1106  IterativeParsingErrorState, // Right bracket
1107  IterativeParsingErrorState, // Left curly bracket
1108  IterativeParsingObjectFinishState, // Right curly bracket
1109  IterativeParsingErrorState, // Comma
1110  IterativeParsingErrorState, // Colon
1112  IterativeParsingErrorState, // False
1115  IterativeParsingErrorState // Number
1116  },
1117  // MemberKey
1118  {
1119  IterativeParsingErrorState, // Left bracket
1120  IterativeParsingErrorState, // Right bracket
1121  IterativeParsingErrorState, // Left curly bracket
1122  IterativeParsingErrorState, // Right curly bracket
1123  IterativeParsingErrorState, // Comma
1125  IterativeParsingErrorState, // String
1126  IterativeParsingErrorState, // False
1129  IterativeParsingErrorState // Number
1130  },
1131  // KeyValueDelimiter
1132  {
1133  IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1134  IterativeParsingErrorState, // Right bracket
1135  IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1136  IterativeParsingErrorState, // Right curly bracket
1137  IterativeParsingErrorState, // Comma
1138  IterativeParsingErrorState, // Colon
1143  IterativeParsingMemberValueState // Number
1144  },
1145  // MemberValue
1146  {
1147  IterativeParsingErrorState, // Left bracket
1148  IterativeParsingErrorState, // Right bracket
1149  IterativeParsingErrorState, // Left curly bracket
1150  IterativeParsingObjectFinishState, // Right curly bracket
1152  IterativeParsingErrorState, // Colon
1153  IterativeParsingErrorState, // String
1154  IterativeParsingErrorState, // False
1157  IterativeParsingErrorState // Number
1158  },
1159  // MemberDelimiter
1160  {
1161  IterativeParsingErrorState, // Left bracket
1162  IterativeParsingErrorState, // Right bracket
1163  IterativeParsingErrorState, // Left curly bracket
1164  IterativeParsingErrorState, // Right curly bracket
1165  IterativeParsingErrorState, // Comma
1166  IterativeParsingErrorState, // Colon
1168  IterativeParsingErrorState, // False
1171  IterativeParsingErrorState // Number
1172  },
1173  // ObjectFinish(sink state)
1174  {
1177  IterativeParsingErrorState
1178  },
1179  // ArrayInitial
1180  {
1181  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1182  IterativeParsingArrayFinishState, // Right bracket
1183  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1184  IterativeParsingErrorState, // Right curly bracket
1185  IterativeParsingErrorState, // Comma
1186  IterativeParsingErrorState, // Colon
1187  IterativeParsingElementState, // String
1191  IterativeParsingElementState // Number
1192  },
1193  // Element
1194  {
1195  IterativeParsingErrorState, // Left bracket
1196  IterativeParsingArrayFinishState, // Right bracket
1197  IterativeParsingErrorState, // Left curly bracket
1198  IterativeParsingErrorState, // Right curly bracket
1200  IterativeParsingErrorState, // Colon
1201  IterativeParsingErrorState, // String
1202  IterativeParsingErrorState, // False
1205  IterativeParsingErrorState // Number
1206  },
1207  // ElementDelimiter
1208  {
1209  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1210  IterativeParsingErrorState, // Right bracket
1211  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1212  IterativeParsingErrorState, // Right curly bracket
1213  IterativeParsingErrorState, // Comma
1214  IterativeParsingErrorState, // Colon
1215  IterativeParsingElementState, // String
1219  IterativeParsingElementState // Number
1220  },
1221  // ArrayFinish(sink state)
1222  {
1225  IterativeParsingErrorState
1226  },
1227  // Single Value (sink state)
1228  {
1231  IterativeParsingErrorState
1232  }
1233  }; // End of G
1234 
1235  return (IterativeParsingState)G[state][token];
1236  }
Definition: reader.h:1044
IterativeParsingState
Definition: reader.h:1002
#define G(x, y, z)

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
void GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::SetParseError ( ParseErrorCode  code,
size_t  offset 
)
inlineprotected
446 { parseResult_.Set(code, offset); }
ParseResult parseResult_
Definition: reader.h:1436
void Set(ParseErrorCode code, size_t offset=0)
Update error code and offset.
Definition: error.h:125
Definition: inftrees.h:24
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
RAPIDJSON_FORCEINLINE Token GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Tokenize ( Ch  c)
inlineprivate
1047  {
1048 
1050 #define N NumberToken
1051 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1052  // Maps from ASCII to Token
1053  static const unsigned char tokenMap[256] = {
1054  N16, // 00~0F
1055  N16, // 10~1F
1056  N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1057  N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1058  N16, // 40~4F
1059  N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1060  N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1061  N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1062  N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1063  };
1064 #undef N
1065 #undef N16
1066 
1068  if (sizeof(Ch) == 1 || unsigned(c) < 256)
1069  return (Token)tokenMap[(unsigned char)c];
1070  else
1071  return NumberToken;
1072  }
Definition: reader.h:1036
Definition: reader.h:1033
Definition: reader.h:1032
Definition: reader.h:1029
Definition: reader.h:1035
Definition: reader.h:1042
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:376
Definition: reader.h:1040
Definition: reader.h:1038
Token
Definition: reader.h:1028
Definition: reader.h:1039
Definition: reader.h:1030
Definition: reader.h:1041

+ Here is the caller graph for this function:

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
template<unsigned parseFlags, typename InputStream , typename Handler >
RAPIDJSON_FORCEINLINE IterativeParsingState GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::Transit ( IterativeParsingState  src,
Token  token,
IterativeParsingState  dst,
InputStream &  is,
Handler &  handler 
)
inlineprivate
1241  {
1242  (void)token;
1243 
1244  switch (dst) {
1246  return dst;
1247 
1250  {
1251  // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1252  // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1253  IterativeParsingState n = src;
1258  // Push current state.
1259  *stack_.template Push<SizeType>(1) = n;
1260  // Initialize and push the member/element count.
1261  *stack_.template Push<SizeType>(1) = 0;
1262  // Call handler
1263  bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1264  // On handler short circuits the parsing.
1265  if (!hr) {
1268  }
1269  else {
1270  is.Take();
1271  return dst;
1272  }
1273  }
1274 
1276  ParseString<parseFlags>(is, handler, true);
1277  if (HasParseError())
1279  else
1280  return dst;
1281 
1283  RAPIDJSON_ASSERT(token == ColonToken);
1284  is.Take();
1285  return dst;
1286 
1288  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1289  ParseValue<parseFlags>(is, handler);
1290  if (HasParseError()) {
1292  }
1293  return dst;
1294 
1296  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1297  ParseValue<parseFlags>(is, handler);
1298  if (HasParseError()) {
1300  }
1301  return dst;
1302 
1305  is.Take();
1306  // Update member/element count.
1307  *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1308  return dst;
1309 
1311  {
1312  // Get member count.
1313  SizeType c = *stack_.template Pop<SizeType>(1);
1314  // If the object is not empty, count the last member.
1316  ++c;
1317  // Restore the state.
1318  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1319  // Transit to Finish state if this is the topmost scope.
1320  if (n == IterativeParsingStartState)
1322  // Call handler
1323  bool hr = handler.EndObject(c);
1324  // On handler short circuits the parsing.
1325  if (!hr) {
1328  }
1329  else {
1330  is.Take();
1331  return n;
1332  }
1333  }
1334 
1336  {
1337  // Get element count.
1338  SizeType c = *stack_.template Pop<SizeType>(1);
1339  // If the array is not empty, count the last element.
1340  if (src == IterativeParsingElementState)
1341  ++c;
1342  // Restore the state.
1343  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1344  // Transit to Finish state if this is the topmost scope.
1345  if (n == IterativeParsingStartState)
1347  // Call handler
1348  bool hr = handler.EndArray(c);
1349  // On handler short circuits the parsing.
1350  if (!hr) {
1353  }
1354  else {
1355  is.Take();
1356  return n;
1357  }
1358  }
1359 
1360  default:
1361  // This branch is for IterativeParsingValueState actually.
1362  // Use `default:` rather than
1363  // `case IterativeParsingValueState:` is for code coverage.
1364 
1365  // The IterativeParsingStartState is not enumerated in this switch-case.
1366  // It is impossible for that case. And it can be caught by following assertion.
1367 
1368  // The IterativeParsingFinishState is not enumerated in this switch-case either.
1369  // It is a "derivative" state which cannot triggered from Predict() directly.
1370  // Therefore it cannot happen here. And it can be caught by following assertion.
1372 
1373  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1374  ParseValue<parseFlags>(is, handler);
1375  if (HasParseError()) {
1377  }
1379  }
1380  }
Definition: reader.h:1036
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Parsing was terminated.
Definition: error.h:83
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:90
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:437
IterativeParsingState
Definition: reader.h:1002
internal::Stack< StackAllocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:1435

Member Data Documentation

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
const size_t GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::kDefaultStackCapacity = 256
staticprivate

Default stack capacity in bytes for storing a single decoded string.

template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
ParseResult GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::parseResult_
private
template<typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
internal::Stack<StackAllocator> GenericReader< SourceEncoding, TargetEncoding, StackAllocator >::stack_
private

A stack for storing decoded string temporarily during non-destructive parsing.


The documentation for this class was generated from the following file: