/src/boost/boost/json/impl/serializer.ipp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) |
3 | | // |
4 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | | // |
7 | | // Official repository: https://github.com/boostorg/json |
8 | | // |
9 | | |
10 | | #ifndef BOOST_JSON_IMPL_SERIALIZER_IPP |
11 | | #define BOOST_JSON_IMPL_SERIALIZER_IPP |
12 | | |
13 | | #include <boost/json/serializer.hpp> |
14 | | #include <boost/json/detail/format.hpp> |
15 | | #include <boost/json/detail/sse2.hpp> |
16 | | #include <ostream> |
17 | | |
18 | | #ifdef _MSC_VER |
19 | | #pragma warning(push) |
20 | | #pragma warning(disable: 4127) // conditional expression is constant |
21 | | #endif |
22 | | |
23 | | namespace boost { |
24 | | namespace json { |
25 | | |
26 | | enum class serializer::state : char |
27 | | { |
28 | | nul1, nul2, nul3, nul4, |
29 | | tru1, tru2, tru3, tru4, |
30 | | fal1, fal2, fal3, fal4, fal5, |
31 | | str1, str2, str3, str4, esc1, |
32 | | utf1, utf2, utf3, utf4, utf5, |
33 | | num, |
34 | | arr1, arr2, arr3, arr4, |
35 | | obj1, obj2, obj3, obj4, obj5, obj6 |
36 | | }; |
37 | | |
38 | | //---------------------------------------------------------- |
39 | | |
40 | | serializer:: |
41 | 4.55k | ~serializer() noexcept = default; |
42 | | |
43 | | serializer:: |
44 | | serializer( |
45 | | storage_ptr sp, |
46 | | unsigned char* buf, |
47 | | std::size_t buf_size, |
48 | | serialize_options const& opts) noexcept |
49 | | : st_( |
50 | | std::move(sp), |
51 | | buf, |
52 | | buf_size) |
53 | | , opts_(opts) |
54 | 4.55k | { |
55 | 4.55k | } |
56 | | |
57 | | bool |
58 | | serializer:: |
59 | | suspend(state st) |
60 | 2.16k | { |
61 | 2.16k | st_.push(st); |
62 | 2.16k | return false; |
63 | 2.16k | } |
64 | | |
65 | | bool |
66 | | serializer:: |
67 | | suspend( |
68 | | state st, |
69 | | array::const_iterator it, |
70 | | array const* pa) |
71 | 5.91k | { |
72 | 5.91k | st_.push(pa); |
73 | 5.91k | st_.push(it); |
74 | 5.91k | st_.push(st); |
75 | 5.91k | return false; |
76 | 5.91k | } |
77 | | |
78 | | bool |
79 | | serializer:: |
80 | | suspend( |
81 | | state st, |
82 | | object::const_iterator it, |
83 | | object const* po) |
84 | 2.60k | { |
85 | 2.60k | st_.push(po); |
86 | 2.60k | st_.push(it); |
87 | 2.60k | st_.push(st); |
88 | 2.60k | return false; |
89 | 2.60k | } |
90 | | |
91 | | template<bool StackEmpty> |
92 | | bool |
93 | | serializer:: |
94 | | write_null(stream& ss0) |
95 | 136 | { |
96 | 136 | local_stream ss(ss0); |
97 | 136 | if(! StackEmpty && ! st_.empty()) |
98 | 68 | { |
99 | 68 | state st; |
100 | 68 | st_.pop(st); |
101 | 68 | switch(st) |
102 | 68 | { |
103 | 0 | default: |
104 | 12 | case state::nul1: goto do_nul1; |
105 | 17 | case state::nul2: goto do_nul2; |
106 | 18 | case state::nul3: goto do_nul3; |
107 | 21 | case state::nul4: goto do_nul4; |
108 | 68 | } |
109 | 68 | } |
110 | 80 | do_nul1: |
111 | 80 | if(BOOST_JSON_LIKELY(ss)) |
112 | 68 | ss.append('n'); |
113 | 12 | else |
114 | 12 | return suspend(state::nul1); |
115 | 85 | do_nul2: |
116 | 85 | if(BOOST_JSON_LIKELY(ss)) |
117 | 68 | ss.append('u'); |
118 | 17 | else |
119 | 17 | return suspend(state::nul2); |
120 | 86 | do_nul3: |
121 | 86 | if(BOOST_JSON_LIKELY(ss)) |
122 | 68 | ss.append('l'); |
123 | 18 | else |
124 | 18 | return suspend(state::nul3); |
125 | 89 | do_nul4: |
126 | 89 | if(BOOST_JSON_LIKELY(ss)) |
127 | 68 | ss.append('l'); |
128 | 21 | else |
129 | 21 | return suspend(state::nul4); |
130 | 68 | return true; |
131 | 89 | } bool boost::json::serializer::write_null<true>(boost::json::detail::stream&) Line | Count | Source | 95 | 68 | { | 96 | 68 | local_stream ss(ss0); | 97 | 68 | if(! StackEmpty && ! st_.empty()) | 98 | 0 | { | 99 | 0 | state st; | 100 | 0 | st_.pop(st); | 101 | 0 | switch(st) | 102 | 0 | { | 103 | 0 | default: | 104 | 0 | case state::nul1: goto do_nul1; | 105 | 0 | case state::nul2: goto do_nul2; | 106 | 0 | case state::nul3: goto do_nul3; | 107 | 0 | case state::nul4: goto do_nul4; | 108 | 0 | } | 109 | 0 | } | 110 | 68 | do_nul1: | 111 | 68 | if(BOOST_JSON_LIKELY(ss)) | 112 | 56 | ss.append('n'); | 113 | 12 | else | 114 | 12 | return suspend(state::nul1); | 115 | 56 | do_nul2: | 116 | 56 | if(BOOST_JSON_LIKELY(ss)) | 117 | 39 | ss.append('u'); | 118 | 17 | else | 119 | 17 | return suspend(state::nul2); | 120 | 39 | do_nul3: | 121 | 39 | if(BOOST_JSON_LIKELY(ss)) | 122 | 21 | ss.append('l'); | 123 | 18 | else | 124 | 18 | return suspend(state::nul3); | 125 | 21 | do_nul4: | 126 | 21 | if(BOOST_JSON_LIKELY(ss)) | 127 | 0 | ss.append('l'); | 128 | 21 | else | 129 | 21 | return suspend(state::nul4); | 130 | 0 | return true; | 131 | 21 | } |
bool boost::json::serializer::write_null<false>(boost::json::detail::stream&) Line | Count | Source | 95 | 68 | { | 96 | 68 | local_stream ss(ss0); | 97 | 68 | if(! StackEmpty && ! st_.empty()) | 98 | 68 | { | 99 | 68 | state st; | 100 | 68 | st_.pop(st); | 101 | 68 | switch(st) | 102 | 68 | { | 103 | 0 | default: | 104 | 12 | case state::nul1: goto do_nul1; | 105 | 17 | case state::nul2: goto do_nul2; | 106 | 18 | case state::nul3: goto do_nul3; | 107 | 21 | case state::nul4: goto do_nul4; | 108 | 68 | } | 109 | 68 | } | 110 | 12 | do_nul1: | 111 | 12 | if(BOOST_JSON_LIKELY(ss)) | 112 | 12 | ss.append('n'); | 113 | 0 | else | 114 | 0 | return suspend(state::nul1); | 115 | 29 | do_nul2: | 116 | 29 | if(BOOST_JSON_LIKELY(ss)) | 117 | 29 | ss.append('u'); | 118 | 0 | else | 119 | 0 | return suspend(state::nul2); | 120 | 47 | do_nul3: | 121 | 47 | if(BOOST_JSON_LIKELY(ss)) | 122 | 47 | ss.append('l'); | 123 | 0 | else | 124 | 0 | return suspend(state::nul3); | 125 | 68 | do_nul4: | 126 | 68 | if(BOOST_JSON_LIKELY(ss)) | 127 | 68 | ss.append('l'); | 128 | 0 | else | 129 | 0 | return suspend(state::nul4); | 130 | 68 | return true; | 131 | 68 | } |
|
132 | | |
133 | | template<bool StackEmpty> |
134 | | bool |
135 | | serializer:: |
136 | | write_true(stream& ss0) |
137 | 122 | { |
138 | 122 | local_stream ss(ss0); |
139 | 122 | if(! StackEmpty && ! st_.empty()) |
140 | 61 | { |
141 | 61 | state st; |
142 | 61 | st_.pop(st); |
143 | 61 | switch(st) |
144 | 61 | { |
145 | 0 | default: |
146 | 15 | case state::tru1: goto do_tru1; |
147 | 15 | case state::tru2: goto do_tru2; |
148 | 13 | case state::tru3: goto do_tru3; |
149 | 18 | case state::tru4: goto do_tru4; |
150 | 61 | } |
151 | 61 | } |
152 | 76 | do_tru1: |
153 | 76 | if(BOOST_JSON_LIKELY(ss)) |
154 | 61 | ss.append('t'); |
155 | 15 | else |
156 | 15 | return suspend(state::tru1); |
157 | 76 | do_tru2: |
158 | 76 | if(BOOST_JSON_LIKELY(ss)) |
159 | 61 | ss.append('r'); |
160 | 15 | else |
161 | 15 | return suspend(state::tru2); |
162 | 74 | do_tru3: |
163 | 74 | if(BOOST_JSON_LIKELY(ss)) |
164 | 61 | ss.append('u'); |
165 | 13 | else |
166 | 13 | return suspend(state::tru3); |
167 | 79 | do_tru4: |
168 | 79 | if(BOOST_JSON_LIKELY(ss)) |
169 | 61 | ss.append('e'); |
170 | 18 | else |
171 | 18 | return suspend(state::tru4); |
172 | 61 | return true; |
173 | 79 | } bool boost::json::serializer::write_true<true>(boost::json::detail::stream&) Line | Count | Source | 137 | 61 | { | 138 | 61 | local_stream ss(ss0); | 139 | 61 | if(! StackEmpty && ! st_.empty()) | 140 | 0 | { | 141 | 0 | state st; | 142 | 0 | st_.pop(st); | 143 | 0 | switch(st) | 144 | 0 | { | 145 | 0 | default: | 146 | 0 | case state::tru1: goto do_tru1; | 147 | 0 | case state::tru2: goto do_tru2; | 148 | 0 | case state::tru3: goto do_tru3; | 149 | 0 | case state::tru4: goto do_tru4; | 150 | 0 | } | 151 | 0 | } | 152 | 61 | do_tru1: | 153 | 61 | if(BOOST_JSON_LIKELY(ss)) | 154 | 46 | ss.append('t'); | 155 | 15 | else | 156 | 15 | return suspend(state::tru1); | 157 | 46 | do_tru2: | 158 | 46 | if(BOOST_JSON_LIKELY(ss)) | 159 | 31 | ss.append('r'); | 160 | 15 | else | 161 | 15 | return suspend(state::tru2); | 162 | 31 | do_tru3: | 163 | 31 | if(BOOST_JSON_LIKELY(ss)) | 164 | 18 | ss.append('u'); | 165 | 13 | else | 166 | 13 | return suspend(state::tru3); | 167 | 18 | do_tru4: | 168 | 18 | if(BOOST_JSON_LIKELY(ss)) | 169 | 0 | ss.append('e'); | 170 | 18 | else | 171 | 18 | return suspend(state::tru4); | 172 | 0 | return true; | 173 | 18 | } |
bool boost::json::serializer::write_true<false>(boost::json::detail::stream&) Line | Count | Source | 137 | 61 | { | 138 | 61 | local_stream ss(ss0); | 139 | 61 | if(! StackEmpty && ! st_.empty()) | 140 | 61 | { | 141 | 61 | state st; | 142 | 61 | st_.pop(st); | 143 | 61 | switch(st) | 144 | 61 | { | 145 | 0 | default: | 146 | 15 | case state::tru1: goto do_tru1; | 147 | 15 | case state::tru2: goto do_tru2; | 148 | 13 | case state::tru3: goto do_tru3; | 149 | 18 | case state::tru4: goto do_tru4; | 150 | 61 | } | 151 | 61 | } | 152 | 15 | do_tru1: | 153 | 15 | if(BOOST_JSON_LIKELY(ss)) | 154 | 15 | ss.append('t'); | 155 | 0 | else | 156 | 0 | return suspend(state::tru1); | 157 | 30 | do_tru2: | 158 | 30 | if(BOOST_JSON_LIKELY(ss)) | 159 | 30 | ss.append('r'); | 160 | 0 | else | 161 | 0 | return suspend(state::tru2); | 162 | 43 | do_tru3: | 163 | 43 | if(BOOST_JSON_LIKELY(ss)) | 164 | 43 | ss.append('u'); | 165 | 0 | else | 166 | 0 | return suspend(state::tru3); | 167 | 61 | do_tru4: | 168 | 61 | if(BOOST_JSON_LIKELY(ss)) | 169 | 61 | ss.append('e'); | 170 | 0 | else | 171 | 0 | return suspend(state::tru4); | 172 | 61 | return true; | 173 | 61 | } |
|
174 | | |
175 | | template<bool StackEmpty> |
176 | | bool |
177 | | serializer:: |
178 | | write_false(stream& ss0) |
179 | 142 | { |
180 | 142 | local_stream ss(ss0); |
181 | 142 | if(! StackEmpty && ! st_.empty()) |
182 | 71 | { |
183 | 71 | state st; |
184 | 71 | st_.pop(st); |
185 | 71 | switch(st) |
186 | 71 | { |
187 | 0 | default: |
188 | 13 | case state::fal1: goto do_fal1; |
189 | 14 | case state::fal2: goto do_fal2; |
190 | 12 | case state::fal3: goto do_fal3; |
191 | 17 | case state::fal4: goto do_fal4; |
192 | 15 | case state::fal5: goto do_fal5; |
193 | 71 | } |
194 | 71 | } |
195 | 84 | do_fal1: |
196 | 84 | if(BOOST_JSON_LIKELY(ss)) |
197 | 71 | ss.append('f'); |
198 | 13 | else |
199 | 13 | return suspend(state::fal1); |
200 | 85 | do_fal2: |
201 | 85 | if(BOOST_JSON_LIKELY(ss)) |
202 | 71 | ss.append('a'); |
203 | 14 | else |
204 | 14 | return suspend(state::fal2); |
205 | 83 | do_fal3: |
206 | 83 | if(BOOST_JSON_LIKELY(ss)) |
207 | 71 | ss.append('l'); |
208 | 12 | else |
209 | 12 | return suspend(state::fal3); |
210 | 88 | do_fal4: |
211 | 88 | if(BOOST_JSON_LIKELY(ss)) |
212 | 71 | ss.append('s'); |
213 | 17 | else |
214 | 17 | return suspend(state::fal4); |
215 | 86 | do_fal5: |
216 | 86 | if(BOOST_JSON_LIKELY(ss)) |
217 | 71 | ss.append('e'); |
218 | 15 | else |
219 | 15 | return suspend(state::fal5); |
220 | 71 | return true; |
221 | 86 | } bool boost::json::serializer::write_false<true>(boost::json::detail::stream&) Line | Count | Source | 179 | 71 | { | 180 | 71 | local_stream ss(ss0); | 181 | 71 | if(! StackEmpty && ! st_.empty()) | 182 | 0 | { | 183 | 0 | state st; | 184 | 0 | st_.pop(st); | 185 | 0 | switch(st) | 186 | 0 | { | 187 | 0 | default: | 188 | 0 | case state::fal1: goto do_fal1; | 189 | 0 | case state::fal2: goto do_fal2; | 190 | 0 | case state::fal3: goto do_fal3; | 191 | 0 | case state::fal4: goto do_fal4; | 192 | 0 | case state::fal5: goto do_fal5; | 193 | 0 | } | 194 | 0 | } | 195 | 71 | do_fal1: | 196 | 71 | if(BOOST_JSON_LIKELY(ss)) | 197 | 58 | ss.append('f'); | 198 | 13 | else | 199 | 13 | return suspend(state::fal1); | 200 | 58 | do_fal2: | 201 | 58 | if(BOOST_JSON_LIKELY(ss)) | 202 | 44 | ss.append('a'); | 203 | 14 | else | 204 | 14 | return suspend(state::fal2); | 205 | 44 | do_fal3: | 206 | 44 | if(BOOST_JSON_LIKELY(ss)) | 207 | 32 | ss.append('l'); | 208 | 12 | else | 209 | 12 | return suspend(state::fal3); | 210 | 32 | do_fal4: | 211 | 32 | if(BOOST_JSON_LIKELY(ss)) | 212 | 15 | ss.append('s'); | 213 | 17 | else | 214 | 17 | return suspend(state::fal4); | 215 | 15 | do_fal5: | 216 | 15 | if(BOOST_JSON_LIKELY(ss)) | 217 | 0 | ss.append('e'); | 218 | 15 | else | 219 | 15 | return suspend(state::fal5); | 220 | 0 | return true; | 221 | 15 | } |
bool boost::json::serializer::write_false<false>(boost::json::detail::stream&) Line | Count | Source | 179 | 71 | { | 180 | 71 | local_stream ss(ss0); | 181 | 71 | if(! StackEmpty && ! st_.empty()) | 182 | 71 | { | 183 | 71 | state st; | 184 | 71 | st_.pop(st); | 185 | 71 | switch(st) | 186 | 71 | { | 187 | 0 | default: | 188 | 13 | case state::fal1: goto do_fal1; | 189 | 14 | case state::fal2: goto do_fal2; | 190 | 12 | case state::fal3: goto do_fal3; | 191 | 17 | case state::fal4: goto do_fal4; | 192 | 15 | case state::fal5: goto do_fal5; | 193 | 71 | } | 194 | 71 | } | 195 | 13 | do_fal1: | 196 | 13 | if(BOOST_JSON_LIKELY(ss)) | 197 | 13 | ss.append('f'); | 198 | 0 | else | 199 | 0 | return suspend(state::fal1); | 200 | 27 | do_fal2: | 201 | 27 | if(BOOST_JSON_LIKELY(ss)) | 202 | 27 | ss.append('a'); | 203 | 0 | else | 204 | 0 | return suspend(state::fal2); | 205 | 39 | do_fal3: | 206 | 39 | if(BOOST_JSON_LIKELY(ss)) | 207 | 39 | ss.append('l'); | 208 | 0 | else | 209 | 0 | return suspend(state::fal3); | 210 | 56 | do_fal4: | 211 | 56 | if(BOOST_JSON_LIKELY(ss)) | 212 | 56 | ss.append('s'); | 213 | 0 | else | 214 | 0 | return suspend(state::fal4); | 215 | 71 | do_fal5: | 216 | 71 | if(BOOST_JSON_LIKELY(ss)) | 217 | 71 | ss.append('e'); | 218 | 0 | else | 219 | 0 | return suspend(state::fal5); | 220 | 71 | return true; | 221 | 71 | } |
|
222 | | |
223 | | template<bool StackEmpty> |
224 | | bool |
225 | | serializer:: |
226 | | write_string(stream& ss0) |
227 | 33.4k | { |
228 | 33.4k | local_stream ss(ss0); |
229 | 33.4k | local_const_stream cs(cs0_); |
230 | 33.4k | if(! StackEmpty && ! st_.empty()) |
231 | 979 | { |
232 | 979 | state st; |
233 | 979 | st_.pop(st); |
234 | 979 | switch(st) |
235 | 979 | { |
236 | 0 | default: |
237 | 32 | case state::str1: goto do_str1; |
238 | 95 | case state::str2: goto do_str2; |
239 | 655 | case state::str3: goto do_str3; |
240 | 0 | case state::str4: goto do_str4; |
241 | 41 | case state::esc1: goto do_esc1; |
242 | 31 | case state::utf1: goto do_utf1; |
243 | 33 | case state::utf2: goto do_utf2; |
244 | 33 | case state::utf3: goto do_utf3; |
245 | 28 | case state::utf4: goto do_utf4; |
246 | 31 | case state::utf5: goto do_utf5; |
247 | 979 | } |
248 | 979 | } |
249 | 32.4k | static constexpr char hex[] = "0123456789abcdef"; |
250 | 32.4k | static constexpr char esc[] = |
251 | 32.4k | "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu" |
252 | 32.4k | "\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
253 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0" |
254 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
255 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
256 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
257 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
258 | 32.4k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; |
259 | | |
260 | | // opening quote |
261 | 32.4k | do_str1: |
262 | 32.4k | if(BOOST_JSON_LIKELY(ss)) |
263 | 32.4k | ss.append('\x22'); // '"' |
264 | 32 | else |
265 | 32 | return suspend(state::str1); |
266 | | |
267 | | // fast loop, |
268 | | // copy unescaped |
269 | 32.5k | do_str2: |
270 | 32.5k | if(BOOST_JSON_LIKELY(ss)) |
271 | 32.5k | { |
272 | 32.5k | std::size_t n = cs.remain(); |
273 | 32.5k | if(BOOST_JSON_LIKELY(n > 0)) |
274 | 17.4k | { |
275 | 17.4k | if(ss.remain() > n) |
276 | 17.0k | n = detail::count_unescaped( |
277 | 17.0k | cs.data(), n); |
278 | 419 | else |
279 | 419 | n = detail::count_unescaped( |
280 | 419 | cs.data(), ss.remain()); |
281 | 17.4k | if(n > 0) |
282 | 7.63k | { |
283 | 7.63k | ss.append(cs.data(), n); |
284 | 7.63k | cs.skip(n); |
285 | 7.63k | if(! ss) |
286 | 43 | return suspend(state::str2); |
287 | 7.63k | } |
288 | 17.4k | } |
289 | 15.0k | else |
290 | 15.0k | { |
291 | 15.0k | ss.append('\x22'); // '"' |
292 | 15.0k | return true; |
293 | 15.0k | } |
294 | 32.5k | } |
295 | 52 | else |
296 | 52 | { |
297 | 52 | return suspend(state::str2); |
298 | 52 | } |
299 | | |
300 | | // slow loop, |
301 | | // handle escapes |
302 | 18.2k | do_str3: |
303 | 24.6M | while(BOOST_JSON_LIKELY(ss)) |
304 | 24.6M | { |
305 | 24.6M | if(BOOST_JSON_LIKELY(cs)) |
306 | 24.6M | { |
307 | 24.6M | auto const ch = *cs; |
308 | 24.6M | auto const c = esc[static_cast< |
309 | 24.6M | unsigned char>(ch)]; |
310 | 24.6M | ++cs; |
311 | 24.6M | if(! c) |
312 | 24.1M | { |
313 | 24.1M | ss.append(ch); |
314 | 24.1M | } |
315 | 470k | else if(c != 'u') |
316 | 313k | { |
317 | 313k | ss.append('\\'); |
318 | 313k | if(BOOST_JSON_LIKELY(ss)) |
319 | 313k | { |
320 | 313k | ss.append(c); |
321 | 313k | } |
322 | 41 | else |
323 | 41 | { |
324 | 41 | buf_[0] = c; |
325 | 41 | return suspend( |
326 | 41 | state::esc1); |
327 | 41 | } |
328 | 313k | } |
329 | 156k | else |
330 | 156k | { |
331 | 156k | if(BOOST_JSON_LIKELY( |
332 | 156k | ss.remain() >= 6)) |
333 | 156k | { |
334 | 156k | ss.append("\\u00", 4); |
335 | 156k | ss.append(hex[static_cast< |
336 | 156k | unsigned char>(ch) >> 4]); |
337 | 156k | ss.append(hex[static_cast< |
338 | 156k | unsigned char>(ch) & 15]); |
339 | 156k | } |
340 | 156 | else |
341 | 156 | { |
342 | 156 | ss.append('\\'); |
343 | 156 | buf_[0] = hex[static_cast< |
344 | 156 | unsigned char>(ch) >> 4]; |
345 | 156 | buf_[1] = hex[static_cast< |
346 | 156 | unsigned char>(ch) & 15]; |
347 | 156 | goto do_utf1; |
348 | 156 | } |
349 | 156k | } |
350 | 24.6M | } |
351 | 17.3k | else |
352 | 17.3k | { |
353 | 17.3k | ss.append('\x22'); // '"' |
354 | 17.3k | return true; |
355 | 17.3k | } |
356 | 24.6M | } |
357 | 655 | return suspend(state::str3); |
358 | | |
359 | 0 | do_str4: |
360 | 0 | if(BOOST_JSON_LIKELY(ss)) |
361 | 0 | ss.append('\x22'); // '"' |
362 | 0 | else |
363 | 0 | return suspend(state::str4); |
364 | | |
365 | 41 | do_esc1: |
366 | 41 | if(BOOST_JSON_LIKELY(ss)) |
367 | 41 | ss.append(buf_[0]); |
368 | 0 | else |
369 | 0 | return suspend(state::esc1); |
370 | 41 | goto do_str3; |
371 | | |
372 | 187 | do_utf1: |
373 | 187 | if(BOOST_JSON_LIKELY(ss)) |
374 | 156 | ss.append('u'); |
375 | 31 | else |
376 | 31 | return suspend(state::utf1); |
377 | 189 | do_utf2: |
378 | 189 | if(BOOST_JSON_LIKELY(ss)) |
379 | 156 | ss.append('0'); |
380 | 33 | else |
381 | 33 | return suspend(state::utf2); |
382 | 189 | do_utf3: |
383 | 189 | if(BOOST_JSON_LIKELY(ss)) |
384 | 156 | ss.append('0'); |
385 | 33 | else |
386 | 33 | return suspend(state::utf3); |
387 | 184 | do_utf4: |
388 | 184 | if(BOOST_JSON_LIKELY(ss)) |
389 | 156 | ss.append(buf_[0]); |
390 | 28 | else |
391 | 28 | return suspend(state::utf4); |
392 | 187 | do_utf5: |
393 | 187 | if(BOOST_JSON_LIKELY(ss)) |
394 | 156 | ss.append(buf_[1]); |
395 | 31 | else |
396 | 31 | return suspend(state::utf5); |
397 | 156 | goto do_str3; |
398 | 187 | } bool boost::json::serializer::write_string<true>(boost::json::detail::stream&) Line | Count | Source | 227 | 30.3k | { | 228 | 30.3k | local_stream ss(ss0); | 229 | 30.3k | local_const_stream cs(cs0_); | 230 | 30.3k | if(! StackEmpty && ! st_.empty()) | 231 | 0 | { | 232 | 0 | state st; | 233 | 0 | st_.pop(st); | 234 | 0 | switch(st) | 235 | 0 | { | 236 | 0 | default: | 237 | 0 | case state::str1: goto do_str1; | 238 | 0 | case state::str2: goto do_str2; | 239 | 0 | case state::str3: goto do_str3; | 240 | 0 | case state::str4: goto do_str4; | 241 | 0 | case state::esc1: goto do_esc1; | 242 | 0 | case state::utf1: goto do_utf1; | 243 | 0 | case state::utf2: goto do_utf2; | 244 | 0 | case state::utf3: goto do_utf3; | 245 | 0 | case state::utf4: goto do_utf4; | 246 | 0 | case state::utf5: goto do_utf5; | 247 | 0 | } | 248 | 0 | } | 249 | 30.3k | static constexpr char hex[] = "0123456789abcdef"; | 250 | 30.3k | static constexpr char esc[] = | 251 | 30.3k | "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu" | 252 | 30.3k | "\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 253 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0" | 254 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 255 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 256 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 257 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 258 | 30.3k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; | 259 | | | 260 | | // opening quote | 261 | 30.3k | do_str1: | 262 | 30.3k | if(BOOST_JSON_LIKELY(ss)) | 263 | 30.3k | ss.append('\x22'); // '"' | 264 | 21 | else | 265 | 21 | return suspend(state::str1); | 266 | | | 267 | | // fast loop, | 268 | | // copy unescaped | 269 | 30.3k | do_str2: | 270 | 30.3k | if(BOOST_JSON_LIKELY(ss)) | 271 | 30.3k | { | 272 | 30.3k | std::size_t n = cs.remain(); | 273 | 30.3k | if(BOOST_JSON_LIKELY(n > 0)) | 274 | 15.4k | { | 275 | 15.4k | if(ss.remain() > n) | 276 | 15.1k | n = detail::count_unescaped( | 277 | 15.1k | cs.data(), n); | 278 | 305 | else | 279 | 305 | n = detail::count_unescaped( | 280 | 305 | cs.data(), ss.remain()); | 281 | 15.4k | if(n > 0) | 282 | 6.42k | { | 283 | 6.42k | ss.append(cs.data(), n); | 284 | 6.42k | cs.skip(n); | 285 | 6.42k | if(! ss) | 286 | 26 | return suspend(state::str2); | 287 | 6.42k | } | 288 | 15.4k | } | 289 | 14.9k | else | 290 | 14.9k | { | 291 | 14.9k | ss.append('\x22'); // '"' | 292 | 14.9k | return true; | 293 | 14.9k | } | 294 | 30.3k | } | 295 | 40 | else | 296 | 40 | { | 297 | 40 | return suspend(state::str2); | 298 | 40 | } | 299 | | | 300 | | // slow loop, | 301 | | // handle escapes | 302 | 15.3k | do_str3: | 303 | 771k | while(BOOST_JSON_LIKELY(ss)) | 304 | 771k | { | 305 | 771k | if(BOOST_JSON_LIKELY(cs)) | 306 | 756k | { | 307 | 756k | auto const ch = *cs; | 308 | 756k | auto const c = esc[static_cast< | 309 | 756k | unsigned char>(ch)]; | 310 | 756k | ++cs; | 311 | 756k | if(! c) | 312 | 727k | { | 313 | 727k | ss.append(ch); | 314 | 727k | } | 315 | 28.7k | else if(c != 'u') | 316 | 14.2k | { | 317 | 14.2k | ss.append('\\'); | 318 | 14.2k | if(BOOST_JSON_LIKELY(ss)) | 319 | 14.2k | { | 320 | 14.2k | ss.append(c); | 321 | 14.2k | } | 322 | 23 | else | 323 | 23 | { | 324 | 23 | buf_[0] = c; | 325 | 23 | return suspend( | 326 | 23 | state::esc1); | 327 | 23 | } | 328 | 14.2k | } | 329 | 14.5k | else | 330 | 14.5k | { | 331 | 14.5k | if(BOOST_JSON_LIKELY( | 332 | 14.5k | ss.remain() >= 6)) | 333 | 14.4k | { | 334 | 14.4k | ss.append("\\u00", 4); | 335 | 14.4k | ss.append(hex[static_cast< | 336 | 14.4k | unsigned char>(ch) >> 4]); | 337 | 14.4k | ss.append(hex[static_cast< | 338 | 14.4k | unsigned char>(ch) & 15]); | 339 | 14.4k | } | 340 | 81 | else | 341 | 81 | { | 342 | 81 | ss.append('\\'); | 343 | 81 | buf_[0] = hex[static_cast< | 344 | 81 | unsigned char>(ch) >> 4]; | 345 | 81 | buf_[1] = hex[static_cast< | 346 | 81 | unsigned char>(ch) & 15]; | 347 | 81 | goto do_utf1; | 348 | 81 | } | 349 | 14.5k | } | 350 | 756k | } | 351 | 15.0k | else | 352 | 15.0k | { | 353 | 15.0k | ss.append('\x22'); // '"' | 354 | 15.0k | return true; | 355 | 15.0k | } | 356 | 771k | } | 357 | 218 | return suspend(state::str3); | 358 | | | 359 | 0 | do_str4: | 360 | 0 | if(BOOST_JSON_LIKELY(ss)) | 361 | 0 | ss.append('\x22'); // '"' | 362 | 0 | else | 363 | 0 | return suspend(state::str4); | 364 | | | 365 | 0 | do_esc1: | 366 | 0 | if(BOOST_JSON_LIKELY(ss)) | 367 | 0 | ss.append(buf_[0]); | 368 | 0 | else | 369 | 0 | return suspend(state::esc1); | 370 | 0 | goto do_str3; | 371 | | | 372 | 81 | do_utf1: | 373 | 81 | if(BOOST_JSON_LIKELY(ss)) | 374 | 64 | ss.append('u'); | 375 | 17 | else | 376 | 17 | return suspend(state::utf1); | 377 | 64 | do_utf2: | 378 | 64 | if(BOOST_JSON_LIKELY(ss)) | 379 | 44 | ss.append('0'); | 380 | 20 | else | 381 | 20 | return suspend(state::utf2); | 382 | 44 | do_utf3: | 383 | 44 | if(BOOST_JSON_LIKELY(ss)) | 384 | 27 | ss.append('0'); | 385 | 17 | else | 386 | 17 | return suspend(state::utf3); | 387 | 27 | do_utf4: | 388 | 27 | if(BOOST_JSON_LIKELY(ss)) | 389 | 14 | ss.append(buf_[0]); | 390 | 13 | else | 391 | 13 | return suspend(state::utf4); | 392 | 14 | do_utf5: | 393 | 14 | if(BOOST_JSON_LIKELY(ss)) | 394 | 0 | ss.append(buf_[1]); | 395 | 14 | else | 396 | 14 | return suspend(state::utf5); | 397 | 0 | goto do_str3; | 398 | 14 | } |
bool boost::json::serializer::write_string<false>(boost::json::detail::stream&) Line | Count | Source | 227 | 3.04k | { | 228 | 3.04k | local_stream ss(ss0); | 229 | 3.04k | local_const_stream cs(cs0_); | 230 | 3.04k | if(! StackEmpty && ! st_.empty()) | 231 | 979 | { | 232 | 979 | state st; | 233 | 979 | st_.pop(st); | 234 | 979 | switch(st) | 235 | 979 | { | 236 | 0 | default: | 237 | 32 | case state::str1: goto do_str1; | 238 | 95 | case state::str2: goto do_str2; | 239 | 655 | case state::str3: goto do_str3; | 240 | 0 | case state::str4: goto do_str4; | 241 | 41 | case state::esc1: goto do_esc1; | 242 | 31 | case state::utf1: goto do_utf1; | 243 | 33 | case state::utf2: goto do_utf2; | 244 | 33 | case state::utf3: goto do_utf3; | 245 | 28 | case state::utf4: goto do_utf4; | 246 | 31 | case state::utf5: goto do_utf5; | 247 | 979 | } | 248 | 979 | } | 249 | 2.06k | static constexpr char hex[] = "0123456789abcdef"; | 250 | 2.06k | static constexpr char esc[] = | 251 | 2.06k | "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu" | 252 | 2.06k | "\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 253 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0" | 254 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 255 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 256 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 257 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 258 | 2.06k | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; | 259 | | | 260 | | // opening quote | 261 | 2.09k | do_str1: | 262 | 2.09k | if(BOOST_JSON_LIKELY(ss)) | 263 | 2.08k | ss.append('\x22'); // '"' | 264 | 11 | else | 265 | 11 | return suspend(state::str1); | 266 | | | 267 | | // fast loop, | 268 | | // copy unescaped | 269 | 2.17k | do_str2: | 270 | 2.17k | if(BOOST_JSON_LIKELY(ss)) | 271 | 2.16k | { | 272 | 2.16k | std::size_t n = cs.remain(); | 273 | 2.16k | if(BOOST_JSON_LIKELY(n > 0)) | 274 | 2.02k | { | 275 | 2.02k | if(ss.remain() > n) | 276 | 1.90k | n = detail::count_unescaped( | 277 | 1.90k | cs.data(), n); | 278 | 114 | else | 279 | 114 | n = detail::count_unescaped( | 280 | 114 | cs.data(), ss.remain()); | 281 | 2.02k | if(n > 0) | 282 | 1.21k | { | 283 | 1.21k | ss.append(cs.data(), n); | 284 | 1.21k | cs.skip(n); | 285 | 1.21k | if(! ss) | 286 | 17 | return suspend(state::str2); | 287 | 1.21k | } | 288 | 2.02k | } | 289 | 145 | else | 290 | 145 | { | 291 | 145 | ss.append('\x22'); // '"' | 292 | 145 | return true; | 293 | 145 | } | 294 | 2.16k | } | 295 | 12 | else | 296 | 12 | { | 297 | 12 | return suspend(state::str2); | 298 | 12 | } | 299 | | | 300 | | // slow loop, | 301 | | // handle escapes | 302 | 2.85k | do_str3: | 303 | 23.8M | while(BOOST_JSON_LIKELY(ss)) | 304 | 23.8M | { | 305 | 23.8M | if(BOOST_JSON_LIKELY(cs)) | 306 | 23.8M | { | 307 | 23.8M | auto const ch = *cs; | 308 | 23.8M | auto const c = esc[static_cast< | 309 | 23.8M | unsigned char>(ch)]; | 310 | 23.8M | ++cs; | 311 | 23.8M | if(! c) | 312 | 23.4M | { | 313 | 23.4M | ss.append(ch); | 314 | 23.4M | } | 315 | 441k | else if(c != 'u') | 316 | 299k | { | 317 | 299k | ss.append('\\'); | 318 | 299k | if(BOOST_JSON_LIKELY(ss)) | 319 | 299k | { | 320 | 299k | ss.append(c); | 321 | 299k | } | 322 | 18 | else | 323 | 18 | { | 324 | 18 | buf_[0] = c; | 325 | 18 | return suspend( | 326 | 18 | state::esc1); | 327 | 18 | } | 328 | 299k | } | 329 | 141k | else | 330 | 141k | { | 331 | 141k | if(BOOST_JSON_LIKELY( | 332 | 141k | ss.remain() >= 6)) | 333 | 141k | { | 334 | 141k | ss.append("\\u00", 4); | 335 | 141k | ss.append(hex[static_cast< | 336 | 141k | unsigned char>(ch) >> 4]); | 337 | 141k | ss.append(hex[static_cast< | 338 | 141k | unsigned char>(ch) & 15]); | 339 | 141k | } | 340 | 75 | else | 341 | 75 | { | 342 | 75 | ss.append('\\'); | 343 | 75 | buf_[0] = hex[static_cast< | 344 | 75 | unsigned char>(ch) >> 4]; | 345 | 75 | buf_[1] = hex[static_cast< | 346 | 75 | unsigned char>(ch) & 15]; | 347 | 75 | goto do_utf1; | 348 | 75 | } | 349 | 141k | } | 350 | 23.8M | } | 351 | 2.32k | else | 352 | 2.32k | { | 353 | 2.32k | ss.append('\x22'); // '"' | 354 | 2.32k | return true; | 355 | 2.32k | } | 356 | 23.8M | } | 357 | 437 | return suspend(state::str3); | 358 | | | 359 | 0 | do_str4: | 360 | 0 | if(BOOST_JSON_LIKELY(ss)) | 361 | 0 | ss.append('\x22'); // '"' | 362 | 0 | else | 363 | 0 | return suspend(state::str4); | 364 | | | 365 | 41 | do_esc1: | 366 | 41 | if(BOOST_JSON_LIKELY(ss)) | 367 | 41 | ss.append(buf_[0]); | 368 | 0 | else | 369 | 0 | return suspend(state::esc1); | 370 | 41 | goto do_str3; | 371 | | | 372 | 106 | do_utf1: | 373 | 106 | if(BOOST_JSON_LIKELY(ss)) | 374 | 92 | ss.append('u'); | 375 | 14 | else | 376 | 14 | return suspend(state::utf1); | 377 | 125 | do_utf2: | 378 | 125 | if(BOOST_JSON_LIKELY(ss)) | 379 | 112 | ss.append('0'); | 380 | 13 | else | 381 | 13 | return suspend(state::utf2); | 382 | 145 | do_utf3: | 383 | 145 | if(BOOST_JSON_LIKELY(ss)) | 384 | 129 | ss.append('0'); | 385 | 16 | else | 386 | 16 | return suspend(state::utf3); | 387 | 157 | do_utf4: | 388 | 157 | if(BOOST_JSON_LIKELY(ss)) | 389 | 142 | ss.append(buf_[0]); | 390 | 15 | else | 391 | 15 | return suspend(state::utf4); | 392 | 173 | do_utf5: | 393 | 173 | if(BOOST_JSON_LIKELY(ss)) | 394 | 156 | ss.append(buf_[1]); | 395 | 17 | else | 396 | 17 | return suspend(state::utf5); | 397 | 156 | goto do_str3; | 398 | 173 | } |
|
399 | | |
400 | | template<bool StackEmpty> |
401 | | bool |
402 | | serializer:: |
403 | | write_number(stream& ss0) |
404 | 6.88M | { |
405 | 6.88M | local_stream ss(ss0); |
406 | 6.88M | if(StackEmpty || st_.empty()) |
407 | 6.88M | { |
408 | 6.88M | switch(jv_->kind()) |
409 | 6.88M | { |
410 | 0 | default: |
411 | 2.14M | case kind::int64: |
412 | 2.14M | if(BOOST_JSON_LIKELY( |
413 | 2.14M | ss.remain() >= |
414 | 2.14M | detail::max_number_chars)) |
415 | 2.13M | { |
416 | 2.13M | ss.advance(detail::format_int64( |
417 | 2.13M | ss.data(), jv_->get_int64())); |
418 | 2.13M | return true; |
419 | 2.13M | } |
420 | 2.03k | cs0_ = { buf_, detail::format_int64( |
421 | 2.03k | buf_, jv_->get_int64()) }; |
422 | 2.03k | break; |
423 | | |
424 | 19.5k | case kind::uint64: |
425 | 19.5k | if(BOOST_JSON_LIKELY( |
426 | 19.5k | ss.remain() >= |
427 | 19.5k | detail::max_number_chars)) |
428 | 19.3k | { |
429 | 19.3k | ss.advance(detail::format_uint64( |
430 | 19.3k | ss.data(), jv_->get_uint64())); |
431 | 19.3k | return true; |
432 | 19.3k | } |
433 | 154 | cs0_ = { buf_, detail::format_uint64( |
434 | 154 | buf_, jv_->get_uint64()) }; |
435 | 154 | break; |
436 | | |
437 | 4.72M | case kind::double_: |
438 | 4.72M | if(BOOST_JSON_LIKELY( |
439 | 4.72M | ss.remain() >= |
440 | 4.72M | detail::max_number_chars)) |
441 | 4.72M | { |
442 | 4.72M | ss.advance( |
443 | 4.72M | detail::format_double( |
444 | 4.72M | ss.data(), |
445 | 4.72M | jv_->get_double(), |
446 | 4.72M | opts_.allow_infinity_and_nan)); |
447 | 4.72M | return true; |
448 | 4.72M | } |
449 | 1.51k | cs0_ = { buf_, detail::format_double( |
450 | 1.51k | buf_, jv_->get_double(), opts_.allow_infinity_and_nan) }; |
451 | 1.51k | break; |
452 | 6.88M | } |
453 | 6.88M | } |
454 | 987 | else |
455 | 987 | { |
456 | 987 | state st; |
457 | 987 | st_.pop(st); |
458 | 987 | BOOST_ASSERT( |
459 | 987 | st == state::num); |
460 | 987 | } |
461 | 4.69k | auto const n = ss.remain(); |
462 | 4.69k | if(n < cs0_.remain()) |
463 | 987 | { |
464 | 987 | ss.append(cs0_.data(), n); |
465 | 987 | cs0_.skip(n); |
466 | 987 | return suspend(state::num); |
467 | 987 | } |
468 | 3.70k | ss.append( |
469 | 3.70k | cs0_.data(), cs0_.remain()); |
470 | 3.70k | return true; |
471 | 4.69k | } bool boost::json::serializer::write_number<true>(boost::json::detail::stream&) Line | Count | Source | 404 | 6.88M | { | 405 | 6.88M | local_stream ss(ss0); | 406 | 6.88M | if(StackEmpty || st_.empty()) | 407 | 6.88M | { | 408 | 6.88M | switch(jv_->kind()) | 409 | 6.88M | { | 410 | 0 | default: | 411 | 2.14M | case kind::int64: | 412 | 2.14M | if(BOOST_JSON_LIKELY( | 413 | 2.14M | ss.remain() >= | 414 | 2.14M | detail::max_number_chars)) | 415 | 2.13M | { | 416 | 2.13M | ss.advance(detail::format_int64( | 417 | 2.13M | ss.data(), jv_->get_int64())); | 418 | 2.13M | return true; | 419 | 2.13M | } | 420 | 2.03k | cs0_ = { buf_, detail::format_int64( | 421 | 2.03k | buf_, jv_->get_int64()) }; | 422 | 2.03k | break; | 423 | | | 424 | 19.5k | case kind::uint64: | 425 | 19.5k | if(BOOST_JSON_LIKELY( | 426 | 19.5k | ss.remain() >= | 427 | 19.5k | detail::max_number_chars)) | 428 | 19.3k | { | 429 | 19.3k | ss.advance(detail::format_uint64( | 430 | 19.3k | ss.data(), jv_->get_uint64())); | 431 | 19.3k | return true; | 432 | 19.3k | } | 433 | 154 | cs0_ = { buf_, detail::format_uint64( | 434 | 154 | buf_, jv_->get_uint64()) }; | 435 | 154 | break; | 436 | | | 437 | 4.72M | case kind::double_: | 438 | 4.72M | if(BOOST_JSON_LIKELY( | 439 | 4.72M | ss.remain() >= | 440 | 4.72M | detail::max_number_chars)) | 441 | 4.72M | { | 442 | 4.72M | ss.advance( | 443 | 4.72M | detail::format_double( | 444 | 4.72M | ss.data(), | 445 | 4.72M | jv_->get_double(), | 446 | 4.72M | opts_.allow_infinity_and_nan)); | 447 | 4.72M | return true; | 448 | 4.72M | } | 449 | 1.51k | cs0_ = { buf_, detail::format_double( | 450 | 1.51k | buf_, jv_->get_double(), opts_.allow_infinity_and_nan) }; | 451 | 1.51k | break; | 452 | 6.88M | } | 453 | 6.88M | } | 454 | 0 | else | 455 | 0 | { | 456 | 0 | state st; | 457 | 0 | st_.pop(st); | 458 | 0 | BOOST_ASSERT( | 459 | 0 | st == state::num); | 460 | 0 | } | 461 | 3.70k | auto const n = ss.remain(); | 462 | 3.70k | if(n < cs0_.remain()) | 463 | 987 | { | 464 | 987 | ss.append(cs0_.data(), n); | 465 | 987 | cs0_.skip(n); | 466 | 987 | return suspend(state::num); | 467 | 987 | } | 468 | 2.71k | ss.append( | 469 | 2.71k | cs0_.data(), cs0_.remain()); | 470 | 2.71k | return true; | 471 | 3.70k | } |
bool boost::json::serializer::write_number<false>(boost::json::detail::stream&) Line | Count | Source | 404 | 987 | { | 405 | 987 | local_stream ss(ss0); | 406 | 987 | if(StackEmpty || st_.empty()) | 407 | 0 | { | 408 | 0 | switch(jv_->kind()) | 409 | 0 | { | 410 | 0 | default: | 411 | 0 | case kind::int64: | 412 | 0 | if(BOOST_JSON_LIKELY( | 413 | 0 | ss.remain() >= | 414 | 0 | detail::max_number_chars)) | 415 | 0 | { | 416 | 0 | ss.advance(detail::format_int64( | 417 | 0 | ss.data(), jv_->get_int64())); | 418 | 0 | return true; | 419 | 0 | } | 420 | 0 | cs0_ = { buf_, detail::format_int64( | 421 | 0 | buf_, jv_->get_int64()) }; | 422 | 0 | break; | 423 | | | 424 | 0 | case kind::uint64: | 425 | 0 | if(BOOST_JSON_LIKELY( | 426 | 0 | ss.remain() >= | 427 | 0 | detail::max_number_chars)) | 428 | 0 | { | 429 | 0 | ss.advance(detail::format_uint64( | 430 | 0 | ss.data(), jv_->get_uint64())); | 431 | 0 | return true; | 432 | 0 | } | 433 | 0 | cs0_ = { buf_, detail::format_uint64( | 434 | 0 | buf_, jv_->get_uint64()) }; | 435 | 0 | break; | 436 | | | 437 | 0 | case kind::double_: | 438 | 0 | if(BOOST_JSON_LIKELY( | 439 | 0 | ss.remain() >= | 440 | 0 | detail::max_number_chars)) | 441 | 0 | { | 442 | 0 | ss.advance( | 443 | 0 | detail::format_double( | 444 | 0 | ss.data(), | 445 | 0 | jv_->get_double(), | 446 | 0 | opts_.allow_infinity_and_nan)); | 447 | 0 | return true; | 448 | 0 | } | 449 | 0 | cs0_ = { buf_, detail::format_double( | 450 | 0 | buf_, jv_->get_double(), opts_.allow_infinity_and_nan) }; | 451 | 0 | break; | 452 | 0 | } | 453 | 0 | } | 454 | 987 | else | 455 | 987 | { | 456 | 987 | state st; | 457 | 987 | st_.pop(st); | 458 | 987 | BOOST_ASSERT( | 459 | 987 | st == state::num); | 460 | 987 | } | 461 | 987 | auto const n = ss.remain(); | 462 | 987 | if(n < cs0_.remain()) | 463 | 0 | { | 464 | 0 | ss.append(cs0_.data(), n); | 465 | 0 | cs0_.skip(n); | 466 | 0 | return suspend(state::num); | 467 | 0 | } | 468 | 987 | ss.append( | 469 | 987 | cs0_.data(), cs0_.remain()); | 470 | 987 | return true; | 471 | 987 | } |
|
472 | | |
473 | | template<bool StackEmpty> |
474 | | bool |
475 | | serializer:: |
476 | | write_array(stream& ss0) |
477 | 17.3k | { |
478 | 17.3k | array const* pa; |
479 | 17.3k | local_stream ss(ss0); |
480 | 17.3k | array::const_iterator it; |
481 | 17.3k | array::const_iterator end; |
482 | 17.3k | if(StackEmpty || st_.empty()) |
483 | 11.4k | { |
484 | 11.4k | pa = pa_; |
485 | 11.4k | it = pa->begin(); |
486 | 11.4k | end = pa->end(); |
487 | 11.4k | } |
488 | 5.91k | else |
489 | 5.91k | { |
490 | 5.91k | state st; |
491 | 5.91k | st_.pop(st); |
492 | 5.91k | st_.pop(it); |
493 | 5.91k | st_.pop(pa); |
494 | 5.91k | end = pa->end(); |
495 | 5.91k | switch(st) |
496 | 5.91k | { |
497 | 0 | default: |
498 | 24 | case state::arr1: goto do_arr1; |
499 | 5.64k | case state::arr2: goto do_arr2; |
500 | 192 | case state::arr3: goto do_arr3; |
501 | 55 | case state::arr4: goto do_arr4; |
502 | 0 | break; |
503 | 5.91k | } |
504 | 5.91k | } |
505 | 11.4k | do_arr1: |
506 | 11.4k | if(BOOST_JSON_LIKELY(ss)) |
507 | 11.4k | ss.append('['); |
508 | 24 | else |
509 | 24 | return suspend( |
510 | 24 | state::arr1, it, pa); |
511 | 11.4k | if(it == end) |
512 | 2.01k | goto do_arr4; |
513 | 9.44k | for(;;) |
514 | 6.94M | { |
515 | 6.95M | do_arr2: |
516 | 6.95M | jv_ = &*it; |
517 | 6.95M | if(! write_value<StackEmpty>(ss)) |
518 | 5.64k | return suspend( |
519 | 5.64k | state::arr2, it, pa); |
520 | 6.94M | if(BOOST_JSON_UNLIKELY( |
521 | 6.94M | ++it == end)) |
522 | 9.44k | break; |
523 | 6.94M | do_arr3: |
524 | 6.94M | if(BOOST_JSON_LIKELY(ss)) |
525 | 6.94M | ss.append(','); |
526 | 192 | else |
527 | 192 | return suspend( |
528 | 192 | state::arr3, it, pa); |
529 | 6.94M | } |
530 | 11.5k | do_arr4: |
531 | 11.5k | if(BOOST_JSON_LIKELY(ss)) |
532 | 11.4k | ss.append(']'); |
533 | 55 | else |
534 | 55 | return suspend( |
535 | 55 | state::arr4, it, pa); |
536 | 11.4k | return true; |
537 | 11.5k | } bool boost::json::serializer::write_array<true>(boost::json::detail::stream&) Line | Count | Source | 477 | 11.4k | { | 478 | 11.4k | array const* pa; | 479 | 11.4k | local_stream ss(ss0); | 480 | 11.4k | array::const_iterator it; | 481 | 11.4k | array::const_iterator end; | 482 | 11.4k | if(StackEmpty || st_.empty()) | 483 | 11.4k | { | 484 | 11.4k | pa = pa_; | 485 | 11.4k | it = pa->begin(); | 486 | 11.4k | end = pa->end(); | 487 | 11.4k | } | 488 | 0 | else | 489 | 0 | { | 490 | 0 | state st; | 491 | 0 | st_.pop(st); | 492 | 0 | st_.pop(it); | 493 | 0 | st_.pop(pa); | 494 | 0 | end = pa->end(); | 495 | 0 | switch(st) | 496 | 0 | { | 497 | 0 | default: | 498 | 0 | case state::arr1: goto do_arr1; | 499 | 0 | case state::arr2: goto do_arr2; | 500 | 0 | case state::arr3: goto do_arr3; | 501 | 0 | case state::arr4: goto do_arr4; | 502 | 0 | break; | 503 | 0 | } | 504 | 0 | } | 505 | 11.4k | do_arr1: | 506 | 11.4k | if(BOOST_JSON_LIKELY(ss)) | 507 | 11.4k | ss.append('['); | 508 | 24 | else | 509 | 24 | return suspend( | 510 | 24 | state::arr1, it, pa); | 511 | 11.4k | if(it == end) | 512 | 2.00k | goto do_arr4; | 513 | 9.42k | for(;;) | 514 | 1.02M | { | 515 | 1.02M | do_arr2: | 516 | 1.02M | jv_ = &*it; | 517 | 1.02M | if(! write_value<StackEmpty>(ss)) | 518 | 1.75k | return suspend( | 519 | 1.75k | state::arr2, it, pa); | 520 | 1.02M | if(BOOST_JSON_UNLIKELY( | 521 | 1.02M | ++it == end)) | 522 | 7.57k | break; | 523 | 1.01M | do_arr3: | 524 | 1.01M | if(BOOST_JSON_LIKELY(ss)) | 525 | 1.01M | ss.append(','); | 526 | 102 | else | 527 | 102 | return suspend( | 528 | 102 | state::arr3, it, pa); | 529 | 1.01M | } | 530 | 9.58k | do_arr4: | 531 | 9.58k | if(BOOST_JSON_LIKELY(ss)) | 532 | 9.54k | ss.append(']'); | 533 | 40 | else | 534 | 40 | return suspend( | 535 | 40 | state::arr4, it, pa); | 536 | 9.54k | return true; | 537 | 9.58k | } |
bool boost::json::serializer::write_array<false>(boost::json::detail::stream&) Line | Count | Source | 477 | 5.91k | { | 478 | 5.91k | array const* pa; | 479 | 5.91k | local_stream ss(ss0); | 480 | 5.91k | array::const_iterator it; | 481 | 5.91k | array::const_iterator end; | 482 | 5.91k | if(StackEmpty || st_.empty()) | 483 | 0 | { | 484 | 0 | pa = pa_; | 485 | 0 | it = pa->begin(); | 486 | 0 | end = pa->end(); | 487 | 0 | } | 488 | 5.91k | else | 489 | 5.91k | { | 490 | 5.91k | state st; | 491 | 5.91k | st_.pop(st); | 492 | 5.91k | st_.pop(it); | 493 | 5.91k | st_.pop(pa); | 494 | 5.91k | end = pa->end(); | 495 | 5.91k | switch(st) | 496 | 5.91k | { | 497 | 0 | default: | 498 | 24 | case state::arr1: goto do_arr1; | 499 | 5.64k | case state::arr2: goto do_arr2; | 500 | 192 | case state::arr3: goto do_arr3; | 501 | 55 | case state::arr4: goto do_arr4; | 502 | 0 | break; | 503 | 5.91k | } | 504 | 5.91k | } | 505 | 24 | do_arr1: | 506 | 24 | if(BOOST_JSON_LIKELY(ss)) | 507 | 24 | ss.append('['); | 508 | 0 | else | 509 | 0 | return suspend( | 510 | 0 | state::arr1, it, pa); | 511 | 24 | if(it == end) | 512 | 13 | goto do_arr4; | 513 | 11 | for(;;) | 514 | 5.92M | { | 515 | 5.93M | do_arr2: | 516 | 5.93M | jv_ = &*it; | 517 | 5.93M | if(! write_value<StackEmpty>(ss)) | 518 | 3.89k | return suspend( | 519 | 3.89k | state::arr2, it, pa); | 520 | 5.92M | if(BOOST_JSON_UNLIKELY( | 521 | 5.92M | ++it == end)) | 522 | 1.86k | break; | 523 | 5.92M | do_arr3: | 524 | 5.92M | if(BOOST_JSON_LIKELY(ss)) | 525 | 5.92M | ss.append(','); | 526 | 90 | else | 527 | 90 | return suspend( | 528 | 90 | state::arr3, it, pa); | 529 | 5.92M | } | 530 | 1.93k | do_arr4: | 531 | 1.93k | if(BOOST_JSON_LIKELY(ss)) | 532 | 1.91k | ss.append(']'); | 533 | 15 | else | 534 | 15 | return suspend( | 535 | 15 | state::arr4, it, pa); | 536 | 1.91k | return true; | 537 | 1.93k | } |
|
538 | | |
539 | | template<bool StackEmpty> |
540 | | bool |
541 | | serializer:: |
542 | | write_object(stream& ss0) |
543 | 9.99k | { |
544 | 9.99k | object const* po; |
545 | 9.99k | local_stream ss(ss0); |
546 | 9.99k | object::const_iterator it; |
547 | 9.99k | object::const_iterator end; |
548 | 9.99k | if(StackEmpty || st_.empty()) |
549 | 7.39k | { |
550 | 7.39k | po = po_; |
551 | 7.39k | it = po->begin(); |
552 | 7.39k | end = po->end(); |
553 | 7.39k | } |
554 | 2.60k | else |
555 | 2.60k | { |
556 | 2.60k | state st; |
557 | 2.60k | st_.pop(st); |
558 | 2.60k | st_.pop(it); |
559 | 2.60k | st_.pop(po); |
560 | 2.60k | end = po->end(); |
561 | 2.60k | switch(st) |
562 | 2.60k | { |
563 | 0 | default: |
564 | 18 | case state::obj1: goto do_obj1; |
565 | 446 | case state::obj2: goto do_obj2; |
566 | 21 | case state::obj3: goto do_obj3; |
567 | 2.05k | case state::obj4: goto do_obj4; |
568 | 26 | case state::obj5: goto do_obj5; |
569 | 36 | case state::obj6: goto do_obj6; |
570 | 0 | break; |
571 | 2.60k | } |
572 | 2.60k | } |
573 | 7.40k | do_obj1: |
574 | 7.40k | if(BOOST_JSON_LIKELY(ss)) |
575 | 7.39k | ss.append('{'); |
576 | 18 | else |
577 | 18 | return suspend( |
578 | 18 | state::obj1, it, po); |
579 | 7.39k | if(BOOST_JSON_UNLIKELY( |
580 | 7.39k | it == end)) |
581 | 1.23k | goto do_obj6; |
582 | 6.15k | for(;;) |
583 | 12.2k | { |
584 | 12.2k | cs0_ = { |
585 | 12.2k | it->key().data(), |
586 | 12.2k | it->key().size() }; |
587 | 12.6k | do_obj2: |
588 | 12.6k | if(BOOST_JSON_UNLIKELY( |
589 | 12.6k | ! write_string<StackEmpty>(ss))) |
590 | 446 | return suspend( |
591 | 446 | state::obj2, it, po); |
592 | 12.2k | do_obj3: |
593 | 12.2k | if(BOOST_JSON_LIKELY(ss)) |
594 | 12.2k | ss.append(':'); |
595 | 21 | else |
596 | 21 | return suspend( |
597 | 21 | state::obj3, it, po); |
598 | 14.2k | do_obj4: |
599 | 14.2k | jv_ = &it->value(); |
600 | 14.2k | if(BOOST_JSON_UNLIKELY( |
601 | 14.2k | ! write_value<StackEmpty>(ss))) |
602 | 2.05k | return suspend( |
603 | 2.05k | state::obj4, it, po); |
604 | 12.2k | ++it; |
605 | 12.2k | if(BOOST_JSON_UNLIKELY(it == end)) |
606 | 6.15k | break; |
607 | 6.11k | do_obj5: |
608 | 6.11k | if(BOOST_JSON_LIKELY(ss)) |
609 | 6.08k | ss.append(','); |
610 | 26 | else |
611 | 26 | return suspend( |
612 | 26 | state::obj5, it, po); |
613 | 6.11k | } |
614 | 7.42k | do_obj6: |
615 | 7.42k | if(BOOST_JSON_LIKELY(ss)) |
616 | 7.39k | { |
617 | 7.39k | ss.append('}'); |
618 | 7.39k | return true; |
619 | 7.39k | } |
620 | 36 | return suspend( |
621 | 36 | state::obj6, it, po); |
622 | 7.42k | } bool boost::json::serializer::write_object<true>(boost::json::detail::stream&) Line | Count | Source | 543 | 7.39k | { | 544 | 7.39k | object const* po; | 545 | 7.39k | local_stream ss(ss0); | 546 | 7.39k | object::const_iterator it; | 547 | 7.39k | object::const_iterator end; | 548 | 7.39k | if(StackEmpty || st_.empty()) | 549 | 7.39k | { | 550 | 7.39k | po = po_; | 551 | 7.39k | it = po->begin(); | 552 | 7.39k | end = po->end(); | 553 | 7.39k | } | 554 | 0 | else | 555 | 0 | { | 556 | 0 | state st; | 557 | 0 | st_.pop(st); | 558 | 0 | st_.pop(it); | 559 | 0 | st_.pop(po); | 560 | 0 | end = po->end(); | 561 | 0 | switch(st) | 562 | 0 | { | 563 | 0 | default: | 564 | 0 | case state::obj1: goto do_obj1; | 565 | 0 | case state::obj2: goto do_obj2; | 566 | 0 | case state::obj3: goto do_obj3; | 567 | 0 | case state::obj4: goto do_obj4; | 568 | 0 | case state::obj5: goto do_obj5; | 569 | 0 | case state::obj6: goto do_obj6; | 570 | 0 | break; | 571 | 0 | } | 572 | 0 | } | 573 | 7.39k | do_obj1: | 574 | 7.39k | if(BOOST_JSON_LIKELY(ss)) | 575 | 7.37k | ss.append('{'); | 576 | 18 | else | 577 | 18 | return suspend( | 578 | 18 | state::obj1, it, po); | 579 | 7.37k | if(BOOST_JSON_UNLIKELY( | 580 | 7.37k | it == end)) | 581 | 1.22k | goto do_obj6; | 582 | 6.14k | for(;;) | 583 | 10.1k | { | 584 | 10.1k | cs0_ = { | 585 | 10.1k | it->key().data(), | 586 | 10.1k | it->key().size() }; | 587 | 10.1k | do_obj2: | 588 | 10.1k | if(BOOST_JSON_UNLIKELY( | 589 | 10.1k | ! write_string<StackEmpty>(ss))) | 590 | 143 | return suspend( | 591 | 143 | state::obj2, it, po); | 592 | 10.0k | do_obj3: | 593 | 10.0k | if(BOOST_JSON_LIKELY(ss)) | 594 | 10.0k | ss.append(':'); | 595 | 11 | else | 596 | 11 | return suspend( | 597 | 11 | state::obj3, it, po); | 598 | 10.0k | do_obj4: | 599 | 10.0k | jv_ = &it->value(); | 600 | 10.0k | if(BOOST_JSON_UNLIKELY( | 601 | 10.0k | ! write_value<StackEmpty>(ss))) | 602 | 1.05k | return suspend( | 603 | 1.05k | state::obj4, it, po); | 604 | 8.97k | ++it; | 605 | 8.97k | if(BOOST_JSON_UNLIKELY(it == end)) | 606 | 4.92k | break; | 607 | 4.04k | do_obj5: | 608 | 4.04k | if(BOOST_JSON_LIKELY(ss)) | 609 | 4.03k | ss.append(','); | 610 | 14 | else | 611 | 14 | return suspend( | 612 | 14 | state::obj5, it, po); | 613 | 4.04k | } | 614 | 6.14k | do_obj6: | 615 | 6.14k | if(BOOST_JSON_LIKELY(ss)) | 616 | 6.12k | { | 617 | 6.12k | ss.append('}'); | 618 | 6.12k | return true; | 619 | 6.12k | } | 620 | 23 | return suspend( | 621 | 23 | state::obj6, it, po); | 622 | 6.14k | } |
bool boost::json::serializer::write_object<false>(boost::json::detail::stream&) Line | Count | Source | 543 | 2.60k | { | 544 | 2.60k | object const* po; | 545 | 2.60k | local_stream ss(ss0); | 546 | 2.60k | object::const_iterator it; | 547 | 2.60k | object::const_iterator end; | 548 | 2.60k | if(StackEmpty || st_.empty()) | 549 | 0 | { | 550 | 0 | po = po_; | 551 | 0 | it = po->begin(); | 552 | 0 | end = po->end(); | 553 | 0 | } | 554 | 2.60k | else | 555 | 2.60k | { | 556 | 2.60k | state st; | 557 | 2.60k | st_.pop(st); | 558 | 2.60k | st_.pop(it); | 559 | 2.60k | st_.pop(po); | 560 | 2.60k | end = po->end(); | 561 | 2.60k | switch(st) | 562 | 2.60k | { | 563 | 0 | default: | 564 | 18 | case state::obj1: goto do_obj1; | 565 | 446 | case state::obj2: goto do_obj2; | 566 | 21 | case state::obj3: goto do_obj3; | 567 | 2.05k | case state::obj4: goto do_obj4; | 568 | 26 | case state::obj5: goto do_obj5; | 569 | 36 | case state::obj6: goto do_obj6; | 570 | 0 | break; | 571 | 2.60k | } | 572 | 2.60k | } | 573 | 18 | do_obj1: | 574 | 18 | if(BOOST_JSON_LIKELY(ss)) | 575 | 18 | ss.append('{'); | 576 | 0 | else | 577 | 0 | return suspend( | 578 | 0 | state::obj1, it, po); | 579 | 18 | if(BOOST_JSON_UNLIKELY( | 580 | 18 | it == end)) | 581 | 8 | goto do_obj6; | 582 | 10 | for(;;) | 583 | 2.06k | { | 584 | 2.06k | cs0_ = { | 585 | 2.06k | it->key().data(), | 586 | 2.06k | it->key().size() }; | 587 | 2.50k | do_obj2: | 588 | 2.50k | if(BOOST_JSON_UNLIKELY( | 589 | 2.50k | ! write_string<StackEmpty>(ss))) | 590 | 303 | return suspend( | 591 | 303 | state::obj2, it, po); | 592 | 2.22k | do_obj3: | 593 | 2.22k | if(BOOST_JSON_LIKELY(ss)) | 594 | 2.21k | ss.append(':'); | 595 | 10 | else | 596 | 10 | return suspend( | 597 | 10 | state::obj3, it, po); | 598 | 4.27k | do_obj4: | 599 | 4.27k | jv_ = &it->value(); | 600 | 4.27k | if(BOOST_JSON_UNLIKELY( | 601 | 4.27k | ! write_value<StackEmpty>(ss))) | 602 | 997 | return suspend( | 603 | 997 | state::obj4, it, po); | 604 | 3.27k | ++it; | 605 | 3.27k | if(BOOST_JSON_UNLIKELY(it == end)) | 606 | 1.23k | break; | 607 | 2.06k | do_obj5: | 608 | 2.06k | if(BOOST_JSON_LIKELY(ss)) | 609 | 2.05k | ss.append(','); | 610 | 12 | else | 611 | 12 | return suspend( | 612 | 12 | state::obj5, it, po); | 613 | 2.06k | } | 614 | 1.27k | do_obj6: | 615 | 1.27k | if(BOOST_JSON_LIKELY(ss)) | 616 | 1.26k | { | 617 | 1.26k | ss.append('}'); | 618 | 1.26k | return true; | 619 | 1.26k | } | 620 | 13 | return suspend( | 621 | 13 | state::obj6, it, po); | 622 | 1.27k | } |
|
623 | | |
624 | | template<bool StackEmpty> |
625 | | bool |
626 | | serializer:: |
627 | | write_value(stream& ss) |
628 | 6.97M | { |
629 | 6.97M | if(StackEmpty || st_.empty()) |
630 | 6.96M | { |
631 | 6.96M | auto const& jv(*jv_); |
632 | 6.96M | switch(jv.kind()) |
633 | 6.96M | { |
634 | 0 | default: |
635 | 7.39k | case kind::object: |
636 | 7.39k | po_ = &jv.get_object(); |
637 | 7.39k | return write_object<true>(ss); |
638 | | |
639 | 11.4k | case kind::array: |
640 | 11.4k | pa_ = &jv.get_array(); |
641 | 11.4k | return write_array<true>(ss); |
642 | | |
643 | 20.2k | case kind::string: |
644 | 20.2k | { |
645 | 20.2k | auto const& js = jv.get_string(); |
646 | 20.2k | cs0_ = { js.data(), js.size() }; |
647 | 20.2k | return write_string<true>(ss); |
648 | 0 | } |
649 | | |
650 | 2.14M | case kind::int64: |
651 | 2.16M | case kind::uint64: |
652 | 6.88M | case kind::double_: |
653 | 6.88M | return write_number<true>(ss); |
654 | | |
655 | 28.2k | case kind::bool_: |
656 | 28.2k | if(jv.get_bool()) |
657 | 11.0k | { |
658 | 11.0k | if(BOOST_JSON_LIKELY( |
659 | 11.0k | ss.remain() >= 4)) |
660 | 11.0k | { |
661 | 11.0k | ss.append("true", 4); |
662 | 11.0k | return true; |
663 | 11.0k | } |
664 | 61 | return write_true<true>(ss); |
665 | 11.0k | } |
666 | 17.1k | else |
667 | 17.1k | { |
668 | 17.1k | if(BOOST_JSON_LIKELY( |
669 | 17.1k | ss.remain() >= 5)) |
670 | 17.1k | { |
671 | 17.1k | ss.append("false", 5); |
672 | 17.1k | return true; |
673 | 17.1k | } |
674 | 71 | return write_false<true>(ss); |
675 | 17.1k | } |
676 | | |
677 | 15.1k | case kind::null: |
678 | 15.1k | if(BOOST_JSON_LIKELY( |
679 | 15.1k | ss.remain() >= 4)) |
680 | 15.1k | { |
681 | 15.1k | ss.append("null", 4); |
682 | 15.1k | return true; |
683 | 15.1k | } |
684 | 68 | return write_null<true>(ss); |
685 | 6.96M | } |
686 | 6.96M | } |
687 | 10.2k | else |
688 | 10.2k | { |
689 | 10.2k | state st; |
690 | 10.2k | st_.peek(st); |
691 | 10.2k | switch(st) |
692 | 10.2k | { |
693 | 0 | default: |
694 | 29 | case state::nul1: case state::nul2: |
695 | 68 | case state::nul3: case state::nul4: |
696 | 68 | return write_null<StackEmpty>(ss); |
697 | | |
698 | 30 | case state::tru1: case state::tru2: |
699 | 61 | case state::tru3: case state::tru4: |
700 | 61 | return write_true<StackEmpty>(ss); |
701 | | |
702 | 27 | case state::fal1: case state::fal2: |
703 | 56 | case state::fal3: case state::fal4: |
704 | 71 | case state::fal5: |
705 | 71 | return write_false<StackEmpty>(ss); |
706 | | |
707 | 50 | case state::str1: case state::str2: |
708 | 420 | case state::str3: case state::str4: |
709 | 439 | case state::esc1: |
710 | 479 | case state::utf1: case state::utf2: |
711 | 516 | case state::utf3: case state::utf4: |
712 | 533 | case state::utf5: |
713 | 533 | return write_string<StackEmpty>(ss); |
714 | | |
715 | 987 | case state::num: |
716 | 987 | return write_number<StackEmpty>(ss); |
717 | | |
718 | 5.67k | case state::arr1: case state::arr2: |
719 | 5.91k | case state::arr3: case state::arr4: |
720 | 5.91k | return write_array<StackEmpty>(ss); |
721 | | |
722 | 464 | case state::obj1: case state::obj2: |
723 | 2.53k | case state::obj3: case state::obj4: |
724 | 2.60k | case state::obj5: case state::obj6: |
725 | 2.60k | return write_object<StackEmpty>(ss); |
726 | 10.2k | } |
727 | 10.2k | } |
728 | 6.97M | } bool boost::json::serializer::write_value<true>(boost::json::detail::stream&) Line | Count | Source | 628 | 1.03M | { | 629 | 1.03M | if(StackEmpty || st_.empty()) | 630 | 1.03M | { | 631 | 1.03M | auto const& jv(*jv_); | 632 | 1.03M | switch(jv.kind()) | 633 | 1.03M | { | 634 | 0 | default: | 635 | 6.10k | case kind::object: | 636 | 6.10k | po_ = &jv.get_object(); | 637 | 6.10k | return write_object<true>(ss); | 638 | | | 639 | 6.26k | case kind::array: | 640 | 6.26k | pa_ = &jv.get_array(); | 641 | 6.26k | return write_array<true>(ss); | 642 | | | 643 | 10.3k | case kind::string: | 644 | 10.3k | { | 645 | 10.3k | auto const& js = jv.get_string(); | 646 | 10.3k | cs0_ = { js.data(), js.size() }; | 647 | 10.3k | return write_string<true>(ss); | 648 | 0 | } | 649 | | | 650 | 169k | case kind::int64: | 651 | 184k | case kind::uint64: | 652 | 980k | case kind::double_: | 653 | 980k | return write_number<true>(ss); | 654 | | | 655 | 24.6k | case kind::bool_: | 656 | 24.6k | if(jv.get_bool()) | 657 | 9.16k | { | 658 | 9.16k | if(BOOST_JSON_LIKELY( | 659 | 9.16k | ss.remain() >= 4)) | 660 | 9.13k | { | 661 | 9.13k | ss.append("true", 4); | 662 | 9.13k | return true; | 663 | 9.13k | } | 664 | 25 | return write_true<true>(ss); | 665 | 9.16k | } | 666 | 15.5k | else | 667 | 15.5k | { | 668 | 15.5k | if(BOOST_JSON_LIKELY( | 669 | 15.5k | ss.remain() >= 5)) | 670 | 15.4k | { | 671 | 15.4k | ss.append("false", 5); | 672 | 15.4k | return true; | 673 | 15.4k | } | 674 | 61 | return write_false<true>(ss); | 675 | 15.5k | } | 676 | | | 677 | 9.48k | case kind::null: | 678 | 9.48k | if(BOOST_JSON_LIKELY( | 679 | 9.48k | ss.remain() >= 4)) | 680 | 9.45k | { | 681 | 9.45k | ss.append("null", 4); | 682 | 9.45k | return true; | 683 | 9.45k | } | 684 | 32 | return write_null<true>(ss); | 685 | 1.03M | } | 686 | 1.03M | } | 687 | 0 | else | 688 | 0 | { | 689 | 0 | state st; | 690 | 0 | st_.peek(st); | 691 | 0 | switch(st) | 692 | 0 | { | 693 | 0 | default: | 694 | 0 | case state::nul1: case state::nul2: | 695 | 0 | case state::nul3: case state::nul4: | 696 | 0 | return write_null<StackEmpty>(ss); | 697 | | | 698 | 0 | case state::tru1: case state::tru2: | 699 | 0 | case state::tru3: case state::tru4: | 700 | 0 | return write_true<StackEmpty>(ss); | 701 | | | 702 | 0 | case state::fal1: case state::fal2: | 703 | 0 | case state::fal3: case state::fal4: | 704 | 0 | case state::fal5: | 705 | 0 | return write_false<StackEmpty>(ss); | 706 | | | 707 | 0 | case state::str1: case state::str2: | 708 | 0 | case state::str3: case state::str4: | 709 | 0 | case state::esc1: | 710 | 0 | case state::utf1: case state::utf2: | 711 | 0 | case state::utf3: case state::utf4: | 712 | 0 | case state::utf5: | 713 | 0 | return write_string<StackEmpty>(ss); | 714 | | | 715 | 0 | case state::num: | 716 | 0 | return write_number<StackEmpty>(ss); | 717 | | | 718 | 0 | case state::arr1: case state::arr2: | 719 | 0 | case state::arr3: case state::arr4: | 720 | 0 | return write_array<StackEmpty>(ss); | 721 | | | 722 | 0 | case state::obj1: case state::obj2: | 723 | 0 | case state::obj3: case state::obj4: | 724 | 0 | case state::obj5: case state::obj6: | 725 | 0 | return write_object<StackEmpty>(ss); | 726 | 0 | } | 727 | 0 | } | 728 | 1.03M | } |
bool boost::json::serializer::write_value<false>(boost::json::detail::stream&) Line | Count | Source | 628 | 5.93M | { | 629 | 5.93M | if(StackEmpty || st_.empty()) | 630 | 5.92M | { | 631 | 5.92M | auto const& jv(*jv_); | 632 | 5.92M | switch(jv.kind()) | 633 | 5.92M | { | 634 | 0 | default: | 635 | 1.28k | case kind::object: | 636 | 1.28k | po_ = &jv.get_object(); | 637 | 1.28k | return write_object<true>(ss); | 638 | | | 639 | 5.19k | case kind::array: | 640 | 5.19k | pa_ = &jv.get_array(); | 641 | 5.19k | return write_array<true>(ss); | 642 | | | 643 | 9.84k | case kind::string: | 644 | 9.84k | { | 645 | 9.84k | auto const& js = jv.get_string(); | 646 | 9.84k | cs0_ = { js.data(), js.size() }; | 647 | 9.84k | return write_string<true>(ss); | 648 | 0 | } | 649 | | | 650 | 1.97M | case kind::int64: | 651 | 1.97M | case kind::uint64: | 652 | 5.90M | case kind::double_: | 653 | 5.90M | return write_number<true>(ss); | 654 | | | 655 | 3.59k | case kind::bool_: | 656 | 3.59k | if(jv.get_bool()) | 657 | 1.93k | { | 658 | 1.93k | if(BOOST_JSON_LIKELY( | 659 | 1.93k | ss.remain() >= 4)) | 660 | 1.89k | { | 661 | 1.89k | ss.append("true", 4); | 662 | 1.89k | return true; | 663 | 1.89k | } | 664 | 36 | return write_true<true>(ss); | 665 | 1.93k | } | 666 | 1.66k | else | 667 | 1.66k | { | 668 | 1.66k | if(BOOST_JSON_LIKELY( | 669 | 1.66k | ss.remain() >= 5)) | 670 | 1.65k | { | 671 | 1.65k | ss.append("false", 5); | 672 | 1.65k | return true; | 673 | 1.65k | } | 674 | 10 | return write_false<true>(ss); | 675 | 1.66k | } | 676 | | | 677 | 5.69k | case kind::null: | 678 | 5.69k | if(BOOST_JSON_LIKELY( | 679 | 5.69k | ss.remain() >= 4)) | 680 | 5.65k | { | 681 | 5.65k | ss.append("null", 4); | 682 | 5.65k | return true; | 683 | 5.65k | } | 684 | 36 | return write_null<true>(ss); | 685 | 5.92M | } | 686 | 5.92M | } | 687 | 10.2k | else | 688 | 10.2k | { | 689 | 10.2k | state st; | 690 | 10.2k | st_.peek(st); | 691 | 10.2k | switch(st) | 692 | 10.2k | { | 693 | 0 | default: | 694 | 29 | case state::nul1: case state::nul2: | 695 | 68 | case state::nul3: case state::nul4: | 696 | 68 | return write_null<StackEmpty>(ss); | 697 | | | 698 | 30 | case state::tru1: case state::tru2: | 699 | 61 | case state::tru3: case state::tru4: | 700 | 61 | return write_true<StackEmpty>(ss); | 701 | | | 702 | 27 | case state::fal1: case state::fal2: | 703 | 56 | case state::fal3: case state::fal4: | 704 | 71 | case state::fal5: | 705 | 71 | return write_false<StackEmpty>(ss); | 706 | | | 707 | 50 | case state::str1: case state::str2: | 708 | 420 | case state::str3: case state::str4: | 709 | 439 | case state::esc1: | 710 | 479 | case state::utf1: case state::utf2: | 711 | 516 | case state::utf3: case state::utf4: | 712 | 533 | case state::utf5: | 713 | 533 | return write_string<StackEmpty>(ss); | 714 | | | 715 | 987 | case state::num: | 716 | 987 | return write_number<StackEmpty>(ss); | 717 | | | 718 | 5.67k | case state::arr1: case state::arr2: | 719 | 5.91k | case state::arr3: case state::arr4: | 720 | 5.91k | return write_array<StackEmpty>(ss); | 721 | | | 722 | 464 | case state::obj1: case state::obj2: | 723 | 2.53k | case state::obj3: case state::obj4: | 724 | 2.60k | case state::obj5: case state::obj6: | 725 | 2.60k | return write_object<StackEmpty>(ss); | 726 | 10.2k | } | 727 | 10.2k | } | 728 | 5.93M | } |
|
729 | | |
730 | | string_view |
731 | | serializer:: |
732 | | read_some( |
733 | | char* dest, std::size_t size) |
734 | 7.08k | { |
735 | | // If this goes off it means you forgot |
736 | | // to call reset() before seriailzing a |
737 | | // new value, or you never checked done() |
738 | | // to see if you should stop. |
739 | 7.08k | BOOST_ASSERT(! done_); |
740 | | |
741 | 7.08k | stream ss(dest, size); |
742 | 7.08k | if(st_.empty()) |
743 | 4.55k | (this->*fn0_)(ss); |
744 | 2.53k | else |
745 | 2.53k | (this->*fn1_)(ss); |
746 | 7.08k | if(st_.empty()) |
747 | 4.55k | { |
748 | 4.55k | done_ = true; |
749 | 4.55k | jv_ = nullptr; |
750 | 4.55k | } |
751 | 7.08k | return string_view( |
752 | 7.08k | dest, ss.used(dest)); |
753 | 7.08k | } |
754 | | |
755 | | //---------------------------------------------------------- |
756 | | |
757 | | serializer:: |
758 | | serializer( serialize_options const& opts ) noexcept |
759 | | : opts_(opts) |
760 | 0 | { |
761 | | // ensure room for \uXXXX escape plus one |
762 | 0 | BOOST_STATIC_ASSERT( |
763 | 0 | sizeof(serializer::buf_) >= 7); |
764 | 0 | } |
765 | | |
766 | | void |
767 | | serializer:: |
768 | | reset(value const* p) noexcept |
769 | 4.55k | { |
770 | 4.55k | pv_ = p; |
771 | 4.55k | fn0_ = &serializer::write_value<true>; |
772 | 4.55k | fn1_ = &serializer::write_value<false>; |
773 | | |
774 | 4.55k | jv_ = p; |
775 | 4.55k | st_.clear(); |
776 | 4.55k | done_ = false; |
777 | 4.55k | } |
778 | | |
779 | | void |
780 | | serializer:: |
781 | | reset(array const* p) noexcept |
782 | 0 | { |
783 | 0 | pa_ = p; |
784 | 0 | fn0_ = &serializer::write_array<true>; |
785 | 0 | fn1_ = &serializer::write_array<false>; |
786 | 0 | st_.clear(); |
787 | 0 | done_ = false; |
788 | 0 | } |
789 | | |
790 | | void |
791 | | serializer:: |
792 | | reset(object const* p) noexcept |
793 | 0 | { |
794 | 0 | po_ = p; |
795 | 0 | fn0_ = &serializer::write_object<true>; |
796 | 0 | fn1_ = &serializer::write_object<false>; |
797 | 0 | st_.clear(); |
798 | 0 | done_ = false; |
799 | 0 | } |
800 | | |
801 | | void |
802 | | serializer:: |
803 | | reset(string const* p) noexcept |
804 | 0 | { |
805 | 0 | cs0_ = { p->data(), p->size() }; |
806 | 0 | fn0_ = &serializer::write_string<true>; |
807 | 0 | fn1_ = &serializer::write_string<false>; |
808 | 0 | st_.clear(); |
809 | 0 | done_ = false; |
810 | 0 | } |
811 | | |
812 | | void |
813 | | serializer:: |
814 | | reset(string_view sv) noexcept |
815 | 0 | { |
816 | 0 | cs0_ = { sv.data(), sv.size() }; |
817 | 0 | fn0_ = &serializer::write_string<true>; |
818 | 0 | fn1_ = &serializer::write_string<false>; |
819 | 0 | st_.clear(); |
820 | 0 | done_ = false; |
821 | 0 | } |
822 | | |
823 | | string_view |
824 | | serializer:: |
825 | | read(char* dest, std::size_t size) |
826 | 7.08k | { |
827 | 7.08k | if(! jv_) |
828 | 0 | { |
829 | 0 | static value const null; |
830 | 0 | jv_ = &null; |
831 | 0 | } |
832 | 7.08k | return read_some(dest, size); |
833 | 7.08k | } |
834 | | |
835 | | } // namespace json |
836 | | } // namespace boost |
837 | | |
838 | | #ifdef _MSC_VER |
839 | | #pragma warning(pop) |
840 | | #endif |
841 | | |
842 | | #endif |