⚡ started working on parser with provded result reference #418
Internally, the parser now writes its result into a JSON value provided as a reference. To be usable, the public interfaces need to be extended.
This commit is contained in:
		
							parent
							
								
									f513c46749
								
							
						
					
					
						commit
						c7a69ae03e
					
				
					 2 changed files with 527 additions and 494 deletions
				
			
		
							
								
								
									
										100
									
								
								src/json.hpp
									
										
									
									
									
								
							
							
						
						
									
										100
									
								
								src/json.hpp
									
										
									
									
									
								
							|  | @ -3107,19 +3107,19 @@ class parser | |||
|     /*!
 | ||||
|     @brief public parser interface | ||||
| 
 | ||||
|     @param[in] strict  whether to expect the last token to be EOF | ||||
|     @return parsed JSON value | ||||
|     @param[in] strict      whether to expect the last token to be EOF | ||||
|     @param[in,out] result  parsed JSON value | ||||
| 
 | ||||
|     @throw parse_error.101 in case of an unexpected token | ||||
|     @throw parse_error.102 if to_unicode fails or surrogate error | ||||
|     @throw parse_error.103 if to_unicode fails | ||||
|     */ | ||||
|     BasicJsonType parse(const bool strict = true) | ||||
|     void parse(const bool strict, BasicJsonType& result) | ||||
|     { | ||||
|         // read first token
 | ||||
|         get_token(); | ||||
| 
 | ||||
|         BasicJsonType result = parse_internal(true); | ||||
|         parse_internal(true, result); | ||||
|         result.assert_invariant(); | ||||
| 
 | ||||
|         if (strict) | ||||
|  | @ -3128,9 +3128,12 @@ class parser | |||
|             expect(token_type::end_of_input); | ||||
|         } | ||||
| 
 | ||||
|         // return parser result and replace it with null in case the
 | ||||
|         // top-level value was discarded by the callback function
 | ||||
|         return result.is_discarded() ? BasicJsonType() : std::move(result); | ||||
|         // set top-level value to null if it was discarded by the callback
 | ||||
|         // function
 | ||||
|         if (result.is_discarded()) | ||||
|         { | ||||
|             result = nullptr; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|  | @ -3164,17 +3167,19 @@ class parser | |||
|     @throw parse_error.102 if to_unicode fails or surrogate error | ||||
|     @throw parse_error.103 if to_unicode fails | ||||
|     */ | ||||
|     BasicJsonType parse_internal(bool keep) | ||||
|     void parse_internal(bool keep, BasicJsonType& result) | ||||
|     { | ||||
|         auto result = BasicJsonType(value_t::discarded); | ||||
|         // start with a discarded value
 | ||||
|         if (not result.is_discarded()) | ||||
|         { | ||||
|             result.m_type = value_t::discarded; | ||||
|         } | ||||
| 
 | ||||
|         switch (last_token) | ||||
|         { | ||||
|             case token_type::begin_object: | ||||
|             { | ||||
|                 if (keep and (not callback or | ||||
|                               ((keep = callback(depth++, parse_event_t::object_start, | ||||
|                                                 result)) != 0))) | ||||
|                 if (keep and (not callback or ((keep = callback(depth++, parse_event_t::object_start, result))))) | ||||
|                 { | ||||
|                     // explicitly set result to object to cope with {}
 | ||||
|                     result.m_type = value_t::object; | ||||
|  | @ -3187,15 +3192,15 @@ class parser | |||
|                 // closing } -> we are done
 | ||||
|                 if (last_token == token_type::end_object) | ||||
|                 { | ||||
|                     if (keep and callback and | ||||
|                             not callback(--depth, parse_event_t::object_end, result)) | ||||
|                     if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) | ||||
|                     { | ||||
|                         result = BasicJsonType(value_t::discarded); | ||||
|                         result.m_type = value_t::discarded; | ||||
|                     } | ||||
|                     return result; | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 // parse values
 | ||||
|                 BasicJsonType value; | ||||
|                 while (true) | ||||
|                 { | ||||
|                     // store key
 | ||||
|  | @ -3222,7 +3227,8 @@ class parser | |||
| 
 | ||||
|                     // parse and add value
 | ||||
|                     get_token(); | ||||
|                     auto value = parse_internal(keep); | ||||
|                     value = value_t::discarded; | ||||
|                     parse_internal(keep, value); | ||||
|                     if (keep and keep_tag and not value.is_discarded()) | ||||
|                     { | ||||
|                         result[key] = std::move(value); | ||||
|  | @ -3241,20 +3247,16 @@ class parser | |||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 if (keep and callback and | ||||
|                         not callback(--depth, parse_event_t::object_end, result)) | ||||
|                 if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) | ||||
|                 { | ||||
|                     result = BasicJsonType(value_t::discarded); | ||||
|                     result.m_type = value_t::discarded; | ||||
|                 } | ||||
| 
 | ||||
|                 return result; | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case token_type::begin_array: | ||||
|             { | ||||
|                 if (keep and (not callback or | ||||
|                               ((keep = callback(depth++, parse_event_t::array_start, | ||||
|                                                 result)) != 0))) | ||||
|                 if (keep and (not callback or ((keep = callback(depth++, parse_event_t::array_start, result))))) | ||||
|                 { | ||||
|                     // explicitly set result to object to cope with []
 | ||||
|                     result.m_type = value_t::array; | ||||
|  | @ -3267,19 +3269,19 @@ class parser | |||
|                 // closing ] -> we are done
 | ||||
|                 if (last_token == token_type::end_array) | ||||
|                 { | ||||
|                     if (callback and | ||||
|                             not callback(--depth, parse_event_t::array_end, result)) | ||||
|                     if (callback and not callback(--depth, parse_event_t::array_end, result)) | ||||
|                     { | ||||
|                         result = BasicJsonType(value_t::discarded); | ||||
|                         result.m_type = value_t::discarded; | ||||
|                     } | ||||
|                     return result; | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 // parse values
 | ||||
|                 BasicJsonType value; | ||||
|                 while (true) | ||||
|                 { | ||||
|                     // parse value
 | ||||
|                     auto value = parse_internal(keep); | ||||
|                     parse_internal(keep, value); | ||||
|                     if (keep and not value.is_discarded()) | ||||
|                     { | ||||
|                         result.push_back(std::move(value)); | ||||
|  | @ -3298,13 +3300,11 @@ class parser | |||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 if (keep and callback and | ||||
|                         not callback(--depth, parse_event_t::array_end, result)) | ||||
|                 if (keep and callback and not callback(--depth, parse_event_t::array_end, result)) | ||||
|                 { | ||||
|                     result = BasicJsonType(value_t::discarded); | ||||
|                     result.m_type = value_t::discarded; | ||||
|                 } | ||||
| 
 | ||||
|                 return result; | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case token_type::literal_null: | ||||
|  | @ -3315,7 +3315,8 @@ class parser | |||
| 
 | ||||
|             case token_type::value_string: | ||||
|             { | ||||
|                 result = BasicJsonType(m_lexer.get_string()); | ||||
|                 result.m_type = value_t::string; | ||||
|                 result.m_value = m_lexer.get_string(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|  | @ -3359,7 +3360,6 @@ class parser | |||
|                                                     m_lexer.get_token_string() + | ||||
|                                                     "'")); | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|  | @ -3378,12 +3378,10 @@ class parser | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (keep and callback and | ||||
|                 not callback(depth, parse_event_t::value, result)) | ||||
|         if (keep and callback and not callback(depth, parse_event_t::value, result)) | ||||
|         { | ||||
|             result = BasicJsonType(value_t::discarded); | ||||
|             result.m_type = value_t::discarded; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|  | @ -12892,7 +12890,9 @@ class basic_json | |||
|     static basic_json parse(const CharT s, | ||||
|                             const parser_callback_t cb = nullptr) | ||||
|     { | ||||
|         return parser(detail::input_adapter_factory::create(s), cb).parse(true); | ||||
|         basic_json result; | ||||
|         parser(detail::input_adapter_factory::create(s), cb).parse(true, result); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     template<typename CharT, typename std::enable_if< | ||||
|  | @ -12935,7 +12935,9 @@ class basic_json | |||
|     static basic_json parse(std::istream& i, | ||||
|                             const parser_callback_t cb = nullptr) | ||||
|     { | ||||
|         return parser(detail::input_adapter_factory::create(i), cb).parse(true); | ||||
|         basic_json result; | ||||
|         parser(detail::input_adapter_factory::create(i), cb).parse(true, result); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     static bool accept(std::istream& i) | ||||
|  | @ -12949,7 +12951,9 @@ class basic_json | |||
|     static basic_json parse(std::istream&& i, | ||||
|                             const parser_callback_t cb = nullptr) | ||||
|     { | ||||
|         return parser(detail::input_adapter_factory::create(i), cb).parse(true); | ||||
|         basic_json result; | ||||
|         parser(detail::input_adapter_factory::create(i), cb).parse(true, result); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     static bool accept(std::istream&& i) | ||||
|  | @ -13009,7 +13013,9 @@ class basic_json | |||
|     static basic_json parse(IteratorType first, IteratorType last, | ||||
|                             const parser_callback_t cb = nullptr) | ||||
|     { | ||||
|         return parser(detail::input_adapter_factory::create(first, last), cb).parse(true); | ||||
|         basic_json result; | ||||
|         parser(detail::input_adapter_factory::create(first, last), cb).parse(true, result); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     template<class IteratorType, typename std::enable_if< | ||||
|  | @ -13100,7 +13106,7 @@ class basic_json | |||
|     JSON_DEPRECATED | ||||
|     friend std::istream& operator<<(basic_json& j, std::istream& i) | ||||
|     { | ||||
|         j = parser(detail::input_adapter_factory::create(i)).parse(false); | ||||
|         parser(detail::input_adapter_factory::create(i)).parse(false, j); | ||||
|         return i; | ||||
|     } | ||||
| 
 | ||||
|  | @ -13131,7 +13137,7 @@ class basic_json | |||
|     */ | ||||
|     friend std::istream& operator>>(std::istream& i, basic_json& j) | ||||
|     { | ||||
|         j = parser(detail::input_adapter_factory::create(i)).parse(false); | ||||
|         parser(detail::input_adapter_factory::create(i)).parse(false, j); | ||||
|         return i; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue