1#ifndef SIMDJSON_INTERNAL_JSON_STRUCTURE_ANALYZER_H
2#define SIMDJSON_INTERNAL_JSON_STRUCTURE_ANALYZER_H
4#include "simdjson/dom/base.h"
5#include "simdjson/dom/element.h"
6#include "simdjson/dom/array.h"
7#include "simdjson/dom/object.h"
8#include "simdjson/dom/fractured_json.h"
9#include "simdjson/internal/tape_type.h"
22enum class layout_mode {
30enum class table_column_type {
45 table_column_type type = table_column_type::unknown;
49 size_t plain_width = 0;
51 std::vector<table_column> children{};
56inline bool table_row_is_nested(
const std::vector<table_column>& columns) {
57 for (
const table_column& col : columns) {
58 if (col.type == table_column_type::object || col.type == table_column_type::array) {
69struct element_metrics {
71 size_t complexity = 0;
74 size_t estimated_inline_len = 0;
77 size_t child_count = 0;
80 bool can_inline =
false;
83 bool is_uniform_array =
false;
86 std::vector<table_column> table_columns{};
88 size_t table_row_width = 0;
90 size_t table_row_width_full = 0;
93 std::vector<element_metrics> children{};
96 table_column_type scalar_column_type = table_column_type::unknown;
100inline const element_metrics& child_metrics_at(
const std::vector<element_metrics>& children,
size_t idx) {
101 static const element_metrics empty{};
102 return idx < children.size() ? children[idx] : empty;
106inline const element_metrics& child_metrics_at(
const element_metrics* ptr) {
107 static const element_metrics empty{};
108 return ptr ? *ptr : empty;
122class structure_analyzer {
125 structure_analyzer() : current_opts_(nullptr) {}
128 structure_analyzer(
const structure_analyzer&) =
delete;
131 structure_analyzer& operator=(
const structure_analyzer&) =
delete;
134 structure_analyzer(structure_analyzer&&) =
default;
137 structure_analyzer& operator=(structure_analyzer&&) =
default;
145 element_metrics analyze(
const dom::element& elem,
146 const fractured_json_options& opts);
159 element_metrics analyze_array(
const dom::array& arr,
160 const fractured_json_options& opts);
168 element_metrics analyze_object(
const dom::object& obj,
169 const fractured_json_options& opts);
173 static layout_mode decide_layout(
const element_metrics& metrics,
175 const fractured_json_options& opts,
176 bool has_trailing_comma =
false);
179 const fractured_json_options* current_opts_ =
nullptr;
182 element_metrics analyze_element(
const dom::element& elem,
size_t depth)
const;
185 element_metrics analyze_scalar(
const dom::element& elem)
const;
188 element_metrics analyze_array(
const dom::array& arr,
size_t depth)
const;
191 element_metrics analyze_object(
const dom::object& obj,
size_t depth)
const;
194 size_t estimate_string_length(std::string_view s)
const;
197 size_t estimate_number_length(
double d)
const;
198 size_t estimate_number_length(int64_t i)
const;
199 size_t estimate_number_length(uint64_t u)
const;
208 bool check_array_uniformity(
const dom::array& arr, element_metrics& metrics,
size_t depth)
const;
213 static void classify_and_measure(
const std::vector<std::pair<dom::element, const element_metrics*>>& values,
214 table_column_type& common,
size_t& max_width);
217 void build_table_columns(
const std::vector<std::pair<dom::element, const element_metrics*>>& values,
218 std::vector<table_column>& out_columns)
const;
221 size_t compute_columns_width(
const std::vector<table_column>& columns)
const;
224 static size_t column_height(
const table_column& column);
227 static bool flatten_deepest_columns(std::vector<table_column>& columns);
230 void recompute_column_widths(std::vector<table_column>& columns)
const;
@ object
A JSON object ( { "a": 1, "b" 2, ... } )
@ number
A JSON number ( 1 or -2.3 or 4.5e6 ...)
@ array
A JSON array ( [ 1, 2, 3 ... ] )
element_type
The actual concrete type of a JSON element This is the type it is most easily cast to with get<>.
The top level simdjson namespace, containing everything the library provides.