1namespace simdjson {
2
3namespace SIMDJSON_IMPLEMENTATION {
4namespace ondemand {
5
6simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {}
7
8simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast<const char *>(buf); }
9
10
11simdjson_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
29simdjson_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
48simdjson_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(s1: raw(), s2: target.data(), n: target.size());
51}
52
53simdjson_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(s1: raw(), s2: target.data(), n: 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
68simdjson_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
92simdjson_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
104simdjson_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
129simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept {
130 return a.unsafe_is_equal(target: c);
131}
132
133simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept {
134 return a == c;
135}
136
137simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept {
138 return !(a == c);
139}
140
141simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept {
142 return !(a == c);
143}
144
145
146simdjson_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(in: *this, allow_replacement);
148}
149
150simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept {
151 return iter.unescape_wobbly(in: *this);
152}
153
154simdjson_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
172namespace simdjson {
173
174simdjson_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>(t&: value)) {}
176simdjson_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
179simdjson_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}
183simdjson_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}
187simdjson_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
192