1#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H
3#ifndef SIMDJSON_CONDITIONAL_INCLUDE
4#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H
5#include "simdjson/generic/ondemand/base.h"
6#include "simdjson/generic/ondemand/field.h"
7#include "simdjson/generic/ondemand/object.h"
8#include "simdjson/generic/ondemand/object_iterator.h"
9#include "simdjson/generic/ondemand/raw_json_string.h"
10#include "simdjson/generic/ondemand/json_iterator.h"
11#include "simdjson/generic/ondemand/value-inl.h"
12#include "simdjson/jsonpathutil.h"
13#if SIMDJSON_STATIC_REFLECTION
14#include "simdjson/generic/ondemand/json_string_builder.h"
20namespace SIMDJSON_IMPLEMENTATION {
25 SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) );
27 logger::log_line(iter.json_iter(),
"ERROR: ",
"Cannot find key %.*s",
"", -1, 0, logger::log_level::error,
static_cast<int>(key.size()), key.data());
30 return value(iter.child());
34 SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) );
36 logger::log_line(iter.json_iter(),
"ERROR: ",
"Cannot find key %.*s",
"", -1, 0, logger::log_level::error,
static_cast<int>(key.size()), key.data());
39 return value(iter.child());
42 return find_field_unordered(key);
44simdjson_inline simdjson_result<value> object::operator[](
const std::string_view key) &&
noexcept {
45 return std::forward<object>(*this).find_field_unordered(key);
49 SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) );
51 logger::log_line(iter.json_iter(),
"ERROR: ",
"Cannot find key %.*s",
"", -1, 0, logger::log_level::error,
static_cast<int>(key.size()), key.data());
54 return value(iter.child());
58 SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) );
60 logger::log_line(iter.json_iter(),
"ERROR: ",
"Cannot find key %.*s",
"", -1, 0, logger::log_level::error,
static_cast<int>(key.size()), key.data());
63 return value(iter.child());
67 SIMDJSON_TRY( iter.start_object().error() );
70simdjson_inline simdjson_result<object> object::start_root(value_iterator &iter)
noexcept {
71 SIMDJSON_TRY( iter.start_root_object().error() );
75 if(iter.is_at_key()) {
90 auto error = iter.field_key().get(actual_key);
91 if (error) { iter.abandon();
return error; };
93 if ((error = iter.field_value())) { iter.abandon();
return error; }
95 auto error_skip = iter.json_iter().skip_child(iter.depth()-1);
96 if(error_skip) { iter.abandon(); }
101 const uint8_t * starting_point{iter.peek_start()};
103 if(error) {
return error; }
104 const uint8_t * final_point{iter._json_iter->peek()};
105 return std::string_view(
reinterpret_cast<const char*
>(starting_point),
size_t(final_point - starting_point));
109 SIMDJSON_TRY( iter.started_object().error() );
113simdjson_inline
object object::resume(
const value_iterator &iter)
noexcept {
117simdjson_inline
object::object(
const value_iterator &_iter) noexcept
122simdjson_inline simdjson_result<object_iterator> object::begin() noexcept {
123#if SIMDJSON_DEVELOPMENT_CHECKS
126 return object_iterator(iter);
128simdjson_inline simdjson_result<object_iterator> object::end() noexcept {
129 return object_iterator(iter);
134 json_pointer = json_pointer.substr(1);
135 size_t slash = json_pointer.find(
'/');
136 std::string_view key = json_pointer.substr(0, slash);
141 size_t escape = key.find(
'~');
142 if (escape != std::string_view::npos) {
144 std::string unescaped(key);
146 switch (unescaped[escape+1]) {
148 unescaped.replace(escape, 2,
"~");
151 unescaped.replace(escape, 2,
"/");
156 escape = unescaped.find(
'~', escape+1);
157 }
while (escape != std::string::npos);
158 child = find_field(unescaped);
160 child = find_field(key);
166 if (slash != std::string_view::npos) {
167 child = child.at_pointer(json_pointer.substr(slash));
174 if (json_pointer ==
"-1") {
177 return at_pointer(json_pointer);
181 std::vector<value> result;
183 auto result_pair = get_next_key_and_json_path(json_path);
184 std::string_view key = result_pair.first;
185 std::string_view remaining_path = result_pair.second;
189 for (
auto field : *
this) {
193 if (remaining_path.empty()) {
194 result.push_back(std::move(val));
198 if (nested_result.error()) {
199 return nested_result.error();
202 std::vector<value> nested_vec;
203 SIMDJSON_TRY(std::move(nested_result).get(nested_vec));
205 result.insert(result.end(),
206 std::make_move_iterator(nested_vec.begin()),
207 std::make_move_iterator(nested_vec.end()));
213 SIMDJSON_TRY(find_field(key).get(val));
215 if (remaining_path.empty()) {
216 result.push_back(std::move(val));
227 for(simdjson_unused
auto v : *
this) { count++; }
229 if(iter.error()) {
return iter.
error(); }
238 auto error = iter.reset_object().get(is_not_empty);
239 if(error) {
return error; }
240 return !is_not_empty;
244 return iter.reset_object();
247#if SIMDJSON_SUPPORTS_CONCEPTS && SIMDJSON_STATIC_REFLECTION
249template<constevalutil::fixed_string... FieldNames,
typename T>
250 requires(std::is_class_v<T> && (
sizeof...(FieldNames) > 0))
251simdjson_warn_unused simdjson_inline
error_code object::extract_into(T& out) &
noexcept {
253 auto should_extract = [](std::string_view field_name)
constexpr ->
bool {
254 return ((FieldNames.view() == field_name) || ...);
258 template for (
constexpr auto mem : std::define_static_array(
259 std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()))) {
261 if constexpr (!std::meta::is_const(mem) && std::meta::is_public(mem)) {
262 constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
265 if constexpr (should_extract(key)) {
267 if constexpr (concepts::optional_type<
decltype(out.[:mem:])>) {
269 auto field_result = find_field_unordered(key);
270 if (!field_result.error()) {
271 auto error = field_result.get(out.[:mem:]);
276 return field_result.error();
282 SIMDJSON_TRY((*
this)[key].get(out.[:mem:]));
299simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object &&value) noexcept
300 : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object>(value)) {}
301simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::simdjson_result(error_code error) noexcept
302 : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object>(error) {}
304simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::begin() noexcept {
305 if (error()) {
return error(); }
306 return first.begin();
308simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::end() noexcept {
309 if (error()) {
return error(); }
312simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::find_field_unordered(std::string_view key) &
noexcept {
313 if (error()) {
return error(); }
314 return first.find_field_unordered(key);
316simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::find_field_unordered(std::string_view key) &&
noexcept {
317 if (error()) {
return error(); }
318 return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object>(first).find_field_unordered(key);
320simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::operator[](std::string_view key) &
noexcept {
321 if (error()) {
return error(); }
324simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::operator[](std::string_view key) &&
noexcept {
325 if (error()) {
return error(); }
326 return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object>(first)[key];
328simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::find_field(std::string_view key) &
noexcept {
329 if (error()) {
return error(); }
330 return first.find_field(key);
332simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::find_field(std::string_view key) &&
noexcept {
333 if (error()) {
return error(); }
334 return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object>(first).find_field(key);
337simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::at_pointer(std::string_view json_pointer)
noexcept {
338 if (error()) {
return error(); }
339 return first.at_pointer(json_pointer);
342simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::at_path(
343 std::string_view json_path)
noexcept {
347 return first.at_path(json_path);
350simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::at_path_with_wildcard(std::string_view json_path)
noexcept {
351 if (error()) {
return error(); }
352 return first.at_path_with_wildcard(json_path);
355inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::reset() noexcept {
356 if (error()) {
return error(); }
357 return first.reset();
360inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::is_empty() noexcept {
361 if (error()) {
return error(); }
362 return first.is_empty();
365simdjson_inline simdjson_result<size_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::count_fields() &
noexcept {
366 if (error()) {
return error(); }
367 return first.count_fields();
370simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::raw_json() noexcept {
371 if (error()) {
return error(); }
372 return first.raw_json();
A JSON field (key/value pair) in an object.
simdjson_inline ondemand::value & value() &noexcept
Get the field value.
A forward-only JSON object field iterator.
simdjson_inline object() noexcept=default
Create a new invalid object.
simdjson_inline simdjson_result< value > find_field_unordered(std::string_view key) &noexcept
Look up a field by name on an object, without regard to key order.
simdjson_inline simdjson_result< std::string_view > raw_json() noexcept
Consumes the object and returns a string_view instance corresponding to the object as represented in ...
simdjson_warn_unused simdjson_inline error_code consume() noexcept
Go to the end of the object, no matter where you are right now.
simdjson_inline simdjson_result< value > find_field(std::string_view key) &noexcept
Look up a field by name on an object (order-sensitive).
simdjson_result< std::vector< value > > at_path_with_wildcard(std::string_view json_path) noexcept
Get all values matching the given JSONPath expression with wildcard support.
simdjson_result< bool > is_empty() &noexcept
This method scans the beginning of the object and checks whether the object is empty.
simdjson_result< bool > reset() &noexcept
Reset the iterator so that we are pointing back at the beginning of the object.
simdjson_result< value > at_path(std::string_view json_path) noexcept
Get the value associated with the given JSONPath expression.
simdjson_result< value > at_pointer(std::string_view json_pointer) noexcept
Get the value associated with the given JSON pointer.
simdjson_inline simdjson_result< size_t > count_fields() &noexcept
This method scans the object and counts the number of key-value pairs.
A string escaped per JSON rules, terminated with quote (").
An ephemeral JSON value returned during iteration.
simdjson_inline simdjson_result< std::vector< value > > at_path_with_wildcard(std::string_view json_path) noexcept
Get all values matching the given JSONPath expression with wildcard support.
The top level simdjson namespace, containing everything the library provides.
error_code
All possible errors returned by simdjson.
@ OUT_OF_ORDER_ITERATION
tried to iterate an array or object out of order (checked when SIMDJSON_DEVELOPMENT_CHECKS=1)
@ NO_SUCH_FIELD
JSON field not found in object.
@ INVALID_JSON_POINTER
Invalid JSON pointer syntax.
std::string json_path_to_pointer_conversion(std::string_view json_path)
Converts JSONPath to JSON Pointer.
The result of a simdjson operation that could fail.
simdjson_inline error_code error() const noexcept
The error.