namespace simdjson { namespace SIMDJSON_IMPLEMENTATION { namespace ondemand { class document; class object; class array; class value; class raw_json_string; class parser; /** * Iterates through a single JSON value at a particular depth. * * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects * the caller to call the right ones. * * @private This is not intended for external use. */ class value_iterator { protected: /** The underlying JSON iterator */ json_iterator *_json_iter{}; /** The depth of this value */ depth_t _depth{}; /** * The starting token index for this value * * PERF NOTE: this is a safety check; we expect this to be elided in release builds. */ const uint32_t *_start_index{}; public: simdjson_really_inline value_iterator() noexcept = default; /** * Denote that we're starting a document. */ simdjson_really_inline void start_document() noexcept; /** * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. * * Optimized for scalars. */ simdjson_warn_unused simdjson_really_inline error_code skip_child() noexcept; /** * Tell whether the iterator is at the EOF mark */ simdjson_really_inline bool at_eof() const noexcept; /** * Tell whether the iterator is at the start of the value */ simdjson_really_inline bool at_start() const noexcept; /** * Tell whether the value is open--if the value has not been used, or the array/object is still open. */ simdjson_really_inline bool is_open() const noexcept; /** * Tell whether the value is at an object's first field (just after the {). */ simdjson_really_inline bool at_first_field() const noexcept; /** * Abandon all iteration. */ simdjson_really_inline void abandon() noexcept; /** * Get the child value as a value_iterator. */ simdjson_really_inline value_iterator child_value() const noexcept; /** * Get the depth of this value. */ simdjson_really_inline depth_t depth() const noexcept; /** * @addtogroup object Object iteration * * Methods to iterate and find object fields. These methods generally *assume* the value is * actually an object; the caller is responsible for keeping track of that fact. * * @{ */ /** * Start an object iteration. * * @returns Whether the object had any fields (returns false for empty). * @error INCORRECT_TYPE if there is no opening { */ simdjson_warn_unused simdjson_really_inline simdjson_result start_object() noexcept; /** * Check for an opening { and start an object iteration. * * @returns Whether the object had any fields (returns false for empty). * @error INCORRECT_TYPE if there is no opening { */ simdjson_warn_unused simdjson_really_inline simdjson_result try_start_object() noexcept; /** * Start an object iteration after the user has already checked and moved past the {. * * Does not move the iterator. * * @returns Whether the object had any fields (returns false for empty). */ simdjson_warn_unused simdjson_really_inline bool started_object() noexcept; /** * Moves to the next field in an object. * * Looks for , and }. If } is found, the object is finished and the iterator advances past it. * Otherwise, it advances to the next value. * * @return whether there is another field in the object. * @error TAPE_ERROR If there is a comma missing between fields. */ simdjson_warn_unused simdjson_really_inline simdjson_result has_next_field() noexcept; /** * Get the current field's key. */ simdjson_warn_unused simdjson_really_inline simdjson_result field_key() noexcept; /** * Pass the : in the field and move to its value. */ simdjson_warn_unused simdjson_really_inline error_code field_value() noexcept; /** * Find the next field with the given key. * * Assumes you have called next_field() or otherwise matched the previous value. * * This means the iterator must be sitting at the next key: * * ``` * { "a": 1, "b": 2 } * ^ * ``` * * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may * fail to match some keys with escapes (\u, \n, etc.). */ simdjson_warn_unused simdjson_really_inline error_code find_field(const std::string_view key) noexcept; /** * Find the next field with the given key, *without* unescaping. This assumes object order: it * will not find the field if it was already passed when looking for some *other* field. * * Assumes you have called next_field() or otherwise matched the previous value. * * This means the iterator must be sitting at the next key: * * ``` * { "a": 1, "b": 2 } * ^ * ``` * * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may * fail to match some keys with escapes (\u, \n, etc.). */ simdjson_warn_unused simdjson_really_inline simdjson_result find_field_raw(const std::string_view key) noexcept; /** * Find the field with the given key without regard to order, and *without* unescaping. * * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. * * Assumes you have called next_field() or otherwise matched the previous value. * * This means the iterator must be sitting at the next key: * * ``` * { "a": 1, "b": 2 } * ^ * ``` * * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may * fail to match some keys with escapes (\u, \n, etc.). */ simdjson_warn_unused simdjson_really_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; /** @} */ /** * @addtogroup array Array iteration * Methods to iterate over array elements. These methods generally *assume* the value is actually * an object; the caller is responsible for keeping track of that fact. * @{ */ /** * Check for an opening [ and start an array iteration. * * @param json A pointer to the potential [. * @returns Whether the array had any elements (returns false for empty). * @error INCORRECT_TYPE If there is no [. */ simdjson_warn_unused simdjson_really_inline simdjson_result start_array() noexcept; /** * Check for an opening [ and start an array iteration. * * @returns Whether the array had any elements (returns false for empty). * @error INCORRECT_TYPE If there is no [. */ simdjson_warn_unused simdjson_really_inline simdjson_result try_start_array() noexcept; /** * Start an array iteration after the user has already checked and moved past the [. * * Does not move the iterator. * * @returns Whether the array had any elements (returns false for empty). */ simdjson_warn_unused simdjson_really_inline bool started_array() noexcept; /** * Moves to the next element in an array. * * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. * Otherwise, it advances to the next value. * * @return Whether there is another element in the array. * @error TAPE_ERROR If there is a comma missing between elements. */ simdjson_warn_unused simdjson_really_inline simdjson_result has_next_element() noexcept; /** * Get a child value iterator. */ simdjson_warn_unused simdjson_really_inline value_iterator child() const noexcept; /** @} */ /** * @defgroup scalar Scalar values * @addtogroup scalar * @{ */ simdjson_warn_unused simdjson_really_inline simdjson_result try_get_string() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_string() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_raw_json_string() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_raw_json_string() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_uint64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_uint64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_int64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_int64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_double() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_double() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_bool() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_bool() noexcept; simdjson_really_inline bool require_null() noexcept; simdjson_really_inline bool is_null() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_root_uint64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_root_uint64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_root_int64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_root_int64() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_root_double() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_root_double() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result try_get_root_bool() noexcept; simdjson_warn_unused simdjson_really_inline simdjson_result require_root_bool() noexcept; simdjson_really_inline bool require_root_null() noexcept; simdjson_really_inline bool is_root_null() noexcept; simdjson_really_inline error_code error() const noexcept; simdjson_really_inline uint8_t *&string_buf_loc() noexcept; simdjson_really_inline const json_iterator &json_iter() const noexcept; simdjson_really_inline json_iterator &json_iter() noexcept; /** @} */ protected: simdjson_really_inline value_iterator(json_iterator *json_iter, depth_t depth, const uint32_t *start_index) noexcept; simdjson_really_inline bool is_null(const uint8_t *json) const noexcept; simdjson_really_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; simdjson_really_inline bool is_root_null(const uint8_t *json, uint32_t max_len) const noexcept; simdjson_really_inline simdjson_result parse_root_bool(const uint8_t *json, uint32_t max_len) const noexcept; simdjson_really_inline simdjson_result parse_root_uint64(const uint8_t *json, uint32_t max_len) const noexcept; simdjson_really_inline simdjson_result parse_root_int64(const uint8_t *json, uint32_t max_len) const noexcept; simdjson_really_inline simdjson_result parse_root_double(const uint8_t *json, uint32_t max_len) const noexcept; simdjson_really_inline void assert_at_start() const noexcept; simdjson_really_inline void assert_at_root() const noexcept; simdjson_really_inline void assert_at_child() const noexcept; simdjson_really_inline void assert_at_next() const noexcept; simdjson_really_inline void assert_at_non_root_start() const noexcept; friend class document; friend class object; friend class array; friend class value; }; // value_iterator } // namespace ondemand } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson namespace simdjson { template<> struct simdjson_result : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base { public: simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::value_iterator &&value) noexcept; ///< @private simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private simdjson_really_inline simdjson_result() noexcept = default; }; } // namespace simdjson