3 namespace SIMDJSON_IMPLEMENTATION {
7 static constexpr
const char * DASHES =
"----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
8 static constexpr
const int LOG_EVENT_LEN = 20;
9 static constexpr
const int LOG_BUFFER_LEN = 30;
10 static constexpr
const int LOG_SMALL_BUFFER_LEN = 10;
11 static int log_depth = 0;
14 static inline char printable_char(
char c) {
22 static inline log_level get_log_level_from_env()
24 SIMDJSON_PUSH_DISABLE_WARNINGS
25 SIMDJSON_DISABLE_DEPRECATED_WARNING
26 char *lvl = getenv(
"SIMDJSON_LOG_LEVEL");
27 SIMDJSON_POP_DISABLE_WARNINGS
28 if (lvl && simdjson_strcasecmp(lvl,
"ERROR") == 0) {
return log_level::LOG_ERROR; }
29 return log_level::LOG_INFO;
32 static inline log_level log_threshold()
34 static log_level threshold = get_log_level_from_env();
38 static inline bool should_log(log_level level)
40 return level >= log_threshold();
43 template<
typename... Args>
44 inline std::string string_format(
const std::string& format,
const Args&... args)
46 int size_s = std::snprintf(
nullptr, 0, format.c_str(), args...) + 1;
47 auto size =
static_cast<size_t>(size_s);
48 if (size <= 0)
return std::string();
49 std::unique_ptr<char[]> buf(
new char[size]);
50 std::snprintf(buf.get(), size, format.c_str(), args...);
51 return std::string(buf.get(), buf.get() + size - 1);
54 inline void log_event(
const json_iterator &iter,
const char *type, std::string_view detail,
int delta,
int depth_delta) noexcept {
55 log_line(iter,
"", type, detail, delta, depth_delta, log_level::LOG_INFO);
58 inline void log_value(
const json_iterator &iter, token_position index,
depth_t depth,
const char *type, std::string_view detail) noexcept {
59 log_line(iter, index, depth,
"", type, detail, log_level::LOG_INFO);
61 inline void log_value(
const json_iterator &iter,
const char *type, std::string_view detail,
int delta,
int depth_delta) noexcept {
62 log_line(iter,
"", type, detail, delta, depth_delta, log_level::LOG_INFO);
65 inline void log_start_value(
const json_iterator &iter, token_position index,
depth_t depth,
const char *type, std::string_view detail) noexcept {
66 log_line(iter, index, depth,
"+", type, detail, log_level::LOG_INFO);
67 if (LOG_ENABLED) { log_depth++; }
69 inline void log_start_value(
const json_iterator &iter,
const char *type,
int delta,
int depth_delta) noexcept {
70 log_line(iter,
"+", type,
"", delta, depth_delta, log_level::LOG_INFO);
71 if (LOG_ENABLED) { log_depth++; }
74 inline void log_end_value(
const json_iterator &iter,
const char *type,
int delta,
int depth_delta) noexcept {
75 if (LOG_ENABLED) { log_depth--; }
76 log_line(iter,
"-", type,
"", delta, depth_delta, log_level::LOG_INFO);
79 inline void log_error(
const json_iterator &iter,
const char *error,
const char *detail,
int delta,
int depth_delta) noexcept {
80 log_line(iter,
"ERROR: ", error, detail, delta, depth_delta, log_level::LOG_ERROR);
82 inline void log_error(
const json_iterator &iter, token_position index,
depth_t depth,
const char *error,
const char *detail) noexcept {
83 log_line(iter, index, depth,
"ERROR: ", error, detail, log_level::LOG_ERROR);
86 inline void log_event(
const value_iterator &iter,
const char *type, std::string_view detail,
int delta,
int depth_delta) noexcept {
87 log_event(iter.json_iter(), type, detail, delta, depth_delta);
90 inline void log_value(
const value_iterator &iter,
const char *type, std::string_view detail,
int delta,
int depth_delta) noexcept {
91 log_value(iter.json_iter(), type, detail, delta, depth_delta);
94 inline void log_start_value(
const value_iterator &iter,
const char *type,
int delta,
int depth_delta) noexcept {
95 log_start_value(iter.json_iter(), type, delta, depth_delta);
98 inline void log_end_value(
const value_iterator &iter,
const char *type,
int delta,
int depth_delta) noexcept {
99 log_end_value(iter.json_iter(), type, delta, depth_delta);
102 inline void log_error(
const value_iterator &iter,
const char *error,
const char *detail,
int delta,
int depth_delta) noexcept {
103 log_error(iter.json_iter(), error, detail, delta, depth_delta);
106 inline void log_headers() noexcept {
107 if (LOG_ENABLED && simdjson_unlikely(should_log(log_level::LOG_INFO))) {
110 static bool displayed_hint{
false};
113 if(!displayed_hint) {
115 printf(
"# Logging provides the depth and position of the iterator user-visible steps:\n");
116 printf(
"# +array says 'this is where we were when we discovered the start array'\n");
117 printf(
"# -array says 'this is where we were when we ended the array'\n");
118 printf(
"# skip says 'this is a structural or value I am skipping'\n");
119 printf(
"# +/-skip says 'this is a start/end array or object I am skipping'\n");
121 printf(
"# The indentation of the terms (array, string,...) indicates the depth,\n");
122 printf(
"# in addition to the depth being displayed.\n");
124 printf(
"# Every token in the document has a single depth determined by the tokens before it,\n");
125 printf(
"# and is not affected by what the token actually is.\n");
127 printf(
"# Not all structural elements are presented as tokens in the logs.\n");
129 printf(
"# We never give control to the user within an empty array or an empty object.\n");
131 printf(
"# Inside an array, having a depth greater than the array's depth means that\n");
132 printf(
"# we are pointing inside a value.\n");
133 printf(
"# Having a depth equal to the array means that we are pointing right before a value.\n");
134 printf(
"# Having a depth smaller than the array means that we have moved beyond the array.\n");
135 displayed_hint =
true;
138 printf(
"| %-*s ", LOG_EVENT_LEN,
"Event");
139 printf(
"| %-*s ", LOG_BUFFER_LEN,
"Buffer");
140 printf(
"| %-*s ", LOG_SMALL_BUFFER_LEN,
"Next");
142 printf(
"| %-*s ", 5,
"Depth");
146 printf(
"|%.*s", LOG_EVENT_LEN+2, DASHES);
147 printf(
"|%.*s", LOG_BUFFER_LEN+2, DASHES);
148 printf(
"|%.*s", LOG_SMALL_BUFFER_LEN+2, DASHES);
150 printf(
"|%.*s", 5+2, DASHES);
157 inline void log_line(
const json_iterator &iter,
const char *title_prefix,
const char *title, std::string_view detail,
int delta,
int depth_delta, log_level level) noexcept {
158 log_line(iter, iter.position()+delta,
depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level);
160 inline void log_line(
const json_iterator &iter, token_position index,
depth_t depth,
const char *title_prefix,
const char *title, std::string_view detail, log_level level) noexcept {
161 if (LOG_ENABLED && simdjson_unlikely(should_log(level))) {
162 const int indent = depth*2;
163 const auto buf = iter.token.buf;
164 printf(
"| %*s%s%-*s ",
167 LOG_EVENT_LEN - indent -
int(strlen(title_prefix)), title
174 if(index < iter._root) {
175 printf(
"%*s", LOG_BUFFER_LEN,
"");
177 auto current_structural = &buf[*index];
178 for (
int i=0;i<LOG_BUFFER_LEN;i++) {
179 printf(
"%c", printable_char(current_structural[i]));
187 auto next_structural = &buf[*(index+1)];
188 for (
int i=0;i<LOG_SMALL_BUFFER_LEN;i++) {
189 printf(
"%c", printable_char(next_structural[i]));
194 printf(
"| %5i ", depth);
195 printf(
"| %6.*s ",
int(detail.size()) , detail.data());
int32_t depth_t
Represents the depth of a JSON value (number of nested arrays/objects).
We want to support argument-dependent lookup (ADL).