simdjson  3.11.0
Ridiculously Fast JSON
raw_json_string-inl.h
1 #ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H
2 
3 #ifndef SIMDJSON_CONDITIONAL_INCLUDE
4 #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H
5 #include "simdjson/generic/ondemand/base.h"
6 #include "simdjson/generic/ondemand/raw_json_string.h"
7 #include "simdjson/generic/ondemand/json_iterator-inl.h"
8 #include "simdjson/generic/implementation_simdjson_result_base-inl.h"
9 #endif // SIMDJSON_CONDITIONAL_INCLUDE
10 
11 namespace simdjson {
12 
13 namespace SIMDJSON_IMPLEMENTATION {
14 namespace ondemand {
15 
16 simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {}
17 
18 simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast<const char *>(buf); }
19 
20 
21 simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept {
22  size_t pos{0};
23  // if the content has no escape character, just scan through it quickly!
24  for(;pos < target.size() && target[pos] != '\\';pos++) {}
25  // slow path may begin.
26  bool escaping{false};
27  for(;pos < target.size();pos++) {
28  if((target[pos] == '"') && !escaping) {
29  return false;
30  } else if(target[pos] == '\\') {
31  escaping = !escaping;
32  } else {
33  escaping = false;
34  }
35  }
36  return true;
37 }
38 
39 simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept {
40  size_t pos{0};
41  // if the content has no escape character, just scan through it quickly!
42  for(;target[pos] && target[pos] != '\\';pos++) {}
43  // slow path may begin.
44  bool escaping{false};
45  for(;target[pos];pos++) {
46  if((target[pos] == '"') && !escaping) {
47  return false;
48  } else if(target[pos] == '\\') {
49  escaping = !escaping;
50  } else {
51  escaping = false;
52  }
53  }
54  return true;
55 }
56 
57 
58 simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept {
59  // If we are going to call memcmp, then we must know something about the length of the raw_json_string.
60  return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size());
61 }
62 
63 simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept {
64  // Assumptions: does not contain unescaped quote characters, and
65  // the raw content is quote terminated within a valid JSON string.
66  if(target.size() <= SIMDJSON_PADDING) {
67  return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size());
68  }
69  const char * r{raw()};
70  size_t pos{0};
71  for(;pos < target.size();pos++) {
72  if(r[pos] != target[pos]) { return false; }
73  }
74  if(r[pos] != '"') { return false; }
75  return true;
76 }
77 
78 simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept {
79  const char * r{raw()};
80  size_t pos{0};
81  bool escaping{false};
82  for(;pos < target.size();pos++) {
83  if(r[pos] != target[pos]) { return false; }
84  // if target is a compile-time constant and it is free from
85  // quotes, then the next part could get optimized away through
86  // inlining.
87  if((target[pos] == '"') && !escaping) {
88  // We have reached the end of the raw_json_string but
89  // the target is not done.
90  return false;
91  } else if(target[pos] == '\\') {
92  escaping = !escaping;
93  } else {
94  escaping = false;
95  }
96  }
97  if(r[pos] != '"') { return false; }
98  return true;
99 }
100 
101 
102 simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept {
103  // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and
104  // the raw content is quote terminated within a valid JSON string.
105  const char * r{raw()};
106  size_t pos{0};
107  for(;target[pos];pos++) {
108  if(r[pos] != target[pos]) { return false; }
109  }
110  if(r[pos] != '"') { return false; }
111  return true;
112 }
113 
114 simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept {
115  // Assumptions: does not contain unescaped quote characters, and
116  // the raw content is quote terminated within a valid JSON string.
117  const char * r{raw()};
118  size_t pos{0};
119  bool escaping{false};
120  for(;target[pos];pos++) {
121  if(r[pos] != target[pos]) { return false; }
122  // if target is a compile-time constant and it is free from
123  // quotes, then the next part could get optimized away through
124  // inlining.
125  if((target[pos] == '"') && !escaping) {
126  // We have reached the end of the raw_json_string but
127  // the target is not done.
128  return false;
129  } else if(target[pos] == '\\') {
130  escaping = !escaping;
131  } else {
132  escaping = false;
133  }
134  }
135  if(r[pos] != '"') { return false; }
136  return true;
137 }
138 
139 simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept {
140  return a.unsafe_is_equal(c);
141 }
142 
143 simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept {
144  return a == c;
145 }
146 
147 simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept {
148  return !(a == c);
149 }
150 
151 simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept {
152  return !(a == c);
153 }
154 
155 
156 simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept {
157  return iter.unescape(*this, allow_replacement);
158 }
159 
160 simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept {
161  return iter.unescape_wobbly(*this);
162 }
163 
164 simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept {
165  bool in_escape = false;
166  const char *s = str.raw();
167  while (true) {
168  switch (*s) {
169  case '\\': in_escape = !in_escape; break;
170  case '"': if (in_escape) { in_escape = false; } else { return out; } break;
171  default: if (in_escape) { in_escape = false; }
172  }
173  out << *s;
174  s++;
175  }
176 }
177 
178 } // namespace ondemand
179 } // namespace SIMDJSON_IMPLEMENTATION
180 } // namespace simdjson
181 
182 namespace simdjson {
183 
184 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>::simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string &&value) noexcept
185  : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>(value)) {}
186 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>::simdjson_result(error_code error) noexcept
187  : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>(error) {}
188 
189 simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>::raw() const noexcept {
190  if (error()) { return error(); }
191  return first.raw();
192 }
193 simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>::unescape(SIMDJSON_IMPLEMENTATION::ondemand::json_iterator &iter, bool allow_replacement) const noexcept {
194  if (error()) { return error(); }
195  return first.unescape(iter, allow_replacement);
196 }
197 simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string>::unescape_wobbly(SIMDJSON_IMPLEMENTATION::ondemand::json_iterator &iter) const noexcept {
198  if (error()) { return error(); }
199  return first.unescape_wobbly(iter);
200 }
201 } // namespace simdjson
202 
203 #endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H
A string escaped per JSON rules, terminated with quote (").
simdjson_inline bool is_equal(std::string_view target) const noexcept
This compares the current instance to the std::string_view target: returns true if they are byte-by-b...
static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept
Returns true if target is free from unescaped quote.
simdjson_inline raw_json_string() noexcept=default
Create a new invalid raw_json_string.
simdjson_inline const char * raw() const noexcept
Get the raw pointer to the beginning of the string in the JSON (just after the ").
simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept
This compares the current instance to the std::string_view target: returns true if they are byte-by-b...
simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept
Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user i...
std::ostream & operator<<(std::ostream &out, json_type type) noexcept
Write the JSON type to the output stream.
Definition: json_type-inl.h:14
The top level simdjson namespace, containing everything the library provides.
Definition: base.h:8
error_code
All possible errors returned by simdjson.
Definition: error.h:19
constexpr size_t SIMDJSON_PADDING
The amount of padding needed in a buffer to parse JSON.
Definition: base.h:32
simdjson_inline error_code error() const noexcept
The error.
Definition: error-inl.h:131