@@ -513,6 +513,68 @@ class GenericReader {
513
513
return Parse<kParseDefaultFlags >(is, handler);
514
514
}
515
515
516
+ // ! Initialize JSON text token-by-token parsing
517
+ /* !
518
+ */
519
+ void IterativeParseInit () {
520
+ parseResult_.Clear ();
521
+ state_ = IterativeParsingStartState;
522
+ }
523
+
524
+ // ! Parse one token from JSON text
525
+ /* ! \tparam InputStream Type of input stream, implementing Stream concept
526
+ \tparam Handler Type of handler, implementing Handler concept.
527
+ \param is Input stream to be parsed.
528
+ \param handler The handler to receive events.
529
+ \return Whether the parsing is successful.
530
+ */
531
+ template <unsigned parseFlags, typename InputStream, typename Handler>
532
+ ParseResult IterativeParseNext (InputStream& is, Handler& handler) {
533
+ while (is.Peek () != ' \0 ' ) {
534
+ RAPIDJSON_PARSE_ERROR_EARLY_RETURN (parseResult_);
535
+ SkipWhitespaceAndComments<parseFlags>(is);
536
+
537
+ Token t = Tokenize (is.Peek ());
538
+ IterativeParsingState n = Predict (state_, t);
539
+ IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
540
+
541
+ if (d == IterativeParsingErrorState) {
542
+ HandleError (state_, is);
543
+ return parseResult_;
544
+ }
545
+
546
+ state_ = d;
547
+
548
+ // Do not further consume streams if a root JSON has been parsed.
549
+ if (state_ == IterativeParsingFinishState) {
550
+ // If StopWhenDone is not set, and stray data is found post-root, flag an error.
551
+ if (!(parseFlags & kParseStopWhenDoneFlag )) {
552
+ SkipWhitespaceAndComments<parseFlags>(is);
553
+ if (is.Peek () != ' \0 ' )
554
+ HandleError (state_, is);
555
+ }
556
+ return parseResult_;
557
+ }
558
+
559
+ if (!IsIterativeParsingDelimiterState (n))
560
+ return parseResult_;
561
+ }
562
+
563
+ // Handle the end of file.
564
+ if (state_ != IterativeParsingFinishState)
565
+ HandleError (state_, is);
566
+
567
+ stack_.Clear ();
568
+ return parseResult_;
569
+ }
570
+
571
+ // ! Check if token-by-token parsing JSON text is complete
572
+ /* ! \return Whether the JSON has been fully decoded.
573
+ */
574
+ bool IterativeParseComplete () {
575
+ return IsIterativeParsingCompleteState (state_);
576
+ }
577
+
516
578
// ! Whether a parse error has occured in the last parsing.
517
579
bool HasParseError () const { return parseResult_.IsError (); }
518
580
@@ -1803,44 +1865,37 @@ class GenericReader {
1803
1865
}
1804
1866
}
1805
1867
1868
+ RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState (IterativeParsingState s) {
1869
+ const unsigned int delimiterStateMask =
1870
+ (1 << IterativeParsingKeyValueDelimiterState) |
1871
+ (1 << IterativeParsingMemberDelimiterState) |
1872
+ (1 << IterativeParsingElementDelimiterState);
1873
+
1874
+ return (1 << s) & delimiterStateMask;
1875
+ }
1876
+
1877
+ RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState (IterativeParsingState s) {
1878
+ const unsigned int completeStateMask =
1879
+ (1 << IterativeParsingFinishState) |
1880
+ (1 << IterativeParsingErrorState);
1881
+
1882
+ return (1 << s) & completeStateMask;
1883
+ }
1884
+
1806
1885
template <unsigned parseFlags, typename InputStream, typename Handler>
1807
1886
ParseResult IterativeParse (InputStream& is, Handler& handler) {
1808
- parseResult_.Clear ();
1809
- ClearStackOnExit scope (*this );
1810
- IterativeParsingState state = IterativeParsingStartState;
1811
-
1812
- SkipWhitespaceAndComments<parseFlags>(is);
1813
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN (parseResult_);
1814
- while (is.Peek () != ' \0 ' ) {
1815
- Token t = Tokenize (is.Peek ());
1816
- IterativeParsingState n = Predict (state, t);
1817
- IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1818
-
1819
- if (d == IterativeParsingErrorState) {
1820
- HandleError (state, is);
1887
+ IterativeParseInit ();
1888
+ while (!IterativeParseComplete ()) {
1889
+ if (!IterativeParseNext<parseFlags>(is, handler))
1821
1890
break ;
1822
- }
1823
-
1824
- state = d;
1825
-
1826
- // Do not further consume streams if a root JSON has been parsed.
1827
- if ((parseFlags & kParseStopWhenDoneFlag ) && state == IterativeParsingFinishState)
1828
- break ;
1829
-
1830
- SkipWhitespaceAndComments<parseFlags>(is);
1831
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN (parseResult_);
1832
1891
}
1833
-
1834
- // Handle the end of file.
1835
- if (state != IterativeParsingFinishState)
1836
- HandleError (state, is);
1837
-
1838
1892
return parseResult_;
1839
1893
}
1840
1894
1841
1895
static const size_t kDefaultStackCapacity = 256 ; // !< Default stack capacity in bytes for storing a single decoded string.
1842
1896
internal::Stack<StackAllocator> stack_; // !< A stack for storing decoded string temporarily during non-destructive parsing.
1843
1897
ParseResult parseResult_;
1898
+ IterativeParsingState state_;
1844
1899
}; // class GenericReader
1845
1900
1846
1901
// ! Reader with UTF8 encoding and default allocator.
0 commit comments