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