| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | ||
| 3 | // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) | ||
| 4 | // | ||
| 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| 7 | // | ||
| 8 | // Official repository: https://github.com/boostorg/json | ||
| 9 | // | ||
| 10 | |||
| 11 | #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP | ||
| 12 | #define BOOST_JSON_BASIC_PARSER_IMPL_HPP | ||
| 13 | |||
| 14 | #include <boost/json/detail/config.hpp> | ||
| 15 | #include <boost/json/detail/literals.hpp> | ||
| 16 | #include <boost/json/basic_parser.hpp> | ||
| 17 | #include <boost/json/error.hpp> | ||
| 18 | #include <boost/json/detail/buffer.hpp> | ||
| 19 | #include <boost/json/detail/charconv/from_chars.hpp> | ||
| 20 | #include <boost/json/detail/sse2.hpp> | ||
| 21 | #include <boost/mp11/algorithm.hpp> | ||
| 22 | #include <boost/mp11/integral.hpp> | ||
| 23 | #include <cmath> | ||
| 24 | #include <limits> | ||
| 25 | #include <cstring> | ||
| 26 | |||
| 27 | #ifdef _MSC_VER | ||
| 28 | #pragma warning(push) | ||
| 29 | #pragma warning(disable: 4702) // unreachable code | ||
| 30 | #pragma warning(disable: 4127) // conditional expression is constant | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /* This file must be manually included to get the | ||
| 34 | function template definitions for basic_parser. | ||
| 35 | */ | ||
| 36 | |||
| 37 | /* Reference: | ||
| 38 | |||
| 39 | https://www.json.org/ | ||
| 40 | |||
| 41 | RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format | ||
| 42 | https://tools.ietf.org/html/rfc7159 | ||
| 43 | |||
| 44 | https://ampl.com/netlib/fp/dtoa.c | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef BOOST_JSON_DOCS | ||
| 48 | |||
| 49 | namespace boost { | ||
| 50 | namespace json { | ||
| 51 | namespace detail { | ||
| 52 | |||
| 53 | inline | ||
| 54 | double | ||
| 55 | 1033693 | pow10(int exp) noexcept | |
| 56 | { | ||
| 57 | static double const tab[618] = { | ||
| 58 | 1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, | ||
| 59 | |||
| 60 | 1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, | ||
| 61 | 1e-290, 1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, | ||
| 62 | 1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271, | ||
| 63 | 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261, | ||
| 64 | 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, 1e-252, 1e-251, | ||
| 65 | 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241, | ||
| 66 | 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231, | ||
| 67 | 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222, 1e-221, | ||
| 68 | 1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, | ||
| 69 | 1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, | ||
| 70 | |||
| 71 | 1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, | ||
| 72 | 1e-190, 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, | ||
| 73 | 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171, | ||
| 74 | 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161, | ||
| 75 | 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, 1e-153, 1e-152, 1e-151, | ||
| 76 | 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141, | ||
| 77 | 1e-140, 1e-139, 1e-138, 1e-137, 1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, | ||
| 78 | 1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, | ||
| 79 | 1e-120, 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, | ||
| 80 | 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, | ||
| 81 | |||
| 82 | 1e-100, 1e-099, 1e-098, 1e-097, 1e-096, 1e-095, 1e-094, 1e-093, 1e-092, 1e-091, | ||
| 83 | 1e-090, 1e-089, 1e-088, 1e-087, 1e-086, 1e-085, 1e-084, 1e-083, 1e-082, 1e-081, | ||
| 84 | 1e-080, 1e-079, 1e-078, 1e-077, 1e-076, 1e-075, 1e-074, 1e-073, 1e-072, 1e-071, | ||
| 85 | 1e-070, 1e-069, 1e-068, 1e-067, 1e-066, 1e-065, 1e-064, 1e-063, 1e-062, 1e-061, | ||
| 86 | 1e-060, 1e-059, 1e-058, 1e-057, 1e-056, 1e-055, 1e-054, 1e-053, 1e-052, 1e-051, | ||
| 87 | 1e-050, 1e-049, 1e-048, 1e-047, 1e-046, 1e-045, 1e-044, 1e-043, 1e-042, 1e-041, | ||
| 88 | 1e-040, 1e-039, 1e-038, 1e-037, 1e-036, 1e-035, 1e-034, 1e-033, 1e-032, 1e-031, | ||
| 89 | 1e-030, 1e-029, 1e-028, 1e-027, 1e-026, 1e-025, 1e-024, 1e-023, 1e-022, 1e-021, | ||
| 90 | 1e-020, 1e-019, 1e-018, 1e-017, 1e-016, 1e-015, 1e-014, 1e-013, 1e-012, 1e-011, | ||
| 91 | 1e-010, 1e-009, 1e-008, 1e-007, 1e-006, 1e-005, 1e-004, 1e-003, 1e-002, 1e-001, | ||
| 92 | |||
| 93 | 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, | ||
| 94 | 1e+010, 1e+011, 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, | ||
| 95 | 1e+020, 1e+021, 1e+022, 1e+023, 1e+024, 1e+025, 1e+026, 1e+027, 1e+028, 1e+029, | ||
| 96 | 1e+030, 1e+031, 1e+032, 1e+033, 1e+034, 1e+035, 1e+036, 1e+037, 1e+038, 1e+039, | ||
| 97 | 1e+040, 1e+041, 1e+042, 1e+043, 1e+044, 1e+045, 1e+046, 1e+047, 1e+048, 1e+049, | ||
| 98 | 1e+050, 1e+051, 1e+052, 1e+053, 1e+054, 1e+055, 1e+056, 1e+057, 1e+058, 1e+059, | ||
| 99 | 1e+060, 1e+061, 1e+062, 1e+063, 1e+064, 1e+065, 1e+066, 1e+067, 1e+068, 1e+069, | ||
| 100 | 1e+070, 1e+071, 1e+072, 1e+073, 1e+074, 1e+075, 1e+076, 1e+077, 1e+078, 1e+079, | ||
| 101 | 1e+080, 1e+081, 1e+082, 1e+083, 1e+084, 1e+085, 1e+086, 1e+087, 1e+088, 1e+089, | ||
| 102 | 1e+090, 1e+091, 1e+092, 1e+093, 1e+094, 1e+095, 1e+096, 1e+097, 1e+098, 1e+099, | ||
| 103 | |||
| 104 | 1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, | ||
| 105 | 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118, 1e+119, | ||
| 106 | 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129, | ||
| 107 | 1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135, 1e+136, 1e+137, 1e+138, 1e+139, | ||
| 108 | 1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, | ||
| 109 | 1e+150, 1e+151, 1e+152, 1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, | ||
| 110 | 1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169, | ||
| 111 | 1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179, | ||
| 112 | 1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188, 1e+189, | ||
| 113 | 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199, | ||
| 114 | |||
| 115 | 1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209, | ||
| 116 | 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219, | ||
| 117 | 1e+220, 1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229, | ||
| 118 | 1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239, | ||
| 119 | 1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, | ||
| 120 | 1e+250, 1e+251, 1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259, | ||
| 121 | 1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269, | ||
| 122 | 1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279, | ||
| 123 | 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288, 1e+289, | ||
| 124 | 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299, | ||
| 125 | |||
| 126 | 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 }; | ||
| 127 | |||
| 128 |
2/2✓ Branch 0 taken 341 times.
✓ Branch 1 taken 1033352 times.
|
1033693 | if( exp > 308 ) |
| 129 | { | ||
| 130 | 341 | return std::numeric_limits<double>::infinity(); | |
| 131 | } | ||
| 132 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 1033201 times.
|
1033352 | else if( exp < -308 ) |
| 133 | { | ||
| 134 | // due to the way pow10 is used by dec_to_float, | ||
| 135 | // we can afford to return 0.0 here | ||
| 136 | 151 | return 0.0; | |
| 137 | } | ||
| 138 | else | ||
| 139 | { | ||
| 140 | 1033201 | exp += 308; | |
| 141 |
2/4✓ Branch 0 taken 1033201 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1033201 times.
✗ Branch 3 not taken.
|
1033201 | BOOST_ASSERT(exp >= 0 && exp < 618); |
| 142 | 1033201 | return tab[exp]; | |
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | inline | ||
| 147 | double | ||
| 148 | 1033693 | dec_to_float( | |
| 149 | std::uint64_t m, | ||
| 150 | std::int32_t e, | ||
| 151 | bool neg) noexcept | ||
| 152 | { | ||
| 153 | // convert to double explicitly to silence warnings | ||
| 154 | 1033693 | double x = static_cast<double>(m); | |
| 155 |
2/2✓ Branch 0 taken 13164 times.
✓ Branch 1 taken 1020529 times.
|
1033693 | if(neg) |
| 156 | 13164 | x = -x; | |
| 157 | |||
| 158 |
2/2✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 1028506 times.
|
1033693 | if(e < -305) |
| 159 | { | ||
| 160 | 5187 | x *= 1e-305 ; | |
| 161 | 5187 | e += 305; | |
| 162 | } | ||
| 163 | |||
| 164 |
4/4✓ Branch 0 taken 574295 times.
✓ Branch 1 taken 459398 times.
✓ Branch 2 taken 54813 times.
✓ Branch 3 taken 519482 times.
|
1033693 | if(e >= -22 && e < 0) |
| 165 | 54813 | return x / pow10(-e); | |
| 166 | |||
| 167 | 978880 | return x * pow10(e); | |
| 168 | } | ||
| 169 | |||
| 170 | inline | ||
| 171 | bool | ||
| 172 | is_control(char c) noexcept | ||
| 173 | { | ||
| 174 | return static_cast<unsigned char>(c) < 32; | ||
| 175 | } | ||
| 176 | |||
| 177 | inline | ||
| 178 | int | ||
| 179 | 66931 | hex_digit(unsigned char c) noexcept | |
| 180 | { | ||
| 181 | // by Peter Dimov | ||
| 182 |
4/4✓ Branch 0 taken 66396 times.
✓ Branch 1 taken 535 times.
✓ Branch 2 taken 35759 times.
✓ Branch 3 taken 30637 times.
|
66931 | if( c >= '0' && c <= '9' ) |
| 183 | 35759 | return c - '0'; | |
| 184 | 31172 | c &= ~0x20; | |
| 185 |
4/4✓ Branch 0 taken 30637 times.
✓ Branch 1 taken 535 times.
✓ Branch 2 taken 30562 times.
✓ Branch 3 taken 75 times.
|
31172 | if( c >= 'A' && c <= 'F' ) |
| 186 | 30562 | return 10 + c - 'A'; | |
| 187 | 610 | return -1; | |
| 188 | } | ||
| 189 | |||
| 190 | } // detail | ||
| 191 | |||
| 192 | //---------------------------------------------------------- | ||
| 193 | |||
| 194 | template< class Handler > | ||
| 195 | template< bool StackEmpty_, char First_ > | ||
| 196 | struct basic_parser<Handler>:: | ||
| 197 | parse_number_helper | ||
| 198 | { | ||
| 199 | basic_parser* parser; | ||
| 200 | char const* p; | ||
| 201 | |||
| 202 | template< std::size_t N > | ||
| 203 | char const* | ||
| 204 | 4253742 | operator()( mp11::mp_size_t<N> ) const | |
| 205 | { | ||
| 206 | 8496602 | return parser->parse_number( | |
| 207 | 4253742 | p, | |
| 208 | std::integral_constant<bool, StackEmpty_>(), | ||
| 209 | std::integral_constant<char, First_>(), | ||
| 210 | std::integral_constant< | ||
| 211 | 4242862 | number_precision, static_cast<number_precision>(N)>() ); | |
| 212 | } | ||
| 213 | }; | ||
| 214 | |||
| 215 | //---------------------------------------------------------- | ||
| 216 | |||
| 217 | template<class Handler> | ||
| 218 | void | ||
| 219 | 274180 | basic_parser<Handler>:: | |
| 220 | reserve() | ||
| 221 | { | ||
| 222 |
2/2✓ Branch 1 taken 37444 times.
✓ Branch 2 taken 173075 times.
|
274180 | if(BOOST_JSON_LIKELY( |
| 223 | ! st_.empty())) | ||
| 224 | 58286 | return; | |
| 225 | // Reserve the largest stack we need, | ||
| 226 | // to avoid reallocation during suspend. | ||
| 227 | 431788 | st_.reserve( | |
| 228 | sizeof(state) + // document parsing state | ||
| 229 | (sizeof(state) + | ||
| 230 | 215894 | sizeof(std::size_t)) * depth() + // array and object state + size | |
| 231 | sizeof(state) + // value parsing state | ||
| 232 | sizeof(std::size_t) + // string size | ||
| 233 | sizeof(state)); // comment state | ||
| 234 | } | ||
| 235 | |||
| 236 | //---------------------------------------------------------- | ||
| 237 | // | ||
| 238 | // The sentinel value is returned by parse functions | ||
| 239 | // to indicate that the parser failed, or suspended. | ||
| 240 | // this is used as it is distinct from all valid values | ||
| 241 | // for data in write | ||
| 242 | |||
| 243 | template<class Handler> | ||
| 244 | const char* | ||
| 245 | 5925259 | basic_parser<Handler>:: | |
| 246 | sentinel() | ||
| 247 | { | ||
| 248 | // the "+1" ensures that the returned pointer is unique even if | ||
| 249 | // the given input buffer borders on this object | ||
| 250 | return reinterpret_cast< | ||
| 251 | 5925259 | const char*>(this) + 1; | |
| 252 | } | ||
| 253 | |||
| 254 | template<class Handler> | ||
| 255 | bool | ||
| 256 | 2696259 | basic_parser<Handler>:: | |
| 257 | incomplete( | ||
| 258 | const detail::const_stream_wrapper& cs) | ||
| 259 | { | ||
| 260 | 2696259 | return cs.begin() == sentinel(); | |
| 261 | } | ||
| 262 | |||
| 263 | //---------------------------------------------------------- | ||
| 264 | // | ||
| 265 | // These functions are declared with the BOOST_NOINLINE | ||
| 266 | // attribute to avoid polluting the parsers hot-path. | ||
| 267 | // They return the canary value to indicate suspension | ||
| 268 | // or failure. | ||
| 269 | |||
| 270 | template<class Handler> | ||
| 271 | const char* | ||
| 272 | basic_parser<Handler>:: | ||
| 273 | suspend_or_fail(state st) | ||
| 274 | { | ||
| 275 | if(BOOST_JSON_LIKELY( | ||
| 276 | ! ec_ && more_)) | ||
| 277 | { | ||
| 278 | // suspend | ||
| 279 | reserve(); | ||
| 280 | st_.push_unchecked(st); | ||
| 281 | } | ||
| 282 | return sentinel(); | ||
| 283 | } | ||
| 284 | |||
| 285 | template<class Handler> | ||
| 286 | const char* | ||
| 287 | 95727 | basic_parser<Handler>:: | |
| 288 | suspend_or_fail( | ||
| 289 | state st, | ||
| 290 | std::size_t n) | ||
| 291 | { | ||
| 292 |
6/6✓ Branch 1 taken 36033 times.
✓ Branch 2 taken 20117 times.
✓ Branch 3 taken 35836 times.
✓ Branch 4 taken 197 times.
✓ Branch 5 taken 35836 times.
✓ Branch 6 taken 20314 times.
|
95727 | if(BOOST_JSON_LIKELY( |
| 293 | ! ec_ && more_)) | ||
| 294 | { | ||
| 295 | // suspend | ||
| 296 | 55109 | reserve(); | |
| 297 | 55109 | st_.push_unchecked(n); | |
| 298 | 55109 | st_.push_unchecked(st); | |
| 299 | } | ||
| 300 | 95727 | return sentinel(); | |
| 301 | } | ||
| 302 | |||
| 303 | |||
| 304 | template<class Handler> | ||
| 305 | const char* | ||
| 306 | 38010 | basic_parser<Handler>:: | |
| 307 | fail(const char* p) noexcept | ||
| 308 | { | ||
| 309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 19005 times.
|
38010 | BOOST_ASSERT( p != sentinel() ); |
| 310 | 38010 | end_ = p; | |
| 311 | 38010 | return sentinel(); | |
| 312 | } | ||
| 313 | |||
| 314 | template<class Handler> | ||
| 315 | const char* | ||
| 316 | 15522 | basic_parser<Handler>:: | |
| 317 | fail( | ||
| 318 | const char* p, | ||
| 319 | error ev, | ||
| 320 | source_location const* loc) noexcept | ||
| 321 | { | ||
| 322 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7772 times.
|
15522 | BOOST_ASSERT( p != sentinel() ); |
| 323 | 15522 | end_ = p; | |
| 324 | 15522 | ec_.assign(ev, loc); | |
| 325 | 15522 | return sentinel(); | |
| 326 | } | ||
| 327 | |||
| 328 | template<class Handler> | ||
| 329 | const char* | ||
| 330 | 22107 | basic_parser<Handler>:: | |
| 331 | maybe_suspend( | ||
| 332 | const char* p, | ||
| 333 | state st) | ||
| 334 | { | ||
| 335 |
2/2✓ Branch 1 taken 9424 times.
✓ Branch 2 taken 1865 times.
|
22107 | if( p != sentinel() ) |
| 336 | 18416 | end_ = p; | |
| 337 |
2/2✓ Branch 0 taken 11027 times.
✓ Branch 1 taken 262 times.
|
22107 | if(BOOST_JSON_LIKELY(more_)) |
| 338 | { | ||
| 339 | // suspend | ||
| 340 | 21602 | reserve(); | |
| 341 | 21602 | st_.push_unchecked(st); | |
| 342 | } | ||
| 343 | 22107 | return sentinel(); | |
| 344 | } | ||
| 345 | |||
| 346 | template<class Handler> | ||
| 347 | const char* | ||
| 348 | 59318 | basic_parser<Handler>:: | |
| 349 | maybe_suspend( | ||
| 350 | const char* p, | ||
| 351 | state st, | ||
| 352 | std::size_t n) | ||
| 353 | { | ||
| 354 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 38223 times.
|
59318 | BOOST_ASSERT( p != sentinel() ); |
| 355 | 59318 | end_ = p; | |
| 356 |
2/2✓ Branch 0 taken 37823 times.
✓ Branch 1 taken 400 times.
|
59318 | if(BOOST_JSON_LIKELY(more_)) |
| 357 | { | ||
| 358 | // suspend | ||
| 359 | 58524 | reserve(); | |
| 360 | 58524 | st_.push_unchecked(n); | |
| 361 | 58524 | st_.push_unchecked(st); | |
| 362 | } | ||
| 363 | 59318 | return sentinel(); | |
| 364 | } | ||
| 365 | |||
| 366 | template<class Handler> | ||
| 367 | const char* | ||
| 368 | 1736 | basic_parser<Handler>:: | |
| 369 | maybe_suspend( | ||
| 370 | const char* p, | ||
| 371 | state st, | ||
| 372 | const number& num) | ||
| 373 | { | ||
| 374 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1123 times.
|
1736 | BOOST_ASSERT( p != sentinel() ); |
| 375 | 1736 | end_ = p; | |
| 376 |
1/2✓ Branch 0 taken 1123 times.
✗ Branch 1 not taken.
|
1736 | if(BOOST_JSON_LIKELY(more_)) |
| 377 | { | ||
| 378 | // suspend | ||
| 379 | 1736 | num_ = num; | |
| 380 | 1736 | reserve(); | |
| 381 | 1736 | st_.push_unchecked(st);; | |
| 382 | } | ||
| 383 | 1736 | return sentinel(); | |
| 384 | } | ||
| 385 | |||
| 386 | template<class Handler> | ||
| 387 | const char* | ||
| 388 | 95505 | basic_parser<Handler>:: | |
| 389 | suspend( | ||
| 390 | const char* p, | ||
| 391 | state st) | ||
| 392 | { | ||
| 393 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 88656 times.
|
95505 | BOOST_ASSERT( p != sentinel() ); |
| 394 | 95505 | end_ = p; | |
| 395 | // suspend | ||
| 396 | 95505 | reserve(); | |
| 397 | 95505 | st_.push_unchecked(st); | |
| 398 | 95505 | return sentinel(); | |
| 399 | } | ||
| 400 | |||
| 401 | template<class Handler> | ||
| 402 | const char* | ||
| 403 | 41704 | basic_parser<Handler>:: | |
| 404 | suspend( | ||
| 405 | const char* p, | ||
| 406 | state st, | ||
| 407 | const number& num) | ||
| 408 | { | ||
| 409 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36054 times.
|
41704 | BOOST_ASSERT( p != sentinel() ); |
| 410 | 41704 | end_ = p; | |
| 411 | // suspend | ||
| 412 | 41704 | num_ = num; | |
| 413 | 41704 | reserve(); | |
| 414 | 41704 | st_.push_unchecked(st); | |
| 415 | 41704 | return sentinel(); | |
| 416 | } | ||
| 417 | |||
| 418 | template<class Handler> | ||
| 419 | template< | ||
| 420 | bool StackEmpty_/*, | ||
| 421 | bool Terminal_*/> | ||
| 422 | const char* | ||
| 423 | 43474 | basic_parser<Handler>:: | |
| 424 | parse_comment(const char* p, | ||
| 425 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 426 | /*std::integral_constant<bool, Terminal_>*/ bool terminal) | ||
| 427 | { | ||
| 428 | 43474 | detail::const_stream_wrapper cs(p, end_); | |
| 429 | 43474 | const char* start = cs.begin(); | |
| 430 | std::size_t remain; | ||
| 431 |
6/6✓ Branch 1 taken 7921 times.
✓ Branch 2 taken 13816 times.
✓ Branch 4 taken 3507 times.
✓ Branch 5 taken 4414 times.
✓ Branch 6 taken 3507 times.
✓ Branch 7 taken 18230 times.
|
43474 | if(! stack_empty && ! st_.empty()) |
| 432 | { | ||
| 433 | state st; | ||
| 434 |
1/1✓ Branch 1 taken 3507 times.
|
7014 | st_.pop(st); |
| 435 |
4/5✗ Branch 0 not taken.
✓ Branch 1 taken 534 times.
✓ Branch 2 taken 2319 times.
✓ Branch 3 taken 438 times.
✓ Branch 4 taken 216 times.
|
7014 | switch(st) |
| 436 | { | ||
| 437 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 438 | 1068 | case state::com1: goto do_com1; | |
| 439 | 4638 | case state::com2: goto do_com2; | |
| 440 | 876 | case state::com3: goto do_com3; | |
| 441 | 432 | case state::com4: goto do_com4; | |
| 442 | } | ||
| 443 | } | ||
| 444 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18230 times.
|
36460 | BOOST_ASSERT(*cs == '/'); |
| 445 | 36460 | ++cs; | |
| 446 | 37528 | do_com1: | |
| 447 |
2/2✓ Branch 1 taken 551 times.
✓ Branch 2 taken 18213 times.
|
37528 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 448 |
1/1✓ Branch 2 taken 551 times.
|
1102 | return maybe_suspend(cs.begin(), state::com1); |
| 449 |
3/3✓ Branch 1 taken 5 times.
✓ Branch 2 taken 10524 times.
✓ Branch 3 taken 7684 times.
|
36426 | switch(*cs) |
| 450 | { | ||
| 451 | 10 | default: | |
| 452 | { | ||
| 453 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 454 | = BOOST_CURRENT_LOCATION; | ||
| 455 | 10 | return fail(cs.begin(), error::syntax, &loc); | |
| 456 | } | ||
| 457 | 21048 | case '/': | |
| 458 | 21048 | ++cs; | |
| 459 | 25686 | do_com2: | |
| 460 | // KRYSTIAN TODO: this is a mess, we have to fix this | ||
| 461 | 25686 | remain = cs.remain(); | |
| 462 |
2/2✓ Branch 0 taken 12418 times.
✓ Branch 1 taken 425 times.
|
51372 | cs = remain ? static_cast<const char*>( |
| 463 | 25686 | std::memchr(cs.begin(), '\n', remain)) : sentinel(); | |
| 464 |
2/2✓ Branch 1 taken 2143 times.
✓ Branch 2 taken 10700 times.
|
25686 | if(! cs.begin()) |
| 465 | 4286 | cs = sentinel(); | |
| 466 |
2/2✓ Branch 1 taken 2568 times.
✓ Branch 2 taken 10275 times.
|
25686 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 467 | { | ||
| 468 | // if the doc does not terminate | ||
| 469 | // with a newline, treat it as the | ||
| 470 | // end of the comment | ||
| 471 |
4/4✓ Branch 0 taken 165 times.
✓ Branch 1 taken 2403 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 126 times.
|
5136 | if(terminal && ! more_) |
| 472 | { | ||
| 473 |
3/6✗ Branch 1 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 4 taken 26 times.
|
78 | if(BOOST_JSON_UNLIKELY(! h_.on_comment( |
| 474 | {start, cs.remain(start)}, ec_))) | ||
| 475 | 4 | return fail(cs.end()); | |
| 476 | 70 | return cs.end(); | |
| 477 | } | ||
| 478 |
3/6✗ Branch 1 not taken.
✓ Branch 6 taken 482 times.
✗ Branch 7 not taken.
✓ Branch 3 taken 577 times.
✗ Branch 5 not taken.
✓ Branch 4 taken 1372 times.
|
5058 | if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( |
| 479 | {start, cs.remain(start)}, ec_))) | ||
| 480 | 190 | return fail(cs.end()); | |
| 481 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 2233 times.
|
4678 | if(terminal) |
| 482 |
1/1✓ Branch 2 taken 106 times.
|
212 | return suspend(cs.end(), state::com2); |
| 483 |
1/1✓ Branch 2 taken 2233 times.
|
4466 | return maybe_suspend(cs.end(), state::com2); |
| 484 | } | ||
| 485 | 20550 | break; | |
| 486 | 3368 | case '*': | |
| 487 | do | ||
| 488 | { | ||
| 489 | 18736 | ++cs; | |
| 490 | 19612 | do_com3: | |
| 491 | // KRYSTIAN TODO: this is a mess, we have to fix this | ||
| 492 | 19612 | remain = cs.remain(); | |
| 493 |
2/2✓ Branch 0 taken 9545 times.
✓ Branch 1 taken 261 times.
|
39224 | cs = remain ? static_cast<const char*>( |
| 494 | 19612 | std::memchr(cs.begin(), '*', remain)) : sentinel(); | |
| 495 |
2/2✓ Branch 1 taken 242 times.
✓ Branch 2 taken 9564 times.
|
19612 | if(! cs.begin()) |
| 496 | 484 | cs = sentinel(); | |
| 497 | // stopped inside a c comment | ||
| 498 |
2/2✓ Branch 1 taken 503 times.
✓ Branch 2 taken 9303 times.
|
19612 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 499 | { | ||
| 500 |
3/6✗ Branch 1 not taken.
✓ Branch 6 taken 193 times.
✗ Branch 7 not taken.
✓ Branch 3 taken 223 times.
✗ Branch 5 not taken.
✓ Branch 4 taken 56 times.
|
1006 | if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( |
| 501 | {start, cs.remain(start)}, ec_))) | ||
| 502 | 60 | return fail(cs.end()); | |
| 503 |
1/1✓ Branch 2 taken 443 times.
|
886 | return maybe_suspend(cs.end(), state::com3); |
| 504 | } | ||
| 505 | // found a asterisk, check if the next char is a slash | ||
| 506 | 18606 | ++cs; | |
| 507 | 19038 | do_com4: | |
| 508 |
2/2✓ Branch 1 taken 259 times.
✓ Branch 2 taken 9260 times.
|
19038 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 509 | { | ||
| 510 |
3/6✗ Branch 1 not taken.
✓ Branch 6 taken 104 times.
✗ Branch 7 not taken.
✓ Branch 3 taken 122 times.
✗ Branch 5 not taken.
✓ Branch 4 taken 14 times.
|
518 | if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( |
| 511 | {start, cs.used(start)}, ec_))) | ||
| 512 | 36 | return fail(cs.begin()); | |
| 513 |
1/1✓ Branch 2 taken 223 times.
|
446 | return maybe_suspend(cs.begin(), state::com4); |
| 514 | } | ||
| 515 | } | ||
| 516 |
2/2✓ Branch 1 taken 1684 times.
✓ Branch 2 taken 7576 times.
|
18520 | while(*cs != '/'); |
| 517 | } | ||
| 518 | 35702 | ++cs; | |
| 519 |
3/6✗ Branch 1 not taken.
✓ Branch 6 taken 7687 times.
✗ Branch 7 not taken.
✓ Branch 3 taken 8651 times.
✗ Branch 5 not taken.
✓ Branch 4 taken 539 times.
|
35702 | if(BOOST_JSON_UNLIKELY(! h_.on_comment( |
| 520 | {start, cs.used(start)}, ec_))) | ||
| 521 | 1928 | return fail(cs.begin()); | |
| 522 | 31846 | return cs.begin(); | |
| 523 | } | ||
| 524 | |||
| 525 | template<class Handler> | ||
| 526 | template<bool StackEmpty_> | ||
| 527 | const char* | ||
| 528 | 4636814 | basic_parser<Handler>:: | |
| 529 | parse_document(const char* p, | ||
| 530 | std::integral_constant<bool, StackEmpty_> stack_empty) | ||
| 531 | { | ||
| 532 | 4636814 | detail::const_stream_wrapper cs(p, end_); | |
| 533 |
5/6✓ Branch 1 taken 169596 times.
✓ Branch 2 taken 2148811 times.
✓ Branch 4 taken 169596 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 169596 times.
✓ Branch 7 taken 2148811 times.
|
4636814 | if(! stack_empty && ! st_.empty()) |
| 534 | { | ||
| 535 | state st; | ||
| 536 | 339192 | st_.peek(st); | |
| 537 |
4/4✓ Branch 0 taken 83532 times.
✓ Branch 1 taken 601 times.
✓ Branch 2 taken 85243 times.
✓ Branch 3 taken 220 times.
|
339192 | switch(st) |
| 538 | { | ||
| 539 | 167064 | default: goto do_doc2; | |
| 540 | 1202 | case state::doc1: | |
| 541 |
1/1✓ Branch 1 taken 601 times.
|
1202 | st_.pop(st); |
| 542 | 1202 | goto do_doc1; | |
| 543 | 170486 | case state::doc3: | |
| 544 |
1/1✓ Branch 1 taken 85243 times.
|
170486 | st_.pop(st); |
| 545 | 170486 | goto do_doc3; | |
| 546 | 440 | case state::com1: case state::com2: | |
| 547 | case state::com3: case state::com4: | ||
| 548 | 440 | goto do_doc4; | |
| 549 | } | ||
| 550 | } | ||
| 551 | 4297622 | do_doc1: | |
| 552 | 4298824 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 553 |
2/2✓ Branch 1 taken 633 times.
✓ Branch 2 taken 2148779 times.
|
4298824 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 554 |
1/1✓ Branch 2 taken 633 times.
|
1266 | return maybe_suspend(cs.begin(), state::doc1); |
| 555 | 4297558 | do_doc2: | |
| 556 | 4464622 | switch(+opt_.allow_comments | | |
| 557 | 4464622 | (opt_.allow_trailing_commas << 1) | | |
| 558 |
8/8✓ Branch 0 taken 2208646 times.
✓ Branch 1 taken 13534 times.
✓ Branch 2 taken 6710 times.
✓ Branch 3 taken 761 times.
✓ Branch 4 taken 760 times.
✓ Branch 5 taken 760 times.
✓ Branch 6 taken 760 times.
✓ Branch 7 taken 380 times.
|
4464622 | (opt_.allow_invalid_utf8 << 2)) |
| 559 | { | ||
| 560 | // no extensions | ||
| 561 | 4417292 | default: | |
| 562 |
1/1✓ Branch 4 taken 2193486 times.
|
4417292 | cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); |
| 563 | 4386976 | break; | |
| 564 | // comments | ||
| 565 | 27068 | case 1: | |
| 566 |
1/1✓ Branch 4 taken 11271 times.
|
27068 | cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); |
| 567 | 22542 | break; | |
| 568 | // trailing | ||
| 569 | 13420 | case 2: | |
| 570 |
1/1✓ Branch 4 taken 5117 times.
|
13420 | cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); |
| 571 | 10234 | break; | |
| 572 | // comments & trailing | ||
| 573 | 1522 | case 3: | |
| 574 |
1/1✓ Branch 4 taken 761 times.
|
1522 | cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); |
| 575 | 1522 | break; | |
| 576 | // skip validation | ||
| 577 | 1520 | case 4: | |
| 578 |
1/1✓ Branch 4 taken 760 times.
|
1520 | cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); |
| 579 | 1520 | break; | |
| 580 | // comments & skip validation | ||
| 581 | 1520 | case 5: | |
| 582 |
1/1✓ Branch 4 taken 760 times.
|
1520 | cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); |
| 583 | 1520 | break; | |
| 584 | // trailing & skip validation | ||
| 585 | 1520 | case 6: | |
| 586 |
1/1✓ Branch 4 taken 760 times.
|
1520 | cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); |
| 587 | 1520 | break; | |
| 588 | // comments & trailing & skip validation | ||
| 589 | 760 | case 7: | |
| 590 |
1/1✓ Branch 4 taken 380 times.
|
760 | cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); |
| 591 | 760 | break; | |
| 592 | } | ||
| 593 |
2/2✓ Branch 1 taken 110735 times.
✓ Branch 2 taken 2102562 times.
|
4426594 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 594 | // the appropriate state has already been pushed into stack | ||
| 595 | 221470 | return sentinel(); | |
| 596 | 4205124 | do_doc3: | |
| 597 | 4376274 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 598 |
2/2✓ Branch 1 taken 2185539 times.
✓ Branch 2 taken 2598 times.
|
4376274 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 599 | { | ||
| 600 |
2/2✓ Branch 0 taken 88550 times.
✓ Branch 1 taken 2096989 times.
|
4371078 | if(more_) |
| 601 |
1/1✓ Branch 2 taken 88550 times.
|
177100 | return suspend(cs.begin(), state::doc3); |
| 602 | } | ||
| 603 |
6/6✓ Branch 0 taken 648 times.
✓ Branch 1 taken 1950 times.
✓ Branch 3 taken 536 times.
✓ Branch 4 taken 112 times.
✓ Branch 5 taken 536 times.
✓ Branch 6 taken 2062 times.
|
5196 | else if(opt_.allow_comments && *cs == '/') |
| 604 | { | ||
| 605 | 1072 | do_doc4: | |
| 606 |
1/1✓ Branch 3 taken 671 times.
|
1512 | cs = parse_comment(cs.begin(), stack_empty, std::true_type()); |
| 607 |
2/2✓ Branch 1 taken 339 times.
✓ Branch 2 taken 332 times.
|
1342 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 608 | 678 | return sentinel(); | |
| 609 | 664 | goto do_doc3; | |
| 610 | } | ||
| 611 | 4198102 | return cs.begin(); | |
| 612 | } | ||
| 613 | |||
| 614 | template<class Handler> | ||
| 615 | template< | ||
| 616 | bool StackEmpty_, | ||
| 617 | bool AllowComments_/*, | ||
| 618 | bool AllowTrailing_, | ||
| 619 | bool AllowBadUTF8_*/> | ||
| 620 | const char* | ||
| 621 | 4699844 | basic_parser<Handler>:: | |
| 622 | parse_value(const char* p, | ||
| 623 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 624 | std::integral_constant<bool, AllowComments_> allow_comments, | ||
| 625 | /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, | ||
| 626 | /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, | ||
| 627 | bool allow_bad_utf16) | ||
| 628 | { | ||
| 629 |
6/6✓ Branch 1 taken 126658 times.
✓ Branch 2 taken 2223264 times.
✓ Branch 4 taken 24758 times.
✓ Branch 5 taken 101900 times.
✓ Branch 6 taken 2248022 times.
✓ Branch 7 taken 101900 times.
|
4699844 | if(stack_empty || st_.empty()) |
| 630 | { | ||
| 631 | 4496044 | loop: | |
| 632 |
14/14✓ Branch 0 taken 22753 times.
✓ Branch 1 taken 25178 times.
✓ Branch 2 taken 2041766 times.
✓ Branch 3 taken 11379 times.
✓ Branch 4 taken 664 times.
✓ Branch 5 taken 722 times.
✓ Branch 6 taken 681 times.
✓ Branch 7 taken 231 times.
✓ Branch 8 taken 47576 times.
✓ Branch 9 taken 20618 times.
✓ Branch 10 taken 74128 times.
✓ Branch 11 taken 6125 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 1105 times.
|
4505876 | switch(*p) |
| 633 | { | ||
| 634 | 45506 | case '0': | |
| 635 | 45506 | return mp11::mp_with_index<3>( | |
| 636 |
1/1✓ Branch 1 taken 22092 times.
|
45506 | static_cast<unsigned char>(opt_.numbers), |
| 637 | 44184 | parse_number_helper<true, '0'>{ this, p }); | |
| 638 | 50356 | case '-': | |
| 639 | 50356 | return mp11::mp_with_index<3>( | |
| 640 |
1/1✓ Branch 1 taken 24066 times.
|
50356 | static_cast<unsigned char>(opt_.numbers), |
| 641 | 48132 | parse_number_helper<true, '-'>{ this, p }); | |
| 642 | 4083532 | case '1': case '2': case '3': | |
| 643 | case '4': case '5': case '6': | ||
| 644 | case '7': case '8': case '9': | ||
| 645 | 4083532 | return mp11::mp_with_index<3>( | |
| 646 |
1/1✓ Branch 1 taken 2038921 times.
|
4083532 | static_cast<unsigned char>(opt_.numbers), |
| 647 | 4077844 | parse_number_helper<true, '+'>{ this, p }); | |
| 648 | 22758 | case 'n': | |
| 649 | 22758 | return parse_literal( p, detail::literals_c<detail::literals::null>() ); | |
| 650 | 1328 | case 't': | |
| 651 | 1328 | return parse_literal( p, detail::literals_c<detail::literals::true_>() ); | |
| 652 | 1444 | case 'f': | |
| 653 | 1444 | return parse_literal( p, detail::literals_c<detail::literals::false_>() ); | |
| 654 | 1362 | case 'I': | |
| 655 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 657 times.
|
1362 | if( !opt_.allow_infinity_and_nan ) |
| 656 | { | ||
| 657 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 658 | = BOOST_CURRENT_LOCATION; | ||
| 659 | 48 | return fail(p, error::syntax, &loc); | |
| 660 | } | ||
| 661 | 1314 | return parse_literal( p, detail::literals_c<detail::literals::infinity>() ); | |
| 662 | 462 | case 'N': | |
| 663 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 201 times.
|
462 | if( !opt_.allow_infinity_and_nan ) |
| 664 | { | ||
| 665 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 666 | = BOOST_CURRENT_LOCATION; | ||
| 667 | 60 | return fail(p, error::syntax, &loc); | |
| 668 | } | ||
| 669 | 402 | return parse_literal(p, detail::literals_c<detail::literals::nan>() ); | |
| 670 | 95152 | case '"': | |
| 671 | 95152 | return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); | |
| 672 | 41236 | case '[': | |
| 673 | 41236 | return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); | |
| 674 | 148256 | case '{': | |
| 675 | 148256 | return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); | |
| 676 | 12250 | case '/': | |
| 677 |
2/2✓ Branch 1 taken 284 times.
✓ Branch 2 taken 5841 times.
|
12250 | if(! allow_comments) |
| 678 | { | ||
| 679 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 680 | = BOOST_CURRENT_LOCATION; | ||
| 681 | 568 | return fail(p, error::syntax, &loc); | |
| 682 | } | ||
| 683 |
1/1✓ Branch 2 taken 5605 times.
|
11682 | p = parse_comment(p, stack_empty, std::false_type()); |
| 684 | // KRYSTIAN NOTE: incomplete takes const_stream, we either | ||
| 685 | // can add an overload, change the existing one to take a pointer, | ||
| 686 | // or just leave it as is | ||
| 687 |
2/2✓ Branch 1 taken 591 times.
✓ Branch 2 taken 5014 times.
|
11210 | if(BOOST_JSON_UNLIKELY(p == sentinel())) |
| 688 | 1182 | return maybe_suspend(p, state::val2); | |
| 689 | BOOST_FALLTHROUGH; | ||
| 690 | case ' ': | ||
| 691 | case '\t': | ||
| 692 | case '\n': | ||
| 693 | case '\r': | ||
| 694 | 10052 | p = detail::count_whitespace(p, end_); | |
| 695 |
2/2✓ Branch 0 taken 110 times.
✓ Branch 1 taken 4916 times.
|
10052 | if(BOOST_JSON_UNLIKELY(p == end_)) |
| 696 | 220 | return maybe_suspend(p, state::val1); | |
| 697 | 9832 | goto loop; | |
| 698 | 2210 | default: | |
| 699 | { | ||
| 700 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 701 | = BOOST_CURRENT_LOCATION; | ||
| 702 | 2210 | return fail(p, error::syntax, &loc); | |
| 703 | } | ||
| 704 | } | ||
| 705 | } | ||
| 706 | 203800 | return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); | |
| 707 | } | ||
| 708 | |||
| 709 | template<class Handler> | ||
| 710 | template< | ||
| 711 | bool AllowComments_/*, | ||
| 712 | bool AllowTrailing_, | ||
| 713 | bool AllowBadUTF8_*/> | ||
| 714 | const char* | ||
| 715 | 203800 | basic_parser<Handler>:: | |
| 716 | resume_value(const char* p, | ||
| 717 | std::integral_constant<bool, AllowComments_> allow_comments, | ||
| 718 | /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, | ||
| 719 | /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, | ||
| 720 | bool allow_bad_utf16) | ||
| 721 | { | ||
| 722 | state st; | ||
| 723 | 203800 | st_.peek(st); | |
| 724 |
8/9✗ Branch 0 not taken.
✓ Branch 1 taken 1924 times.
✓ Branch 2 taken 20256 times.
✓ Branch 3 taken 5716 times.
✓ Branch 4 taken 35047 times.
✓ Branch 5 taken 37174 times.
✓ Branch 6 taken 108 times.
✓ Branch 7 taken 1608 times.
✓ Branch 8 taken 67 times.
|
203800 | switch(st) |
| 725 | { | ||
| 726 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 727 | 3848 | case state::lit1: | |
| 728 |
1/1✓ Branch 1 taken 1698 times.
|
3848 | return parse_literal(p, detail::literals_c<detail::literals::resume>() ); |
| 729 | |||
| 730 | 40512 | case state::str1: case state::str2: | |
| 731 | case state::str8: | ||
| 732 |
1/1✓ Branch 1 taken 18073 times.
|
40512 | return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); |
| 733 | |||
| 734 | 11432 | case state::arr1: case state::arr2: | |
| 735 | case state::arr3: case state::arr4: | ||
| 736 | case state::arr5: case state::arr6: | ||
| 737 |
1/1✓ Branch 1 taken 4370 times.
|
11432 | return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 738 | |||
| 739 | 70094 | case state::obj1: case state::obj2: | |
| 740 | case state::obj3: case state::obj4: | ||
| 741 | case state::obj5: case state::obj6: | ||
| 742 | case state::obj7: case state::obj8: | ||
| 743 | case state::obj9: case state::obj10: | ||
| 744 | case state::obj11: | ||
| 745 |
1/1✓ Branch 1 taken 28960 times.
|
70094 | return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 746 | |||
| 747 | 74348 | case state::num1: case state::num2: | |
| 748 | case state::num3: case state::num4: | ||
| 749 | case state::num5: case state::num6: | ||
| 750 | case state::num7: case state::num8: | ||
| 751 | case state::exp1: case state::exp2: | ||
| 752 | case state::exp3: | ||
| 753 | 74348 | return mp11::mp_with_index<3>( | |
| 754 |
1/1✓ Branch 1 taken 36351 times.
|
74348 | static_cast<unsigned char>(opt_.numbers), |
| 755 | 72702 | parse_number_helper<false, 0>{ this, p }); | |
| 756 | |||
| 757 | // KRYSTIAN NOTE: these are special cases | ||
| 758 | 216 | case state::val1: | |
| 759 | { | ||
| 760 |
1/1✓ Branch 1 taken 108 times.
|
216 | st_.pop(st); |
| 761 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
|
216 | BOOST_ASSERT(st_.empty()); |
| 762 | 216 | p = detail::count_whitespace(p, end_); | |
| 763 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
|
216 | if(BOOST_JSON_UNLIKELY(p == end_)) |
| 764 | ✗ | return maybe_suspend(p, state::val1); | |
| 765 |
1/1✓ Branch 1 taken 82 times.
|
216 | return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 766 | } | ||
| 767 | |||
| 768 | 3216 | case state::val2: | |
| 769 | { | ||
| 770 |
1/1✓ Branch 1 taken 1608 times.
|
3216 | st_.pop(st); |
| 771 |
1/1✓ Branch 2 taken 1590 times.
|
3216 | p = parse_comment(p, std::false_type(), std::false_type()); |
| 772 |
2/2✓ Branch 1 taken 1274 times.
✓ Branch 2 taken 316 times.
|
3180 | if(BOOST_JSON_UNLIKELY(p == sentinel())) |
| 773 |
1/1✓ Branch 1 taken 1274 times.
|
2548 | return maybe_suspend(p, state::val2); |
| 774 |
2/2✓ Branch 0 taken 77 times.
✓ Branch 1 taken 239 times.
|
632 | if(BOOST_JSON_UNLIKELY( p == end_ )) |
| 775 |
1/1✓ Branch 1 taken 77 times.
|
154 | return maybe_suspend(p, state::val3); |
| 776 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
|
478 | BOOST_ASSERT(st_.empty()); |
| 777 |
1/1✓ Branch 1 taken 187 times.
|
478 | return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 778 | } | ||
| 779 | |||
| 780 | 134 | case state::val3: | |
| 781 | { | ||
| 782 |
1/1✓ Branch 1 taken 67 times.
|
134 | st_.pop(st); |
| 783 |
1/1✓ Branch 1 taken 67 times.
|
134 | return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 784 | } | ||
| 785 | } | ||
| 786 | } | ||
| 787 | |||
| 788 | template<class Handler> | ||
| 789 | template<class Literal> | ||
| 790 | const char* | ||
| 791 | 33126 | basic_parser<Handler>:: | |
| 792 | parse_literal(const char* p, Literal) | ||
| 793 | { | ||
| 794 | using L = detail::literals; | ||
| 795 | |||
| 796 | std::size_t cur_lit; | ||
| 797 | std::size_t offset; | ||
| 798 | |||
| 799 | 33126 | detail::const_stream_wrapper cs(p, end_); | |
| 800 | BOOST_IF_CONSTEXPR( Literal::value != L::resume ) | ||
| 801 | { | ||
| 802 | 27264 | constexpr std::size_t index = literal_index(Literal::value); | |
| 803 | 27264 | constexpr char const* literal = detail::literal_strings[index]; | |
| 804 | 27264 | constexpr std::size_t sz = detail::literal_sizes[index]; | |
| 805 | |||
| 806 |
2/2✓ Branch 1 taken 11982 times.
✓ Branch 2 taken 1650 times.
|
27264 | if(BOOST_JSON_LIKELY( cs.remain() >= sz )) |
| 807 | { | ||
| 808 | 23964 | int const cmp = std::memcmp(cs.begin(), literal, sz); | |
| 809 |
2/2✓ Branch 0 taken 197 times.
✓ Branch 1 taken 11785 times.
|
23964 | if( cmp != 0 ) |
| 810 | { | ||
| 811 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 812 | 394 | return fail(cs.begin(), error::syntax, &loc); | |
| 813 | } | ||
| 814 | |||
| 815 | BOOST_IF_CONSTEXPR( Literal::value == L::null ) | ||
| 816 | { | ||
| 817 |
3/5✓ Branch 1 taken 10007 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 9846 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
21574 | if(BOOST_JSON_UNLIKELY( |
| 818 | ! h_.on_null(ec_))) | ||
| 819 | 322 | return fail(cs.begin()); | |
| 820 | } | ||
| 821 | else BOOST_IF_CONSTEXPR( Literal::value == L::true_ ) | ||
| 822 | { | ||
| 823 |
3/5✓ Branch 1 taken 199 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 185 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
768 | if(BOOST_JSON_UNLIKELY( |
| 824 | ! h_.on_bool(true, ec_))) | ||
| 825 | 28 | return fail(cs.begin()); | |
| 826 | } | ||
| 827 | else BOOST_IF_CONSTEXPR( Literal::value == L::false_ ) | ||
| 828 | { | ||
| 829 |
2/5✓ Branch 1 taken 266 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 253 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
812 | if(BOOST_JSON_UNLIKELY( |
| 830 | ! h_.on_bool(false, ec_))) | ||
| 831 | 26 | return fail(cs.begin()); | |
| 832 | } | ||
| 833 | else BOOST_IF_CONSTEXPR( Literal::value == L::infinity ) | ||
| 834 | { | ||
| 835 |
2/6✓ Branch 3 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
206 | if(BOOST_JSON_UNLIKELY( |
| 836 | ! h_.on_double( | ||
| 837 | std::numeric_limits<double>::infinity(), | ||
| 838 | string_view(literal, sz), | ||
| 839 | ec_))) | ||
| 840 | 26 | return fail(cs.begin()); | |
| 841 | } | ||
| 842 | else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity ) | ||
| 843 | { | ||
| 844 |
2/6✓ Branch 3 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
18 | if(BOOST_JSON_UNLIKELY( |
| 845 | ! h_.on_double( | ||
| 846 | -std::numeric_limits<double>::infinity(), | ||
| 847 | string_view(literal, sz), | ||
| 848 | ec_))) | ||
| 849 | 2 | return fail(cs.begin()); | |
| 850 | } | ||
| 851 | else BOOST_IF_CONSTEXPR( Literal::value == L::nan ) | ||
| 852 | { | ||
| 853 |
2/6✓ Branch 3 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
192 | if(BOOST_JSON_UNLIKELY( |
| 854 | ! h_.on_double( | ||
| 855 | std::numeric_limits<double>::quiet_NaN(), | ||
| 856 | string_view(literal, sz), | ||
| 857 | ec_))) | ||
| 858 | 24 | return fail(cs.begin()); | |
| 859 | } | ||
| 860 | else | ||
| 861 | { | ||
| 862 | BOOST_JSON_UNREACHABLE(); | ||
| 863 | } | ||
| 864 | |||
| 865 | 22722 | cs += sz; | |
| 866 | 22722 | return cs.begin(); | |
| 867 | } | ||
| 868 | |||
| 869 | 3300 | offset = 0; | |
| 870 | 3300 | cur_lit = index; | |
| 871 | } | ||
| 872 | else | ||
| 873 | { | ||
| 874 | state st; | ||
| 875 |
1/1✓ Branch 1 taken 2931 times.
|
5862 | st_.pop(st); |
| 876 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2931 times.
|
5862 | BOOST_ASSERT( st == state::lit1 ); |
| 877 | |||
| 878 | 5862 | cur_lit = cur_lit_; | |
| 879 | 5862 | offset = lit_offset_; | |
| 880 | } | ||
| 881 | |||
| 882 | 9162 | std::size_t const lit_size = detail::literal_sizes[cur_lit]; | |
| 883 | 9162 | std::size_t const size = (std::min)( lit_size - offset, cs.remain() ); | |
| 884 | 9162 | int cmp = 0; | |
| 885 |
2/2✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 1 times.
|
9162 | if(BOOST_JSON_LIKELY( cs.begin() )) |
| 886 | 9160 | cmp = std::memcmp( | |
| 887 | 9160 | cs.begin(), detail::literal_strings[cur_lit] + offset, size ); | |
| 888 |
2/2✓ Branch 0 taken 699 times.
✓ Branch 1 taken 3882 times.
|
9162 | if( cmp != 0 ) |
| 889 | { | ||
| 890 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 891 | 1398 | return fail(cs.begin(), error::syntax, &loc); | |
| 892 | } | ||
| 893 | |||
| 894 |
2/2✓ Branch 0 taken 1990 times.
✓ Branch 1 taken 1892 times.
|
7764 | if(BOOST_JSON_UNLIKELY( offset + size < lit_size )) |
| 895 | { | ||
| 896 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1990 times.
|
3980 | BOOST_ASSERT( cur_lit < 256 ); |
| 897 | 3980 | cur_lit_ = static_cast<unsigned char>( cur_lit ); | |
| 898 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1990 times.
|
3980 | BOOST_ASSERT( offset + size < 256 ); |
| 899 | 3980 | lit_offset_ = static_cast<unsigned char>( offset + size ); | |
| 900 |
1/1✓ Branch 2 taken 1990 times.
|
3980 | return maybe_suspend(cs.begin() + size, state::lit1); |
| 901 | } | ||
| 902 | |||
| 903 |
6/7✓ Branch 0 taken 472 times.
✓ Branch 1 taken 152 times.
✓ Branch 2 taken 198 times.
✓ Branch 3 taken 308 times.
✓ Branch 4 taken 686 times.
✓ Branch 5 taken 76 times.
✗ Branch 6 not taken.
|
3784 | switch( static_cast<L>(cur_lit) ) |
| 904 | { | ||
| 905 | 944 | case L::null: | |
| 906 |
3/5✓ Branch 1 taken 253 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 192 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
944 | if(BOOST_JSON_UNLIKELY( |
| 907 | ! h_.on_null(ec_))) | ||
| 908 | 122 | return fail(cs.begin()); | |
| 909 | 702 | break; | |
| 910 | 304 | case L::true_: | |
| 911 |
3/5✓ Branch 1 taken 89 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 67 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
304 | if(BOOST_JSON_UNLIKELY( |
| 912 | ! h_.on_bool(true, ec_))) | ||
| 913 | 44 | return fail(cs.begin()); | |
| 914 | 218 | break; | |
| 915 | 396 | case L::false_: | |
| 916 |
2/5✓ Branch 1 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
396 | if(BOOST_JSON_UNLIKELY( |
| 917 | ! h_.on_bool(false, ec_))) | ||
| 918 | 56 | return fail(cs.begin()); | |
| 919 | 284 | break; | |
| 920 | 616 | case L::infinity: | |
| 921 |
2/6✓ Branch 3 taken 161 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 112 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
616 | if(BOOST_JSON_UNLIKELY( |
| 922 | ! h_.on_double( | ||
| 923 | std::numeric_limits<double>::infinity(), | ||
| 924 | string_view( | ||
| 925 | detail::literal_strings[ literal_index(L::infinity) ], | ||
| 926 | detail::literal_sizes[ literal_index(L::infinity) ]), | ||
| 927 | ec_))) | ||
| 928 | 98 | return fail(cs.begin()); | |
| 929 | 420 | break; | |
| 930 | 1372 | case L::neg_infinity: | |
| 931 |
2/6✓ Branch 3 taken 359 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 257 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
1372 | if(BOOST_JSON_UNLIKELY( |
| 932 | ! h_.on_double( | ||
| 933 | -std::numeric_limits<double>::infinity(), | ||
| 934 | string_view( | ||
| 935 | detail::literal_strings[ literal_index(L::neg_infinity) ], | ||
| 936 | detail::literal_sizes[ literal_index(L::neg_infinity) ]), | ||
| 937 | ec_))) | ||
| 938 | 204 | return fail(cs.begin()); | |
| 939 | 964 | break; | |
| 940 | 152 | case L::nan: | |
| 941 |
2/6✓ Branch 3 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
152 | if(BOOST_JSON_UNLIKELY( |
| 942 | ! h_.on_double( | ||
| 943 | std::numeric_limits<double>::quiet_NaN(), | ||
| 944 | string_view( | ||
| 945 | detail::literal_strings[ literal_index(L::nan) ], | ||
| 946 | detail::literal_sizes[ literal_index(L::nan) ]), | ||
| 947 | ec_))) | ||
| 948 | 24 | return fail(cs.begin()); | |
| 949 | 104 | break; | |
| 950 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 951 | } | ||
| 952 | |||
| 953 | 2692 | cs += size; | |
| 954 | 2692 | return cs.begin(); | |
| 955 | } | ||
| 956 | |||
| 957 | //---------------------------------------------------------- | ||
| 958 | |||
| 959 | template<class Handler> | ||
| 960 | template<bool StackEmpty_, bool IsKey_> | ||
| 961 | const char* | ||
| 962 | 322594 | basic_parser<Handler>:: | |
| 963 | parse_string(const char* p, | ||
| 964 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 965 | std::integral_constant<bool, IsKey_> is_key, | ||
| 966 | bool allow_bad_utf8, | ||
| 967 | bool allow_bad_utf16) | ||
| 968 | { | ||
| 969 | 322594 | detail::const_stream_wrapper cs(p, end_); | |
| 970 | std::size_t total; | ||
| 971 | char const* start; | ||
| 972 | std::size_t size; | ||
| 973 |
6/6✓ Branch 1 taken 39681 times.
✓ Branch 2 taken 121616 times.
✓ Branch 4 taken 32896 times.
✓ Branch 5 taken 6785 times.
✓ Branch 6 taken 32896 times.
✓ Branch 7 taken 128401 times.
|
322594 | if(! stack_empty && ! st_.empty()) |
| 974 | { | ||
| 975 | state st; | ||
| 976 |
1/1✓ Branch 1 taken 32896 times.
|
65792 | st_.pop(st); |
| 977 |
1/1✓ Branch 1 taken 32896 times.
|
65792 | st_.pop(total); |
| 978 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 3149 times.
✓ Branch 2 taken 1861 times.
✓ Branch 3 taken 27886 times.
|
65792 | switch(st) |
| 979 | { | ||
| 980 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 981 | 6298 | case state::str2: goto do_str2; | |
| 982 | 3722 | case state::str8: goto do_str8; | |
| 983 | 55772 | case state::str1: break; | |
| 984 | } | ||
| 985 | } | ||
| 986 | else | ||
| 987 | { | ||
| 988 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 128401 times.
|
256802 | BOOST_ASSERT(*cs == '\x22'); // '"' |
| 989 | 256802 | ++cs; | |
| 990 | 256802 | total = 0; | |
| 991 | } | ||
| 992 | |||
| 993 | 329558 | do_str1: | |
| 994 | 329558 | start = cs.begin(); | |
| 995 |
2/2✓ Branch 0 taken 2177 times.
✓ Branch 1 taken 162602 times.
|
659116 | cs = allow_bad_utf8? |
| 996 | 4354 | detail::count_valid<true>(cs.begin(), cs.end()): | |
| 997 | 325204 | detail::count_valid<false>(cs.begin(), cs.end()); | |
| 998 | 329558 | size = cs.used(start); | |
| 999 |
2/2✓ Branch 1 taken 93996 times.
✓ Branch 2 taken 70783 times.
|
329558 | if(is_key) |
| 1000 | { | ||
| 1001 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46685 times.
|
93370 | BOOST_ASSERT(total <= Handler::max_key_size); |
| 1002 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 93993 times.
|
187992 | if(BOOST_JSON_UNLIKELY(size > |
| 1003 | Handler::max_key_size - total)) | ||
| 1004 | { | ||
| 1005 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1006 | = BOOST_CURRENT_LOCATION; | ||
| 1007 | 6 | return fail(cs.begin(), error::key_too_large, &loc); | |
| 1008 | } | ||
| 1009 | } | ||
| 1010 | else | ||
| 1011 | { | ||
| 1012 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35321 times.
|
70642 | BOOST_ASSERT(total <= Handler::max_string_size); |
| 1013 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 70780 times.
|
141566 | if(BOOST_JSON_UNLIKELY(size > |
| 1014 | Handler::max_string_size - total)) | ||
| 1015 | { | ||
| 1016 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1017 | = BOOST_CURRENT_LOCATION; | ||
| 1018 | 6 | return fail(cs.begin(), error::string_too_large, &loc); | |
| 1019 | } | ||
| 1020 | } | ||
| 1021 | 329546 | total += size; | |
| 1022 |
2/2✓ Branch 1 taken 30220 times.
✓ Branch 2 taken 134553 times.
|
329546 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1023 | { | ||
| 1024 | // call handler if the string isn't empty | ||
| 1025 |
2/2✓ Branch 0 taken 27063 times.
✓ Branch 1 taken 3157 times.
|
60440 | if(BOOST_JSON_LIKELY(size)) |
| 1026 | { | ||
| 1027 | { | ||
| 1028 |
2/2✓ Branch 1 taken 11294 times.
✓ Branch 2 taken 15769 times.
|
54126 | bool r = is_key? |
| 1029 |
1/2✓ Branch 2 taken 8105 times.
✗ Branch 1 not taken.
|
24804 | h_.on_key_part( {start, size}, total, ec_ ): |
| 1030 |
1/2✓ Branch 2 taken 8614 times.
✗ Branch 1 not taken.
|
31990 | h_.on_string_part( {start, size}, total, ec_ ); |
| 1031 | |||
| 1032 |
2/2✓ Branch 0 taken 1110 times.
✓ Branch 1 taken 24845 times.
|
51910 | if(BOOST_JSON_UNLIKELY(!r)) |
| 1033 | { | ||
| 1034 | 2220 | return fail(cs.begin()); | |
| 1035 | } | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 |
1/1✓ Branch 2 taken 28002 times.
|
56004 | return maybe_suspend(cs.begin(), state::str1, total); |
| 1039 | } | ||
| 1040 | // at this point all valid characters have been skipped, so any remaining | ||
| 1041 | // if there are any more characters, they are either escaped, or incomplete | ||
| 1042 | // utf8, or invalid utf8 | ||
| 1043 |
2/2✓ Branch 1 taken 15068 times.
✓ Branch 2 taken 119485 times.
|
269106 | if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"' |
| 1044 | { | ||
| 1045 | // sequence is invalid or incomplete | ||
| 1046 |
5/6✓ Branch 1 taken 3462 times.
✓ Branch 2 taken 11606 times.
✓ Branch 3 taken 3462 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3462 times.
✓ Branch 6 taken 11606 times.
|
30136 | if((*cs & 0x80) && !allow_bad_utf8) |
| 1047 | { | ||
| 1048 | 6924 | seq_.save(cs.begin(), cs.remain()); | |
| 1049 |
2/2✓ Branch 1 taken 1557 times.
✓ Branch 2 taken 1905 times.
|
6924 | if(BOOST_JSON_UNLIKELY(seq_.complete())) |
| 1050 | { | ||
| 1051 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1052 | = BOOST_CURRENT_LOCATION; | ||
| 1053 | 3114 | return fail(cs.begin(), error::syntax, &loc); | |
| 1054 | } | ||
| 1055 |
2/2✓ Branch 0 taken 245 times.
✓ Branch 1 taken 1660 times.
|
3810 | if(BOOST_JSON_LIKELY(size)) |
| 1056 | { | ||
| 1057 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 245 times.
|
490 | bool const r = is_key? |
| 1058 |
0/2✗ Branch 2 not taken.
✗ Branch 1 not taken.
|
44 | h_.on_key_part( {start, size}, total, ec_ ): |
| 1059 |
0/2✗ Branch 2 not taken.
✗ Branch 1 not taken.
|
490 | h_.on_string_part( {start, size}, total, ec_ ); |
| 1060 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 201 times.
|
446 | if(BOOST_JSON_UNLIKELY( !r )) |
| 1061 | 44 | return fail( cs.begin() ); | |
| 1062 | } | ||
| 1063 |
1/1✓ Branch 2 taken 1861 times.
|
3722 | return maybe_suspend(cs.end(), state::str8, total); |
| 1064 | } | ||
| 1065 |
2/2✓ Branch 1 taken 11497 times.
✓ Branch 2 taken 109 times.
|
23212 | else if(BOOST_JSON_LIKELY(*cs == '\\')) |
| 1066 | { | ||
| 1067 | // flush unescaped run from input | ||
| 1068 |
2/2✓ Branch 0 taken 4250 times.
✓ Branch 1 taken 7247 times.
|
22994 | if(BOOST_JSON_LIKELY(size)) |
| 1069 | { | ||
| 1070 |
2/2✓ Branch 1 taken 742 times.
✓ Branch 2 taken 3508 times.
|
8500 | bool const r = is_key? |
| 1071 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 1 not taken.
|
2452 | h_.on_key_part( {start, size}, total, ec_ ): |
| 1072 |
1/2✓ Branch 2 taken 89 times.
✗ Branch 1 not taken.
|
7108 | h_.on_string_part( {start, size}, total, ec_ ); |
| 1073 |
2/2✓ Branch 0 taken 484 times.
✓ Branch 1 taken 3282 times.
|
7532 | if(BOOST_JSON_UNLIKELY( !r )) |
| 1074 | 968 | return fail( cs.begin() ); | |
| 1075 | } | ||
| 1076 | 14494 | do_str2: | |
| 1077 |
1/1✓ Branch 3 taken 12716 times.
|
27356 | cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16); |
| 1078 |
2/2✓ Branch 1 taken 5473 times.
✓ Branch 2 taken 7243 times.
|
25432 | if(BOOST_JSON_UNLIKELY( incomplete(cs) )) |
| 1079 |
1/1✓ Branch 1 taken 5473 times.
|
10946 | return suspend_or_fail(state::str2, total); |
| 1080 | |||
| 1081 | 14486 | goto do_str1; | |
| 1082 | } | ||
| 1083 | // illegal control | ||
| 1084 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 1085 | 218 | return fail(cs.begin(), error::syntax, &loc); | |
| 1086 | } | ||
| 1087 | |||
| 1088 | { | ||
| 1089 |
2/2✓ Branch 1 taken 80135 times.
✓ Branch 2 taken 39350 times.
|
238970 | bool r = is_key? |
| 1090 |
1/2✓ Branch 2 taken 38431 times.
✗ Branch 1 not taken.
|
169018 | h_.on_key( {start, size}, total, ec_ ): |
| 1091 |
1/2✓ Branch 2 taken 26204 times.
✗ Branch 1 not taken.
|
83970 | h_.on_string( {start, size}, total, ec_ ); |
| 1092 | |||
| 1093 |
2/2✓ Branch 0 taken 4318 times.
✓ Branch 1 taken 110793 times.
|
230222 | if(BOOST_JSON_UNLIKELY(!r)) |
| 1094 | { | ||
| 1095 | 8636 | return fail(cs.begin()); | |
| 1096 | } | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | 221586 | ++cs; | |
| 1100 | 221586 | return cs.begin(); | |
| 1101 | |||
| 1102 | 3722 | do_str8: | |
| 1103 | 3722 | uint8_t needed = seq_.needed(); | |
| 1104 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1861 times.
|
3722 | if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) )) |
| 1105 | ✗ | return maybe_suspend(cs.end(), state::str8, total); | |
| 1106 |
2/2✓ Branch 1 taken 210 times.
✓ Branch 2 taken 1651 times.
|
3722 | if(BOOST_JSON_UNLIKELY( !seq_.valid() )) |
| 1107 | { | ||
| 1108 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 1109 | 420 | return fail(cs.begin(), error::syntax, &loc); | |
| 1110 | } | ||
| 1111 | { | ||
| 1112 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1651 times.
|
3302 | bool const r = is_key? |
| 1113 |
0/2✗ Branch 4 not taken.
✗ Branch 1 not taken.
|
402 | h_.on_key_part( {seq_.data(), seq_.length()}, total, ec_ ): |
| 1114 |
1/2✓ Branch 4 taken 629 times.
✗ Branch 1 not taken.
|
3302 | h_.on_string_part( {seq_.data(), seq_.length()}, total, ec_ ); |
| 1115 |
2/2✓ Branch 0 taken 201 times.
✓ Branch 1 taken 1249 times.
|
2900 | if(BOOST_JSON_UNLIKELY( !r )) |
| 1116 | 402 | return fail( cs.begin() ); | |
| 1117 | } | ||
| 1118 | 2498 | cs += needed; | |
| 1119 | 2498 | goto do_str1; | |
| 1120 | } | ||
| 1121 | |||
| 1122 | template<class Handler> | ||
| 1123 | template<bool StackEmpty_> | ||
| 1124 | const char* | ||
| 1125 | 27356 | basic_parser<Handler>:: | |
| 1126 | parse_escaped( | ||
| 1127 | const char* p, | ||
| 1128 | std::size_t& total, | ||
| 1129 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 1130 | bool is_key, | ||
| 1131 | bool allow_bad_utf16) | ||
| 1132 | { | ||
| 1133 | 27356 | constexpr unsigned urc = 0xFFFD; // Unicode replacement character | |
| 1134 |
2/2✓ Branch 0 taken 835 times.
✓ Branch 1 taken 12843 times.
|
27356 | auto const ev_too_large = is_key? |
| 1135 | error::key_too_large : error::string_too_large; | ||
| 1136 | 27356 | auto const max_size = is_key? | |
| 1137 | Handler::max_key_size : Handler::max_string_size; | ||
| 1138 | int digit; | ||
| 1139 | |||
| 1140 | //--------------------------------------------------------------- | ||
| 1141 | // | ||
| 1142 | // To handle escapes, a local temporary buffer accumulates | ||
| 1143 | // the unescaped result. The algorithm attempts to fill the | ||
| 1144 | // buffer to capacity before invoking the handler. | ||
| 1145 | // In some cases the temporary buffer needs to be flushed | ||
| 1146 | // before it is full: | ||
| 1147 | // * When the closing double quote is seen | ||
| 1148 | // * When there in no more input (and more is expected later) | ||
| 1149 | // A goal of the algorithm is to call the handler as few times | ||
| 1150 | // as possible. Thus, when the first escape is encountered, | ||
| 1151 | // the algorithm attempts to fill the temporary buffer first. | ||
| 1152 | // | ||
| 1153 | 27356 | detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp; | |
| 1154 | |||
| 1155 | // Unescaped JSON is never larger than its escaped version. | ||
| 1156 | // To efficiently process only what will fit in the temporary buffer, | ||
| 1157 | // the size of the input stream is temporarily "clipped" to the size | ||
| 1158 | // of the temporary buffer. | ||
| 1159 | // handle escaped character | ||
| 1160 | 27356 | detail::clipped_const_stream cs(p, end_); | |
| 1161 | 27356 | cs.clip(temp.max_size()); | |
| 1162 | |||
| 1163 |
6/6✓ Branch 1 taken 4207 times.
✓ Branch 2 taken 9471 times.
✓ Branch 4 taken 3149 times.
✓ Branch 5 taken 1058 times.
✓ Branch 6 taken 3149 times.
✓ Branch 7 taken 10529 times.
|
27356 | if(! stack_empty && ! st_.empty()) |
| 1164 | { | ||
| 1165 | state st; | ||
| 1166 |
1/1✓ Branch 1 taken 3149 times.
|
6298 | st_.pop(st); |
| 1167 |
11/12✗ Branch 0 not taken.
✓ Branch 1 taken 528 times.
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 390 times.
✓ Branch 4 taken 389 times.
✓ Branch 5 taken 386 times.
✓ Branch 6 taken 232 times.
✓ Branch 7 taken 188 times.
✓ Branch 8 taken 164 times.
✓ Branch 9 taken 162 times.
✓ Branch 10 taken 160 times.
✓ Branch 11 taken 158 times.
|
6298 | switch(st) |
| 1168 | { | ||
| 1169 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 1170 | 1056 | case state::str3: goto do_str3; | |
| 1171 | 784 | case state::str4: goto do_str4; | |
| 1172 | 780 | case state::str5: goto do_str5; | |
| 1173 | 778 | case state::str6: goto do_str6; | |
| 1174 | 772 | case state::str7: goto do_str7; | |
| 1175 | 464 | case state::sur1: goto do_sur1; | |
| 1176 | 376 | case state::sur2: goto do_sur2; | |
| 1177 | 328 | case state::sur3: goto do_sur3; | |
| 1178 | 324 | case state::sur4: goto do_sur4; | |
| 1179 | 320 | case state::sur5: goto do_sur5; | |
| 1180 | 316 | case state::sur6: goto do_sur6; | |
| 1181 | } | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | 7562 | while(true) | |
| 1185 | { | ||
| 1186 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14310 times.
|
28620 | BOOST_ASSERT( temp.capacity() ); |
| 1187 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14310 times.
|
28620 | BOOST_ASSERT(*cs == '\\'); |
| 1188 | 28620 | ++cs; | |
| 1189 | 30338 | do_str3: | |
| 1190 |
2/2✓ Branch 1 taken 561 times.
✓ Branch 2 taken 14813 times.
|
30748 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1191 | { | ||
| 1192 |
2/2✓ Branch 1 taken 100 times.
✓ Branch 2 taken 461 times.
|
1122 | if(BOOST_JSON_LIKELY(! temp.empty())) |
| 1193 | { | ||
| 1194 | ✗ | BOOST_ASSERT(total <= max_size); | |
| 1195 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
200 | if(BOOST_JSON_UNLIKELY( |
| 1196 | temp.size() > max_size - total)) | ||
| 1197 | { | ||
| 1198 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1199 | = BOOST_CURRENT_LOCATION; | ||
| 1200 | ✗ | return fail(cs.begin(), ev_too_large, &loc); | |
| 1201 | } | ||
| 1202 | 200 | total += temp.size(); | |
| 1203 | { | ||
| 1204 | 182 | bool r = is_key | |
| 1205 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
✗ Branch 4 not taken.
✗ Branch 3 not taken.
|
200 | ? h_.on_key_part(temp.get(), total, ec_) |
| 1206 |
0/2✗ Branch 2 not taken.
✗ Branch 1 not taken.
|
200 | : h_.on_string_part(temp.get(), total, ec_); |
| 1207 | |||
| 1208 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 82 times.
|
182 | if(BOOST_JSON_UNLIKELY(!r)) |
| 1209 | { | ||
| 1210 | 18 | return fail(cs.begin()); | |
| 1211 | } | ||
| 1212 | } | ||
| 1213 | 164 | temp.clear(); | |
| 1214 | } | ||
| 1215 | 1086 | cs.clip(temp.max_size()); | |
| 1216 |
1/2✓ Branch 1 taken 543 times.
✗ Branch 2 not taken.
|
1086 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1217 |
1/1✓ Branch 2 taken 543 times.
|
1086 | return maybe_suspend(cs.begin(), state::str3); |
| 1218 | } | ||
| 1219 |
10/10✓ Branch 1 taken 191 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 178 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 112 times.
✓ Branch 6 taken 108 times.
✓ Branch 7 taken 1763 times.
✓ Branch 8 taken 146 times.
✓ Branch 9 taken 266 times.
✓ Branch 10 taken 11688 times.
|
29626 | switch(*cs) |
| 1220 | { | ||
| 1221 | 382 | default: | |
| 1222 | { | ||
| 1223 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1224 | = BOOST_CURRENT_LOCATION; | ||
| 1225 | 382 | return fail(cs.begin(), error::syntax, &loc); | |
| 1226 | } | ||
| 1227 | 530 | case '\x22': // '"' | |
| 1228 | 530 | temp.push_back('\x22'); | |
| 1229 | 530 | ++cs; | |
| 1230 | 530 | break; | |
| 1231 | 356 | case '\\': | |
| 1232 | 356 | temp.push_back('\\'); | |
| 1233 | 356 | ++cs; | |
| 1234 | 356 | break; | |
| 1235 | 192 | case '/': | |
| 1236 | 192 | temp.push_back('/'); | |
| 1237 | 192 | ++cs; | |
| 1238 | 192 | break; | |
| 1239 | 224 | case 'b': | |
| 1240 | 224 | temp.push_back('\x08'); | |
| 1241 | 224 | ++cs; | |
| 1242 | 224 | break; | |
| 1243 | 216 | case 'f': | |
| 1244 | 216 | temp.push_back('\x0c'); | |
| 1245 | 216 | ++cs; | |
| 1246 | 216 | break; | |
| 1247 | 3526 | case 'n': | |
| 1248 | 3526 | temp.push_back('\x0a'); | |
| 1249 | 3526 | ++cs; | |
| 1250 | 3526 | break; | |
| 1251 | 292 | case 'r': | |
| 1252 | 292 | temp.push_back('\x0d'); | |
| 1253 | 292 | ++cs; | |
| 1254 | 292 | break; | |
| 1255 | 532 | case 't': | |
| 1256 | 532 | temp.push_back('\x09'); | |
| 1257 | 532 | ++cs; | |
| 1258 | 532 | break; | |
| 1259 | 23376 | case 'u': | |
| 1260 | // utf16 escape | ||
| 1261 | // | ||
| 1262 | // fast path only when the buffer | ||
| 1263 | // is large enough for 2 surrogates | ||
| 1264 |
2/2✓ Branch 1 taken 5697 times.
✓ Branch 2 taken 5991 times.
|
23376 | if(BOOST_JSON_LIKELY(cs.remain() > 10)) |
| 1265 | { | ||
| 1266 | // KRYSTIAN TODO: this could be done | ||
| 1267 | // with fewer instructions | ||
| 1268 | 22788 | digit = detail::load_little_endian<4>( | |
| 1269 | 11394 | cs.begin() + 1); | |
| 1270 | 11394 | int d4 = detail::hex_digit(static_cast< | |
| 1271 | 11394 | unsigned char>(digit >> 24)); | |
| 1272 | 11394 | int d3 = detail::hex_digit(static_cast< | |
| 1273 | 11394 | unsigned char>(digit >> 16)); | |
| 1274 | 11394 | int d2 = detail::hex_digit(static_cast< | |
| 1275 | 11394 | unsigned char>(digit >> 8)); | |
| 1276 | 11394 | int d1 = detail::hex_digit(static_cast< | |
| 1277 | unsigned char>(digit)); | ||
| 1278 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 5637 times.
|
11394 | if(BOOST_JSON_UNLIKELY( |
| 1279 | (d1 | d2 | d3 | d4) == -1)) | ||
| 1280 | { | ||
| 1281 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 15 times.
|
120 | if(d1 != -1) |
| 1282 | 90 | ++cs; | |
| 1283 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
|
120 | if(d2 != -1) |
| 1284 | 60 | ++cs; | |
| 1285 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 45 times.
|
120 | if(d3 != -1) |
| 1286 | 30 | ++cs; | |
| 1287 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1288 | = BOOST_CURRENT_LOCATION; | ||
| 1289 | 120 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1290 | } | ||
| 1291 | // 32 bit unicode scalar value | ||
| 1292 | 11274 | unsigned u1 = | |
| 1293 | 11274 | (d1 << 12) + (d2 << 8) + | |
| 1294 | 11274 | (d3 << 4) + d4; | |
| 1295 | // valid unicode scalar values are | ||
| 1296 | // [0, D7FF] and [E000, 10FFFF] | ||
| 1297 | // values within this range are valid utf-8 | ||
| 1298 | // code points and invalid leading surrogates. | ||
| 1299 |
6/6✓ Branch 0 taken 4577 times.
✓ Branch 1 taken 1060 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 4297 times.
✓ Branch 4 taken 1340 times.
✓ Branch 5 taken 4297 times.
|
11274 | if(BOOST_JSON_LIKELY( |
| 1300 | u1 < 0xd800 || u1 > 0xdfff)) | ||
| 1301 | { | ||
| 1302 | 2680 | cs += 5; | |
| 1303 | 2680 | temp.append_utf8(u1); | |
| 1304 | 2680 | break; | |
| 1305 | } | ||
| 1306 |
2/2✓ Branch 0 taken 707 times.
✓ Branch 1 taken 3590 times.
|
8594 | if(BOOST_JSON_UNLIKELY(u1 > 0xdbff)) |
| 1307 | { | ||
| 1308 | // If it's an illegal leading surrogate and | ||
| 1309 | // the parser does not allow it, return an error. | ||
| 1310 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 585 times.
|
1414 | if(!allow_bad_utf16) |
| 1311 | { | ||
| 1312 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1313 | = BOOST_CURRENT_LOCATION; | ||
| 1314 | 244 | return fail(cs.begin(), error::illegal_leading_surrogate, | |
| 1315 | 244 | &loc); | |
| 1316 | } | ||
| 1317 | // Otherwise, append the Unicode replacement character | ||
| 1318 | else | ||
| 1319 | { | ||
| 1320 | 1170 | cs += 5; | |
| 1321 | 1170 | temp.append_utf8(urc); | |
| 1322 | 1170 | break; | |
| 1323 | } | ||
| 1324 | } | ||
| 1325 | 7180 | cs += 5; | |
| 1326 | // KRYSTIAN TODO: this can be a two byte load | ||
| 1327 | // and a single comparison. We lose error information, | ||
| 1328 | // but it's faster. | ||
| 1329 |
2/2✓ Branch 1 taken 156 times.
✓ Branch 2 taken 3434 times.
|
7180 | if(BOOST_JSON_UNLIKELY(*cs != '\\')) |
| 1330 | { | ||
| 1331 | // If the next character is not a backslash and | ||
| 1332 | // the parser does not allow it, return a syntax error. | ||
| 1333 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 141 times.
|
312 | if(!allow_bad_utf16) |
| 1334 | { | ||
| 1335 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1336 | = BOOST_CURRENT_LOCATION; | ||
| 1337 | 30 | return fail(cs.begin(), error::syntax, &loc); | |
| 1338 | } | ||
| 1339 | // Otherwise, append the Unicode replacement character since | ||
| 1340 | // the first code point is a valid leading surrogate | ||
| 1341 | else | ||
| 1342 | { | ||
| 1343 | 282 | temp.append_utf8(urc); | |
| 1344 | 282 | break; | |
| 1345 | } | ||
| 1346 | } | ||
| 1347 | 6868 | ++cs; | |
| 1348 |
2/2✓ Branch 1 taken 220 times.
✓ Branch 2 taken 3214 times.
|
6868 | if(BOOST_JSON_UNLIKELY(*cs != 'u')) |
| 1349 | { | ||
| 1350 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 205 times.
|
440 | if (!allow_bad_utf16) |
| 1351 | { | ||
| 1352 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1353 | = BOOST_CURRENT_LOCATION; | ||
| 1354 | 30 | return fail(cs.begin(), error::syntax, &loc); | |
| 1355 | } | ||
| 1356 | // Otherwise, append the Unicode replacement character since | ||
| 1357 | // the first code point is a valid leading surrogate | ||
| 1358 | else | ||
| 1359 | { | ||
| 1360 | 410 | temp.append_utf8(urc); | |
| 1361 | 410 | goto do_str3; | |
| 1362 | } | ||
| 1363 | } | ||
| 1364 | 6428 | ++cs; | |
| 1365 | 6428 | digit = detail::load_little_endian<4>(cs.begin()); | |
| 1366 | 6428 | d4 = detail::hex_digit(static_cast< | |
| 1367 | 6428 | unsigned char>(digit >> 24)); | |
| 1368 | 6428 | d3 = detail::hex_digit(static_cast< | |
| 1369 | 6428 | unsigned char>(digit >> 16)); | |
| 1370 | 6428 | d2 = detail::hex_digit(static_cast< | |
| 1371 | 6428 | unsigned char>(digit >> 8)); | |
| 1372 | 6428 | d1 = detail::hex_digit(static_cast< | |
| 1373 | unsigned char>(digit)); | ||
| 1374 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 3124 times.
|
6428 | if(BOOST_JSON_UNLIKELY( |
| 1375 | (d1 | d2 | d3 | d4) == -1)) | ||
| 1376 | { | ||
| 1377 |
2/2✓ Branch 0 taken 75 times.
✓ Branch 1 taken 15 times.
|
180 | if(d1 != -1) |
| 1378 | 150 | ++cs; | |
| 1379 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
|
180 | if(d2 != -1) |
| 1380 | 90 | ++cs; | |
| 1381 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 75 times.
|
180 | if(d3 != -1) |
| 1382 | 30 | ++cs; | |
| 1383 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1384 | = BOOST_CURRENT_LOCATION; | ||
| 1385 | 180 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1386 | } | ||
| 1387 | 6248 | unsigned u2 = | |
| 1388 | 6248 | (d1 << 12) + (d2 << 8) + | |
| 1389 | 6248 | (d3 << 4) + d4; | |
| 1390 | // Check if the second code point is a valid trailing surrogate. | ||
| 1391 | // Valid trailing surrogates are [DC00, DFFF] | ||
| 1392 |
6/6✓ Branch 0 taken 2310 times.
✓ Branch 1 taken 814 times.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 1771 times.
✓ Branch 4 taken 1353 times.
✓ Branch 5 taken 1771 times.
|
6248 | if(BOOST_JSON_UNLIKELY( |
| 1393 | u2 < 0xdc00 || u2 > 0xdfff)) | ||
| 1394 | { | ||
| 1395 | // If not valid and the parser does not allow it, return an error. | ||
| 1396 |
2/2✓ Branch 0 taken 136 times.
✓ Branch 1 taken 1217 times.
|
2706 | if(!allow_bad_utf16) |
| 1397 | { | ||
| 1398 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1399 | = BOOST_CURRENT_LOCATION; | ||
| 1400 | 272 | return fail(cs.begin(), error::illegal_trailing_surrogate, | |
| 1401 | 272 | &loc); | |
| 1402 | } | ||
| 1403 | // Append the replacement character for the | ||
| 1404 | // first leading surrogate. | ||
| 1405 | 2434 | cs += 4; | |
| 1406 | 2434 | temp.append_utf8(urc); | |
| 1407 | // Check if the second code point is a | ||
| 1408 | // valid unicode scalar value (invalid leading | ||
| 1409 | // or trailing surrogate) | ||
| 1410 |
3/4✓ Branch 0 taken 1217 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 524 times.
✓ Branch 3 taken 693 times.
|
2434 | if (u2 < 0xd800 || u2 > 0xdbff) |
| 1411 | { | ||
| 1412 | 1048 | temp.append_utf8(u2); | |
| 1413 | 1048 | break; | |
| 1414 | } | ||
| 1415 | // If it is a valid leading surrogate | ||
| 1416 | else | ||
| 1417 | { | ||
| 1418 | 1386 | u1_ = u2; | |
| 1419 | 1386 | goto do_sur1; | |
| 1420 | } | ||
| 1421 | } | ||
| 1422 | 3542 | cs += 4; | |
| 1423 | // Calculate the Unicode code point from the surrogate pair and | ||
| 1424 | // append the UTF-8 representation. | ||
| 1425 | 3542 | unsigned cp = | |
| 1426 | 3542 | ((u1 - 0xd800) << 10) + | |
| 1427 | ((u2 - 0xdc00)) + | ||
| 1428 | 0x10000; | ||
| 1429 | // utf-16 surrogate pair | ||
| 1430 | 3542 | temp.append_utf8(cp); | |
| 1431 | 3542 | break; | |
| 1432 | } | ||
| 1433 | // flush | ||
| 1434 |
2/2✓ Branch 1 taken 1722 times.
✓ Branch 2 taken 4269 times.
|
11982 | if(BOOST_JSON_LIKELY(! temp.empty())) |
| 1435 | { | ||
| 1436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
6 | BOOST_ASSERT(total <= max_size); |
| 1437 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1722 times.
|
3444 | if(BOOST_JSON_UNLIKELY( |
| 1438 | temp.size() > max_size - total)) | ||
| 1439 | { | ||
| 1440 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1441 | = BOOST_CURRENT_LOCATION; | ||
| 1442 | ✗ | return fail(cs.begin(), ev_too_large, &loc); | |
| 1443 | } | ||
| 1444 | 3444 | total += temp.size(); | |
| 1445 | { | ||
| 1446 | 3164 | bool r = is_key | |
| 1447 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1722 times.
✗ Branch 4 not taken.
✗ Branch 3 not taken.
|
3444 | ? h_.on_key_part(temp.get(), total, ec_) |
| 1448 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 1 not taken.
|
3444 | : h_.on_string_part(temp.get(), total, ec_); |
| 1449 | |||
| 1450 |
2/2✓ Branch 0 taken 140 times.
✓ Branch 1 taken 1442 times.
|
3164 | if(BOOST_JSON_UNLIKELY(!r)) |
| 1451 | { | ||
| 1452 | 280 | return fail(cs.begin()); | |
| 1453 | } | ||
| 1454 | } | ||
| 1455 | 2884 | temp.clear(); | |
| 1456 | 2884 | cs.clip(temp.max_size()); | |
| 1457 | } | ||
| 1458 | 11422 | ++cs; | |
| 1459 | // utf-16 escape | ||
| 1460 | 12206 | do_str4: | |
| 1461 |
2/2✓ Branch 1 taken 392 times.
✓ Branch 2 taken 5711 times.
|
12206 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1462 |
1/1✓ Branch 2 taken 392 times.
|
784 | return maybe_suspend(cs.begin(), state::str4); |
| 1463 | 11422 | digit = detail::hex_digit(*cs); | |
| 1464 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 5661 times.
|
11422 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1465 | { | ||
| 1466 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1467 | = BOOST_CURRENT_LOCATION; | ||
| 1468 | 100 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1469 | } | ||
| 1470 | 11322 | ++cs; | |
| 1471 | 11322 | u1_ = digit << 12; | |
| 1472 | 12102 | do_str5: | |
| 1473 |
2/2✓ Branch 1 taken 390 times.
✓ Branch 2 taken 5661 times.
|
12102 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1474 |
1/1✓ Branch 2 taken 390 times.
|
780 | return maybe_suspend(cs.begin(), state::str5); |
| 1475 | 11322 | digit = detail::hex_digit(*cs); | |
| 1476 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5641 times.
|
11322 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1477 | { | ||
| 1478 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1479 | = BOOST_CURRENT_LOCATION; | ||
| 1480 | 40 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1481 | } | ||
| 1482 | 11282 | ++cs; | |
| 1483 | 11282 | u1_ += digit << 8; | |
| 1484 | 12060 | do_str6: | |
| 1485 |
2/2✓ Branch 1 taken 389 times.
✓ Branch 2 taken 5641 times.
|
12060 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1486 |
1/1✓ Branch 2 taken 389 times.
|
778 | return maybe_suspend(cs.begin(), state::str6); |
| 1487 | 11282 | digit = detail::hex_digit(*cs); | |
| 1488 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5621 times.
|
11282 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1489 | { | ||
| 1490 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1491 | = BOOST_CURRENT_LOCATION; | ||
| 1492 | 40 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1493 | } | ||
| 1494 | 11242 | ++cs; | |
| 1495 | 11242 | u1_ += digit << 4; | |
| 1496 | 12014 | do_str7: | |
| 1497 |
2/2✓ Branch 1 taken 386 times.
✓ Branch 2 taken 5621 times.
|
12014 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1498 |
1/1✓ Branch 2 taken 386 times.
|
772 | return maybe_suspend(cs.begin(), state::str7); |
| 1499 | 11242 | digit = detail::hex_digit(*cs); | |
| 1500 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 5586 times.
|
11242 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1501 | { | ||
| 1502 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1503 | = BOOST_CURRENT_LOCATION; | ||
| 1504 | 70 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1505 | } | ||
| 1506 | 11172 | ++cs; | |
| 1507 | 11172 | u1_ += digit; | |
| 1508 |
6/6✓ Branch 0 taken 4605 times.
✓ Branch 1 taken 981 times.
✓ Branch 2 taken 453 times.
✓ Branch 3 taken 4152 times.
✓ Branch 4 taken 1434 times.
✓ Branch 5 taken 4152 times.
|
11172 | if(BOOST_JSON_LIKELY( |
| 1509 | u1_ < 0xd800 || u1_ > 0xdfff)) | ||
| 1510 | { | ||
| 1511 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1434 times.
|
2868 | BOOST_ASSERT(temp.empty()); |
| 1512 | // utf-8 codepoint | ||
| 1513 | 2868 | temp.append_utf8(u1_); | |
| 1514 | 2868 | break; | |
| 1515 | } | ||
| 1516 |
2/2✓ Branch 0 taken 1585 times.
✓ Branch 1 taken 2567 times.
|
8304 | if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff)) |
| 1517 | { | ||
| 1518 | // If it's an illegal leading surrogate and | ||
| 1519 | // the parser does not allow it, return an error. | ||
| 1520 |
2/2✓ Branch 0 taken 209 times.
✓ Branch 1 taken 1376 times.
|
3170 | if(!allow_bad_utf16) |
| 1521 | { | ||
| 1522 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1523 | = BOOST_CURRENT_LOCATION; | ||
| 1524 | 418 | return fail(cs.begin(), error::illegal_leading_surrogate, &loc); | |
| 1525 | } | ||
| 1526 | // Otherwise, append the Unicode replacement character | ||
| 1527 | else | ||
| 1528 | { | ||
| 1529 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1376 times.
|
2752 | BOOST_ASSERT(temp.empty()); |
| 1530 | 2752 | temp.append_utf8(urc); | |
| 1531 | 2752 | break; | |
| 1532 | } | ||
| 1533 | } | ||
| 1534 | 5134 | do_sur1: | |
| 1535 |
2/2✓ Branch 1 taken 232 times.
✓ Branch 2 taken 3560 times.
|
7584 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1536 |
1/1✓ Branch 2 taken 232 times.
|
464 | return maybe_suspend(cs.begin(), state::sur1); |
| 1537 |
2/2✓ Branch 1 taken 952 times.
✓ Branch 2 taken 2608 times.
|
7120 | if(BOOST_JSON_UNLIKELY(*cs != '\\')) |
| 1538 | { | ||
| 1539 | // If the next character is not a backslash and | ||
| 1540 | // the parser does not allow it, return a syntax error. | ||
| 1541 |
2/2✓ Branch 0 taken 149 times.
✓ Branch 1 taken 803 times.
|
1904 | if(!allow_bad_utf16) |
| 1542 | { | ||
| 1543 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1544 | = BOOST_CURRENT_LOCATION; | ||
| 1545 | 298 | return fail(cs.begin(), error::syntax, &loc); | |
| 1546 | } | ||
| 1547 | // Otherwise, append the Unicode replacement character since | ||
| 1548 | // the first code point is a valid leading surrogate | ||
| 1549 | else | ||
| 1550 | { | ||
| 1551 | 1606 | temp.append_utf8(urc); | |
| 1552 | 1606 | break; | |
| 1553 | } | ||
| 1554 | } | ||
| 1555 | 5216 | ++cs; | |
| 1556 | 5592 | do_sur2: | |
| 1557 |
2/2✓ Branch 1 taken 188 times.
✓ Branch 2 taken 2608 times.
|
5592 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1558 |
1/1✓ Branch 2 taken 188 times.
|
376 | return maybe_suspend(cs.begin(), state::sur2); |
| 1559 |
2/2✓ Branch 1 taken 396 times.
✓ Branch 2 taken 2212 times.
|
5216 | if(BOOST_JSON_UNLIKELY(*cs != 'u')) |
| 1560 | { | ||
| 1561 |
2/2✓ Branch 0 taken 65 times.
✓ Branch 1 taken 331 times.
|
792 | if (!allow_bad_utf16) |
| 1562 | { | ||
| 1563 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1564 | = BOOST_CURRENT_LOCATION; | ||
| 1565 | 130 | return fail(cs.begin(), error::syntax, &loc); | |
| 1566 | } | ||
| 1567 | // Otherwise, append the Unicode replacement character since | ||
| 1568 | // the first code point is a valid leading surrogate | ||
| 1569 | else | ||
| 1570 | { | ||
| 1571 | 662 | temp.append_utf8(urc); | |
| 1572 | 662 | goto do_str3; | |
| 1573 | } | ||
| 1574 | } | ||
| 1575 | 4424 | ++cs; | |
| 1576 | 4752 | do_sur3: | |
| 1577 |
2/2✓ Branch 1 taken 164 times.
✓ Branch 2 taken 2212 times.
|
4752 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1578 |
1/1✓ Branch 2 taken 164 times.
|
328 | return maybe_suspend(cs.begin(), state::sur3); |
| 1579 | 4424 | digit = detail::hex_digit(*cs); | |
| 1580 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 2177 times.
|
4424 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1581 | { | ||
| 1582 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1583 | = BOOST_CURRENT_LOCATION; | ||
| 1584 | 70 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1585 | } | ||
| 1586 | 4354 | ++cs; | |
| 1587 | 4354 | u2_ = digit << 12; | |
| 1588 | 4678 | do_sur4: | |
| 1589 |
2/2✓ Branch 1 taken 162 times.
✓ Branch 2 taken 2177 times.
|
4678 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1590 |
1/1✓ Branch 2 taken 162 times.
|
324 | return maybe_suspend(cs.begin(), state::sur4); |
| 1591 | 4354 | digit = detail::hex_digit(*cs); | |
| 1592 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 2142 times.
|
4354 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1593 | { | ||
| 1594 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1595 | = BOOST_CURRENT_LOCATION; | ||
| 1596 | 70 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1597 | } | ||
| 1598 | 4284 | ++cs; | |
| 1599 | 4284 | u2_ += digit << 8; | |
| 1600 | 4604 | do_sur5: | |
| 1601 |
2/2✓ Branch 1 taken 160 times.
✓ Branch 2 taken 2142 times.
|
4604 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1602 |
1/1✓ Branch 2 taken 160 times.
|
320 | return maybe_suspend(cs.begin(), state::sur5); |
| 1603 | 4284 | digit = detail::hex_digit(*cs); | |
| 1604 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2122 times.
|
4284 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1605 | { | ||
| 1606 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1607 | = BOOST_CURRENT_LOCATION; | ||
| 1608 | 40 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1609 | } | ||
| 1610 | 4244 | ++cs; | |
| 1611 | 4244 | u2_ += digit << 4; | |
| 1612 | 4560 | do_sur6: | |
| 1613 |
2/2✓ Branch 1 taken 158 times.
✓ Branch 2 taken 2122 times.
|
4560 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1614 |
1/1✓ Branch 2 taken 158 times.
|
316 | return maybe_suspend(cs.begin(), state::sur6); |
| 1615 | 4244 | digit = detail::hex_digit(*cs); | |
| 1616 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2102 times.
|
4244 | if(BOOST_JSON_UNLIKELY(digit == -1)) |
| 1617 | { | ||
| 1618 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1619 | = BOOST_CURRENT_LOCATION; | ||
| 1620 | 40 | return fail(cs.begin(), error::expected_hex_digit, &loc); | |
| 1621 | } | ||
| 1622 | 4204 | ++cs; | |
| 1623 | 4204 | u2_ += digit; | |
| 1624 | // Check if the second code point is a valid trailing surrogate. | ||
| 1625 | // Valid trailing surrogates are [DC00, DFFF] | ||
| 1626 |
6/6✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 340 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 1522 times.
✓ Branch 4 taken 580 times.
✓ Branch 5 taken 1522 times.
|
4204 | if(BOOST_JSON_UNLIKELY( |
| 1627 | u2_ < 0xdc00 || u2_ > 0xdfff)) | ||
| 1628 | { | ||
| 1629 | // If not valid and the parser does not allow it, return an error. | ||
| 1630 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 520 times.
|
1160 | if(!allow_bad_utf16) |
| 1631 | { | ||
| 1632 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1633 | = BOOST_CURRENT_LOCATION; | ||
| 1634 | 120 | return fail(cs.begin(), error::illegal_trailing_surrogate, &loc); | |
| 1635 | } | ||
| 1636 | // Append the replacement character for the | ||
| 1637 | // first leading surrogate. | ||
| 1638 | 1040 | temp.append_utf8(urc); | |
| 1639 | // Check if the second code point is a | ||
| 1640 | // valid unicode scalar value (invalid leading | ||
| 1641 | // or trailing surrogate) | ||
| 1642 |
3/4✓ Branch 0 taken 520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 220 times.
✓ Branch 3 taken 300 times.
|
1040 | if (u2_ < 0xd800 || u2_ > 0xdbff) |
| 1643 | { | ||
| 1644 | 440 | temp.append_utf8(u2_); | |
| 1645 | 440 | break; | |
| 1646 | } | ||
| 1647 | // If it is a valid leading surrogate | ||
| 1648 | else | ||
| 1649 | { | ||
| 1650 | 600 | u1_ = u2_; | |
| 1651 | 600 | goto do_sur1; | |
| 1652 | } | ||
| 1653 | } | ||
| 1654 | // Calculate the Unicode code point from the surrogate pair and | ||
| 1655 | // append the UTF-8 representation. | ||
| 1656 | 3044 | unsigned cp = | |
| 1657 | 3044 | ((u1_ - 0xd800) << 10) + | |
| 1658 | 3044 | ((u2_ - 0xdc00)) + | |
| 1659 | 0x10000; | ||
| 1660 | // utf-16 surrogate pair | ||
| 1661 | 3044 | temp.append_utf8(cp); | |
| 1662 | } | ||
| 1663 | |||
| 1664 | // flush | ||
| 1665 |
6/6✓ Branch 1 taken 12190 times.
✓ Branch 2 taken 460 times.
✓ Branch 4 taken 8409 times.
✓ Branch 5 taken 3781 times.
✓ Branch 6 taken 8869 times.
✓ Branch 7 taken 3781 times.
|
25300 | if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\') |
| 1666 | 17738 | break; | |
| 1667 | } | ||
| 1668 | |||
| 1669 |
1/2✓ Branch 1 taken 8869 times.
✗ Branch 2 not taken.
|
17738 | if(BOOST_JSON_LIKELY( temp.size() )) |
| 1670 | { | ||
| 1671 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 433 times.
|
866 | BOOST_ASSERT(total <= max_size); |
| 1672 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8869 times.
|
17738 | if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total )) |
| 1673 | { | ||
| 1674 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1675 | = BOOST_CURRENT_LOCATION; | ||
| 1676 | ✗ | return fail(cs.begin(), ev_too_large, &loc); | |
| 1677 | } | ||
| 1678 | |||
| 1679 | 17738 | total += temp.size(); | |
| 1680 | 16112 | bool const r = is_key | |
| 1681 |
3/4✓ Branch 0 taken 717 times.
✓ Branch 1 taken 8152 times.
✓ Branch 4 taken 5 times.
✗ Branch 3 not taken.
|
17738 | ? h_.on_key_part(temp.get(), total, ec_) |
| 1682 |
1/2✓ Branch 2 taken 428 times.
✗ Branch 1 not taken.
|
16304 | : h_.on_string_part(temp.get(), total, ec_); |
| 1683 |
2/2✓ Branch 0 taken 813 times.
✓ Branch 1 taken 7243 times.
|
16112 | if(BOOST_JSON_UNLIKELY( !r )) |
| 1684 | 1626 | return fail( cs.begin() ); | |
| 1685 | } | ||
| 1686 | |||
| 1687 | 14486 | return cs.begin(); | |
| 1688 | } | ||
| 1689 | |||
| 1690 | //---------------------------------------------------------- | ||
| 1691 | |||
| 1692 | template<class Handler> | ||
| 1693 | template< | ||
| 1694 | bool StackEmpty_, | ||
| 1695 | bool AllowComments_/*, | ||
| 1696 | bool AllowTrailing_, | ||
| 1697 | bool AllowBadUTF8_*/> | ||
| 1698 | const char* | ||
| 1699 | 218350 | basic_parser<Handler>:: | |
| 1700 | parse_object(const char* p, | ||
| 1701 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 1702 | std::integral_constant<bool, AllowComments_> allow_comments, | ||
| 1703 | /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, | ||
| 1704 | /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, | ||
| 1705 | bool allow_bad_utf16) | ||
| 1706 | { | ||
| 1707 | 218350 | detail::const_stream_wrapper cs(p, end_); | |
| 1708 | std::size_t size; | ||
| 1709 |
5/6✓ Branch 1 taken 35047 times.
✓ Branch 2 taken 74128 times.
✓ Branch 4 taken 35047 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35047 times.
✓ Branch 7 taken 74128 times.
|
218350 | if(! stack_empty && ! st_.empty()) |
| 1710 | { | ||
| 1711 | // resume | ||
| 1712 | state st; | ||
| 1713 |
1/1✓ Branch 1 taken 35047 times.
|
70094 | st_.pop(st); |
| 1714 |
1/1✓ Branch 1 taken 35047 times.
|
70094 | st_.pop(size); |
| 1715 |
11/12✗ Branch 0 not taken.
✓ Branch 1 taken 1595 times.
✓ Branch 2 taken 235 times.
✓ Branch 3 taken 12640 times.
✓ Branch 4 taken 1690 times.
✓ Branch 5 taken 251 times.
✓ Branch 6 taken 1591 times.
✓ Branch 7 taken 15444 times.
✓ Branch 8 taken 426 times.
✓ Branch 9 taken 660 times.
✓ Branch 10 taken 181 times.
✓ Branch 11 taken 334 times.
|
70094 | switch(st) |
| 1716 | { | ||
| 1717 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 1718 | 3190 | case state::obj1: goto do_obj1; | |
| 1719 | 470 | case state::obj2: goto do_obj2; | |
| 1720 | 25280 | case state::obj3: goto do_obj3; | |
| 1721 | 3380 | case state::obj4: goto do_obj4; | |
| 1722 | 502 | case state::obj5: goto do_obj5; | |
| 1723 | 3182 | case state::obj6: goto do_obj6; | |
| 1724 | 30888 | case state::obj7: goto do_obj7; | |
| 1725 | 852 | case state::obj8: goto do_obj8; | |
| 1726 | 1320 | case state::obj9: goto do_obj9; | |
| 1727 | 362 | case state::obj10: goto do_obj10; | |
| 1728 | 668 | case state::obj11: goto do_obj11; | |
| 1729 | } | ||
| 1730 | } | ||
| 1731 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 74128 times.
|
148256 | BOOST_ASSERT(*cs == '{'); |
| 1732 | 148256 | size = 0; | |
| 1733 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 74125 times.
|
148256 | if(BOOST_JSON_UNLIKELY(! depth_)) |
| 1734 | { | ||
| 1735 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 1736 | 6 | return fail(cs.begin(), error::too_deep, &loc); | |
| 1737 | } | ||
| 1738 | 148250 | --depth_; | |
| 1739 |
5/5✓ Branch 1 taken 19060 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 17019 times.
✓ Branch 5 taken 1 times.
✓ Branch 2 taken 34953 times.
|
148250 | if(BOOST_JSON_UNLIKELY( |
| 1740 | ! h_.on_object_begin(ec_))) | ||
| 1741 | 4080 | return fail(cs.begin()); | |
| 1742 | 140094 | ++cs; | |
| 1743 | // object: | ||
| 1744 | // '{' *ws '}' | ||
| 1745 | // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}' | ||
| 1746 | 147226 | do_obj1: | |
| 1747 | 147226 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1748 |
2/2✓ Branch 1 taken 1629 times.
✓ Branch 2 taken 71984 times.
|
147226 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1749 |
1/1✓ Branch 2 taken 1629 times.
|
3258 | return maybe_suspend(cs.begin(), state::obj1, size); |
| 1750 |
2/2✓ Branch 1 taken 69085 times.
✓ Branch 2 taken 2899 times.
|
143968 | if(BOOST_JSON_LIKELY(*cs != '}')) |
| 1751 | { | ||
| 1752 |
2/2✓ Branch 1 taken 2411 times.
✓ Branch 2 taken 66674 times.
|
138170 | if(BOOST_JSON_UNLIKELY(*cs != '\x22')) |
| 1753 | { | ||
| 1754 |
6/6✓ Branch 1 taken 2244 times.
✓ Branch 2 taken 167 times.
✓ Branch 4 taken 2139 times.
✓ Branch 5 taken 105 times.
✓ Branch 6 taken 2139 times.
✓ Branch 7 taken 272 times.
|
4822 | if(allow_comments && *cs == '/') |
| 1755 | { | ||
| 1756 | 4278 | do_obj2: | |
| 1757 |
1/1✓ Branch 3 taken 2290 times.
|
4748 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1758 |
2/2✓ Branch 1 taken 319 times.
✓ Branch 2 taken 1971 times.
|
4580 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1759 |
1/1✓ Branch 1 taken 319 times.
|
638 | return suspend_or_fail(state::obj2, size); |
| 1760 | 3942 | goto do_obj1; | |
| 1761 | } | ||
| 1762 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1763 | = BOOST_CURRENT_LOCATION; | ||
| 1764 | 544 | return fail(cs.begin(), error::syntax, &loc); | |
| 1765 | } | ||
| 1766 | 133348 | loop: | |
| 1767 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 80825 times.
|
161652 | if(BOOST_JSON_UNLIKELY(++size > |
| 1768 | Handler::max_object_size)) | ||
| 1769 | { | ||
| 1770 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1771 | = BOOST_CURRENT_LOCATION; | ||
| 1772 | 2 | return fail(cs.begin(), error::object_too_large, &loc); | |
| 1773 | } | ||
| 1774 | 161650 | do_obj3: | |
| 1775 |
1/1✓ Branch 2 taken 90509 times.
|
186930 | cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16); |
| 1776 |
2/2✓ Branch 1 taken 15584 times.
✓ Branch 2 taken 74925 times.
|
181018 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1777 |
1/1✓ Branch 1 taken 15584 times.
|
31168 | return suspend_or_fail(state::obj3, size); |
| 1778 | 149850 | do_obj4: | |
| 1779 | 158172 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1780 |
2/2✓ Branch 1 taken 1705 times.
✓ Branch 2 taken 77381 times.
|
158172 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1781 |
1/1✓ Branch 2 taken 1705 times.
|
3410 | return maybe_suspend(cs.begin(), state::obj4, size); |
| 1782 |
2/2✓ Branch 1 taken 2925 times.
✓ Branch 2 taken 74456 times.
|
154762 | if(BOOST_JSON_UNLIKELY(*cs != ':')) |
| 1783 | { | ||
| 1784 |
6/6✓ Branch 1 taken 2821 times.
✓ Branch 2 taken 104 times.
✓ Branch 4 taken 2779 times.
✓ Branch 5 taken 42 times.
✓ Branch 6 taken 2779 times.
✓ Branch 7 taken 146 times.
|
5850 | if(allow_comments && *cs == '/') |
| 1785 | { | ||
| 1786 | 5558 | do_obj5: | |
| 1787 |
1/1✓ Branch 3 taken 2876 times.
|
6060 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1788 |
2/2✓ Branch 1 taken 405 times.
✓ Branch 2 taken 2471 times.
|
5752 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1789 |
1/1✓ Branch 1 taken 405 times.
|
810 | return suspend_or_fail(state::obj5, size); |
| 1790 | 4942 | goto do_obj4; | |
| 1791 | } | ||
| 1792 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1793 | = BOOST_CURRENT_LOCATION; | ||
| 1794 | 292 | return fail(cs.begin(), error::syntax, &loc); | |
| 1795 | } | ||
| 1796 | 148912 | ++cs; | |
| 1797 | 152094 | do_obj6: | |
| 1798 | 152094 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1799 |
2/2✓ Branch 1 taken 1621 times.
✓ Branch 2 taken 74426 times.
|
152094 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1800 |
1/1✓ Branch 2 taken 1621 times.
|
3242 | return maybe_suspend(cs.begin(), state::obj6, size); |
| 1801 | 148852 | do_obj7: | |
| 1802 |
1/1✓ Branch 2 taken 82521 times.
|
179740 | cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 1803 |
2/2✓ Branch 1 taken 23589 times.
✓ Branch 2 taken 58932 times.
|
165042 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1804 |
1/1✓ Branch 1 taken 23589 times.
|
47178 | return suspend_or_fail(state::obj7, size); |
| 1805 | 117864 | do_obj8: | |
| 1806 | 122388 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1807 |
2/2✓ Branch 1 taken 441 times.
✓ Branch 2 taken 60753 times.
|
122388 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1808 |
1/1✓ Branch 2 taken 441 times.
|
882 | return maybe_suspend(cs.begin(), state::obj8, size); |
| 1809 |
2/2✓ Branch 1 taken 17792 times.
✓ Branch 2 taken 42961 times.
|
121506 | if(BOOST_JSON_LIKELY(*cs == ',')) |
| 1810 | { | ||
| 1811 | 35584 | ++cs; | |
| 1812 | 39414 | do_obj9: | |
| 1813 | 39414 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1814 |
2/2✓ Branch 1 taken 690 times.
✓ Branch 2 taken 19017 times.
|
39414 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1815 |
1/1✓ Branch 2 taken 690 times.
|
1380 | return maybe_suspend(cs.begin(), state::obj9, size); |
| 1816 | |||
| 1817 | // loop for next element | ||
| 1818 |
2/2✓ Branch 1 taken 14152 times.
✓ Branch 2 taken 4865 times.
|
38034 | if(BOOST_JSON_LIKELY(*cs == '\x22')) |
| 1819 | 28304 | goto loop; | |
| 1820 |
6/6✓ Branch 0 taken 3235 times.
✓ Branch 1 taken 1630 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 3221 times.
✓ Branch 5 taken 1644 times.
✓ Branch 6 taken 3221 times.
|
9730 | if(! allow_trailing || *cs != '}') |
| 1821 | { | ||
| 1822 |
6/6✓ Branch 1 taken 1447 times.
✓ Branch 2 taken 197 times.
✓ Branch 4 taken 1433 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 1433 times.
✓ Branch 7 taken 211 times.
|
3288 | if(allow_comments && *cs == '/') |
| 1823 | { | ||
| 1824 | 2866 | do_obj10: | |
| 1825 |
1/1✓ Branch 3 taken 1525 times.
|
3228 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1826 |
2/2✓ Branch 1 taken 270 times.
✓ Branch 2 taken 1255 times.
|
3050 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1827 |
1/1✓ Branch 1 taken 270 times.
|
540 | return suspend_or_fail(state::obj10, size); |
| 1828 | 2510 | goto do_obj9; | |
| 1829 | } | ||
| 1830 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1831 | = BOOST_CURRENT_LOCATION; | ||
| 1832 | 422 | return fail(cs.begin(), error::syntax, &loc); | |
| 1833 | } | ||
| 1834 | } | ||
| 1835 |
2/2✓ Branch 1 taken 2325 times.
✓ Branch 2 taken 40636 times.
|
85922 | else if(BOOST_JSON_UNLIKELY(*cs != '}')) |
| 1836 | { | ||
| 1837 |
6/6✓ Branch 1 taken 2200 times.
✓ Branch 2 taken 125 times.
✓ Branch 4 taken 2172 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 2172 times.
✓ Branch 7 taken 153 times.
|
4650 | if(allow_comments && *cs == '/') |
| 1838 | { | ||
| 1839 | 4344 | do_obj11: | |
| 1840 |
1/1✓ Branch 3 taken 2338 times.
|
5012 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1841 |
2/2✓ Branch 1 taken 502 times.
✓ Branch 2 taken 1836 times.
|
4676 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1842 |
1/1✓ Branch 1 taken 502 times.
|
1004 | return suspend_or_fail(state::obj11, size); |
| 1843 | 3672 | goto do_obj8; | |
| 1844 | } | ||
| 1845 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1846 | = BOOST_CURRENT_LOCATION; | ||
| 1847 | 306 | return fail(cs.begin(), error::syntax, &loc); | |
| 1848 | } | ||
| 1849 | // got closing brace, fall through | ||
| 1850 | } | ||
| 1851 |
3/5✓ Branch 1 taken 40589 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39086 times.
✓ Branch 5 taken 1 times.
✗ Branch 2 not taken.
|
93512 | if(BOOST_JSON_UNLIKELY( |
| 1852 | ! h_.on_object_end(size, ec_))) | ||
| 1853 | 3004 | return fail(cs.begin()); | |
| 1854 | 87426 | ++depth_; | |
| 1855 | 87426 | ++cs; | |
| 1856 | 87426 | return cs.begin(); | |
| 1857 | } | ||
| 1858 | |||
| 1859 | //---------------------------------------------------------- | ||
| 1860 | |||
| 1861 | template<class Handler> | ||
| 1862 | template< | ||
| 1863 | bool StackEmpty_, | ||
| 1864 | bool AllowComments_/*, | ||
| 1865 | bool AllowTrailing_, | ||
| 1866 | bool AllowBadUTF8_*/> | ||
| 1867 | const char* | ||
| 1868 | 52668 | basic_parser<Handler>:: | |
| 1869 | parse_array(const char* p, | ||
| 1870 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 1871 | std::integral_constant<bool, AllowComments_> allow_comments, | ||
| 1872 | /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, | ||
| 1873 | /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, | ||
| 1874 | bool allow_bad_utf16) | ||
| 1875 | { | ||
| 1876 | 52668 | detail::const_stream_wrapper cs(p, end_); | |
| 1877 | std::size_t size; | ||
| 1878 |
5/6✓ Branch 1 taken 5716 times.
✓ Branch 2 taken 20618 times.
✓ Branch 4 taken 5716 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5716 times.
✓ Branch 7 taken 20618 times.
|
52668 | if(! stack_empty && ! st_.empty()) |
| 1879 | { | ||
| 1880 | // resume | ||
| 1881 | state st; | ||
| 1882 |
1/1✓ Branch 1 taken 5716 times.
|
11432 | st_.pop(st); |
| 1883 |
1/1✓ Branch 1 taken 5716 times.
|
11432 | st_.pop(size); |
| 1884 |
6/7✗ Branch 0 not taken.
✓ Branch 1 taken 1052 times.
✓ Branch 2 taken 384 times.
✓ Branch 3 taken 2924 times.
✓ Branch 4 taken 391 times.
✓ Branch 5 taken 671 times.
✓ Branch 6 taken 294 times.
|
11432 | switch(st) |
| 1885 | { | ||
| 1886 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 1887 | 2104 | case state::arr1: goto do_arr1; | |
| 1888 | 768 | case state::arr2: goto do_arr2; | |
| 1889 | 5848 | case state::arr3: goto do_arr3; | |
| 1890 | 782 | case state::arr4: goto do_arr4; | |
| 1891 | 1342 | case state::arr5: goto do_arr5; | |
| 1892 | 588 | case state::arr6: goto do_arr6; | |
| 1893 | } | ||
| 1894 | } | ||
| 1895 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20618 times.
|
41236 | BOOST_ASSERT(*cs == '['); |
| 1896 | 41236 | size = 0; | |
| 1897 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 20584 times.
|
41236 | if(BOOST_JSON_UNLIKELY(! depth_)) |
| 1898 | { | ||
| 1899 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 1900 | 68 | return fail(cs.begin(), error::too_deep, &loc); | |
| 1901 | } | ||
| 1902 | 41168 | --depth_; | |
| 1903 |
4/5✓ Branch 1 taken 6565 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 5753 times.
✗ Branch 5 not taken.
✓ Branch 2 taken 2136 times.
|
41168 | if(BOOST_JSON_UNLIKELY( |
| 1904 | ! h_.on_array_begin(ec_))) | ||
| 1905 | 1624 | return fail(cs.begin()); | |
| 1906 | 37932 | ++cs; | |
| 1907 | // array: | ||
| 1908 | // '[' *ws ']' | ||
| 1909 | // '[' *ws value *ws *[ ',' *ws value *ws ] ']' | ||
| 1910 | 43102 | do_arr1: | |
| 1911 | 43102 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1912 |
2/2✓ Branch 1 taken 1073 times.
✓ Branch 2 taken 20478 times.
|
43102 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1913 |
1/1✓ Branch 2 taken 1073 times.
|
2146 | return maybe_suspend(cs.begin(), state::arr1, size); |
| 1914 |
2/2✓ Branch 1 taken 18730 times.
✓ Branch 2 taken 1748 times.
|
40956 | if(BOOST_JSON_LIKELY(*cs != ']')) |
| 1915 | { | ||
| 1916 | 37460 | loop: | |
| 1917 |
6/6✓ Branch 1 taken 7766 times.
✓ Branch 2 taken 18427 times.
✓ Branch 4 taken 1789 times.
✓ Branch 5 taken 5977 times.
✓ Branch 6 taken 1789 times.
✓ Branch 7 taken 24404 times.
|
52386 | if(allow_comments && *cs == '/') |
| 1918 | { | ||
| 1919 | 3578 | do_arr2: | |
| 1920 |
1/1✓ Branch 3 taken 2045 times.
|
4346 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1921 |
2/2✓ Branch 1 taken 512 times.
✓ Branch 2 taken 1533 times.
|
4090 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1922 |
1/1✓ Branch 1 taken 512 times.
|
1024 | return suspend_or_fail(state::arr2, size); |
| 1923 | 3066 | goto do_arr1; | |
| 1924 | } | ||
| 1925 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24403 times.
|
48808 | if(BOOST_JSON_UNLIKELY(++size > |
| 1926 | Handler::max_array_size)) | ||
| 1927 | { | ||
| 1928 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1929 | = BOOST_CURRENT_LOCATION; | ||
| 1930 | 2 | return fail(cs.begin(), error::array_too_large, &loc); | |
| 1931 | } | ||
| 1932 | 48806 | do_arr3: | |
| 1933 | // array is not empty, value required | ||
| 1934 |
1/1✓ Branch 2 taken 24696 times.
|
54654 | cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); |
| 1935 |
2/2✓ Branch 1 taken 9038 times.
✓ Branch 2 taken 15658 times.
|
49392 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1936 |
1/1✓ Branch 1 taken 9038 times.
|
18076 | return suspend_or_fail(state::arr3, size); |
| 1937 | 31316 | do_arr4: | |
| 1938 | 34558 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1939 |
2/2✓ Branch 1 taken 500 times.
✓ Branch 2 taken 16779 times.
|
34558 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1940 |
1/1✓ Branch 2 taken 500 times.
|
1000 | return maybe_suspend(cs.begin(), state::arr4, size); |
| 1941 |
2/2✓ Branch 1 taken 9176 times.
✓ Branch 2 taken 7603 times.
|
33558 | if(BOOST_JSON_LIKELY(*cs == ',')) |
| 1942 | { | ||
| 1943 | 18352 | ++cs; | |
| 1944 | 19694 | do_arr5: | |
| 1945 | 19694 | cs = detail::count_whitespace(cs.begin(), cs.end()); | |
| 1946 |
2/2✓ Branch 1 taken 701 times.
✓ Branch 2 taken 9146 times.
|
19694 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 1947 |
1/1✓ Branch 2 taken 701 times.
|
1402 | return maybe_suspend(cs.begin(), state::arr5, size); |
| 1948 | // loop for next element | ||
| 1949 |
6/6✓ Branch 0 taken 2580 times.
✓ Branch 1 taken 6566 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 1683 times.
✓ Branch 5 taken 7463 times.
✓ Branch 6 taken 1683 times.
|
18292 | if(! allow_trailing || *cs != ']') |
| 1950 | 14926 | goto loop; | |
| 1951 | } | ||
| 1952 |
2/2✓ Branch 1 taken 1969 times.
✓ Branch 2 taken 5634 times.
|
15206 | else if(BOOST_JSON_UNLIKELY(*cs != ']')) |
| 1953 | { | ||
| 1954 |
6/6✓ Branch 1 taken 1695 times.
✓ Branch 2 taken 274 times.
✓ Branch 4 taken 1541 times.
✓ Branch 5 taken 154 times.
✓ Branch 6 taken 1541 times.
✓ Branch 7 taken 428 times.
|
3938 | if(allow_comments && *cs == '/') |
| 1955 | { | ||
| 1956 | 3082 | do_arr6: | |
| 1957 |
1/1✓ Branch 3 taken 1688 times.
|
3670 | cs = parse_comment(cs.begin(), stack_empty, std::false_type()); |
| 1958 |
2/2✓ Branch 1 taken 458 times.
✓ Branch 2 taken 1230 times.
|
3376 | if(BOOST_JSON_UNLIKELY(incomplete(cs))) |
| 1959 |
1/1✓ Branch 1 taken 458 times.
|
916 | return suspend_or_fail(state::arr6, size); |
| 1960 | 2460 | goto do_arr4; | |
| 1961 | } | ||
| 1962 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 1963 | = BOOST_CURRENT_LOCATION; | ||
| 1964 | 856 | return fail(cs.begin(), error::syntax, &loc); | |
| 1965 | } | ||
| 1966 | // got closing bracket; fall through | ||
| 1967 | } | ||
| 1968 |
3/5✓ Branch 1 taken 4658 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 4111 times.
✗ Branch 5 not taken.
✗ Branch 2 not taken.
|
18130 | if(BOOST_JSON_UNLIKELY( |
| 1969 | ! h_.on_array_end(size, ec_))) | ||
| 1970 | 1094 | return fail(cs.begin()); | |
| 1971 | 15878 | ++depth_; | |
| 1972 | 15878 | ++cs; | |
| 1973 | 15878 | return cs.begin(); | |
| 1974 | } | ||
| 1975 | |||
| 1976 | //---------------------------------------------------------- | ||
| 1977 | |||
| 1978 | template<class Handler> | ||
| 1979 | template<bool StackEmpty_, char First_, number_precision Numbers_> | ||
| 1980 | const char* | ||
| 1981 | 4253742 | basic_parser<Handler>:: | |
| 1982 | parse_number(const char* p, | ||
| 1983 | std::integral_constant<bool, StackEmpty_> stack_empty, | ||
| 1984 | std::integral_constant<char, First_> first, | ||
| 1985 | std::integral_constant<number_precision, Numbers_> mode) | ||
| 1986 | { | ||
| 1987 | 4253742 | constexpr bool precise_parsing = mode == number_precision::precise; | |
| 1988 | 4253742 | constexpr bool no_parsing = mode == number_precision::none; | |
| 1989 | |||
| 1990 | // only one of these will be true if we are not resuming | ||
| 1991 | // if negative then !zero_first && !nonzero_first | ||
| 1992 | // if zero_first then !nonzero_first && !negative | ||
| 1993 | // if nonzero_first then !zero_first && !negative | ||
| 1994 | 4253742 | bool const negative = first == '-'; | |
| 1995 | 4253742 | bool const zero_first = first == '0'; | |
| 1996 | 4253742 | bool const nonzero_first = first == '+'; | |
| 1997 | 4253742 | detail::const_stream_wrapper cs(p, end_); | |
| 1998 | number num; | ||
| 1999 | 4253742 | const char* begin = cs.begin(); | |
| 2000 |
5/6✓ Branch 1 taken 37174 times.
✓ Branch 2 taken 2089697 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 37174 times.
✓ Branch 6 taken 2089697 times.
✓ Branch 7 taken 37174 times.
|
4253742 | if(stack_empty || st_.empty()) |
| 2001 | { | ||
| 2002 | 4179394 | num.bias = 0; | |
| 2003 | 4179394 | num.exp = 0; | |
| 2004 | 4179394 | num.frac = false; | |
| 2005 | 4179394 | num_buf_.clear(); | |
| 2006 | |||
| 2007 | //---------------------------------- | ||
| 2008 | // | ||
| 2009 | // '-' | ||
| 2010 | // leading minus sign | ||
| 2011 | // | ||
| 2012 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2089697 times.
|
4179394 | BOOST_ASSERT(cs); |
| 2013 | if(negative) | ||
| 2014 | 50356 | ++cs; | |
| 2015 | |||
| 2016 | 4179394 | num.neg = negative; | |
| 2017 | 4179394 | num.frac = false; | |
| 2018 | 4179394 | num.exp = 0; | |
| 2019 | 4179394 | num.bias = 0; | |
| 2020 | |||
| 2021 | // fast path | ||
| 2022 |
2/2✓ Branch 1 taken 2028504 times.
✓ Branch 2 taken 61193 times.
|
4179394 | if( cs.remain() >= 16 + 1 + 16 ) // digits . digits |
| 2023 | { | ||
| 2024 | int n1; | ||
| 2025 | |||
| 2026 |
2/2✓ Branch 0 taken 1836 times.
✓ Branch 1 taken 8152 times.
|
19976 | if( nonzero_first || |
| 2027 | 19976 | (negative && *cs != '0') ) | |
| 2028 | { | ||
| 2029 | 4014634 | n1 = detail::count_digits( cs.begin() ); | |
| 2030 |
2/4✓ Branch 0 taken 2007317 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2007317 times.
✗ Branch 3 not taken.
|
4014634 | BOOST_ASSERT(n1 >= 0 && n1 <= 16); |
| 2031 | |||
| 2032 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1825 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 2 times.
|
3672 | if( negative && n1 == 0 && opt_.allow_infinity_and_nan ) |
| 2033 | { | ||
| 2034 |
1/1✓ Branch 1 taken 8 times.
|
18 | return parse_literal( |
| 2035 | p - 1, | ||
| 2036 | 16 | detail::literals_c<detail::literals::neg_infinity>()); | |
| 2037 | } | ||
| 2038 | |||
| 2039 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1825 times.
|
3654 | if( ! nonzero_first && n1 == 0 ) |
| 2040 | { | ||
| 2041 | // digit required | ||
| 2042 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2043 | = BOOST_CURRENT_LOCATION; | ||
| 2044 | 4 | return fail(cs.begin(), error::syntax, &loc); | |
| 2045 | } | ||
| 2046 | |||
| 2047 | BOOST_IF_CONSTEXPR( !no_parsing ) | ||
| 2048 | 4012916 | num.mant = detail::parse_unsigned( 0, cs.begin(), n1 ); | |
| 2049 | else | ||
| 2050 | 1696 | num.mant = 0; | |
| 2051 | |||
| 2052 | 4014612 | cs += n1; | |
| 2053 | |||
| 2054 | // integer or floating-point with | ||
| 2055 | // >= 16 leading digits | ||
| 2056 |
2/2✓ Branch 0 taken 2001424 times.
✓ Branch 1 taken 5882 times.
|
4014612 | if( n1 == 16 ) |
| 2057 | { | ||
| 2058 | 4002848 | goto do_num2; | |
| 2059 | } | ||
| 2060 | } | ||
| 2061 | else | ||
| 2062 | { | ||
| 2063 | // 0. floating-point or 0e integer | ||
| 2064 | 42374 | num.mant = 0; | |
| 2065 | 42374 | n1 = 0; | |
| 2066 | 42374 | ++cs; | |
| 2067 | } | ||
| 2068 | |||
| 2069 | { | ||
| 2070 | 54138 | const char c = *cs; | |
| 2071 |
2/2✓ Branch 0 taken 9870 times.
✓ Branch 1 taken 17199 times.
|
54138 | if(c != '.') |
| 2072 | { | ||
| 2073 |
2/2✓ Branch 0 taken 6576 times.
✓ Branch 1 taken 3294 times.
|
19740 | if((c | 32) == 'e') |
| 2074 | { | ||
| 2075 | 13152 | ++cs; | |
| 2076 | 13152 | goto do_exp1; | |
| 2077 | } | ||
| 2078 | BOOST_IF_CONSTEXPR( negative && !no_parsing ) | ||
| 2079 | 38 | num.mant = ~num.mant + 1; | |
| 2080 | 6588 | goto finish_signed; | |
| 2081 | } | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | // floating-point number | ||
| 2085 | |||
| 2086 | 34398 | ++cs; | |
| 2087 | |||
| 2088 | 34398 | int n2 = detail::count_digits( cs.begin() ); | |
| 2089 |
2/4✓ Branch 0 taken 17199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17199 times.
✗ Branch 3 not taken.
|
34398 | BOOST_ASSERT(n2 >= 0 && n2 <= 16); |
| 2090 | |||
| 2091 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 17196 times.
|
34398 | if( n2 == 0 ) |
| 2092 | { | ||
| 2093 | // digit required | ||
| 2094 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2095 | = BOOST_CURRENT_LOCATION; | ||
| 2096 | 6 | return fail(cs.begin(), error::syntax, &loc); | |
| 2097 | } | ||
| 2098 | |||
| 2099 | // floating-point mantissa overflow | ||
| 2100 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 17074 times.
|
34392 | if( n1 + n2 >= 19 ) |
| 2101 | { | ||
| 2102 | 244 | goto do_num7; | |
| 2103 | } | ||
| 2104 | |||
| 2105 | BOOST_IF_CONSTEXPR( !no_parsing ) | ||
| 2106 | 25710 | num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 ); | |
| 2107 | |||
| 2108 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17074 times.
|
34148 | BOOST_ASSERT(num.bias == 0); |
| 2109 | |||
| 2110 | 34148 | num.bias -= n2; | |
| 2111 | |||
| 2112 | 34148 | cs += n2; | |
| 2113 | |||
| 2114 | 34148 | char ch = *cs; | |
| 2115 | |||
| 2116 |
2/2✓ Branch 0 taken 110 times.
✓ Branch 1 taken 16964 times.
|
34148 | if( (ch | 32) == 'e' ) |
| 2117 | { | ||
| 2118 | 220 | ++cs; | |
| 2119 | 220 | goto do_exp1; | |
| 2120 | } | ||
| 2121 |
3/4✓ Branch 0 taken 10017 times.
✓ Branch 1 taken 6947 times.
✓ Branch 2 taken 10017 times.
✗ Branch 3 not taken.
|
33928 | else if( ch >= '0' && ch <= '9' ) |
| 2122 | { | ||
| 2123 | 20034 | goto do_num8; | |
| 2124 | } | ||
| 2125 | |||
| 2126 | 13894 | goto finish_dub; | |
| 2127 | } | ||
| 2128 | } | ||
| 2129 | else | ||
| 2130 | { | ||
| 2131 | 74348 | num = num_; | |
| 2132 | state st; | ||
| 2133 |
1/1✓ Branch 1 taken 37174 times.
|
74348 | st_.pop(st); |
| 2134 |
11/12✗ Branch 0 not taken.
✓ Branch 1 taken 602 times.
✓ Branch 2 taken 6338 times.
✓ Branch 3 taken 802 times.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 4537 times.
✓ Branch 6 taken 666 times.
✓ Branch 7 taken 616 times.
✓ Branch 8 taken 10944 times.
✓ Branch 9 taken 469 times.
✓ Branch 10 taken 125 times.
✓ Branch 11 taken 12023 times.
|
74348 | switch(st) |
| 2135 | { | ||
| 2136 | ✗ | default: BOOST_JSON_UNREACHABLE(); | |
| 2137 | 1204 | case state::num1: goto do_num1; | |
| 2138 | 12676 | case state::num2: goto do_num2; | |
| 2139 | 1604 | case state::num3: goto do_num3; | |
| 2140 | 104 | case state::num4: goto do_num4; | |
| 2141 | 9074 | case state::num5: goto do_num5; | |
| 2142 | 1332 | case state::num6: goto do_num6; | |
| 2143 | 1232 | case state::num7: goto do_num7; | |
| 2144 | 21888 | case state::num8: goto do_num8; | |
| 2145 | 938 | case state::exp1: goto do_exp1; | |
| 2146 | 250 | case state::exp2: goto do_exp2; | |
| 2147 | 24046 | case state::exp3: goto do_exp3; | |
| 2148 | } | ||
| 2149 | } | ||
| 2150 | |||
| 2151 | //---------------------------------- | ||
| 2152 | // | ||
| 2153 | // DIGIT | ||
| 2154 | // first digit | ||
| 2155 | // | ||
| 2156 | 123590 | do_num1: | |
| 2157 | 31584 | if(zero_first || nonzero_first || | |
| 2158 |
2/2✓ Branch 1 taken 15070 times.
✓ Branch 2 taken 722 times.
|
31584 | BOOST_JSON_LIKELY(cs)) |
| 2159 | { | ||
| 2160 | 122146 | char const c = *cs; | |
| 2161 | if(zero_first) | ||
| 2162 | { | ||
| 2163 | 19436 | ++cs; | |
| 2164 | 19436 | num.mant = 0; | |
| 2165 | 19436 | goto do_num6; | |
| 2166 | } | ||
| 2167 |
6/6✓ Branch 0 taken 7347 times.
✓ Branch 1 taken 7723 times.
✓ Branch 2 taken 6248 times.
✓ Branch 3 taken 1099 times.
✓ Branch 4 taken 6248 times.
✓ Branch 5 taken 8822 times.
|
30140 | else if(nonzero_first || BOOST_JSON_LIKELY( |
| 2168 | c >= '1' && c <= '9')) | ||
| 2169 | { | ||
| 2170 | 85066 | ++cs; | |
| 2171 | 85066 | num.mant = c - '0'; | |
| 2172 | } | ||
| 2173 |
2/2✓ Branch 0 taken 7627 times.
✓ Branch 1 taken 1195 times.
|
17644 | else if(BOOST_JSON_UNLIKELY( |
| 2174 | c == '0')) | ||
| 2175 | { | ||
| 2176 | 15254 | ++cs; | |
| 2177 | 15254 | num.mant = 0; | |
| 2178 | 15254 | goto do_num6; | |
| 2179 | } | ||
| 2180 |
4/4✓ Branch 0 taken 1011 times.
✓ Branch 1 taken 184 times.
✓ Branch 2 taken 83 times.
✓ Branch 3 taken 4 times.
|
2390 | else if( (negative || num.neg) && opt_.allow_infinity_and_nan ) |
| 2181 | { | ||
| 2182 |
1/1✓ Branch 1 taken 1007 times.
|
2014 | st_.push(state::lit1); |
| 2183 | 2014 | cur_lit_ = literal_index(detail::literals::neg_infinity); | |
| 2184 | 2014 | lit_offset_ = 1; | |
| 2185 |
1/1✓ Branch 2 taken 961 times.
|
2014 | return parse_literal( |
| 2186 | 1922 | cs.begin(), detail::literals_c<detail::literals::resume>() ); | |
| 2187 | } | ||
| 2188 | else | ||
| 2189 | { | ||
| 2190 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2191 | = BOOST_CURRENT_LOCATION; | ||
| 2192 | 376 | return fail(cs.begin(), error::syntax, &loc); | |
| 2193 | } | ||
| 2194 | } | ||
| 2195 | else | ||
| 2196 | { | ||
| 2197 |
3/6✓ Branch 3 taken 215 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 155 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 303 times.
|
1444 | if(BOOST_JSON_UNLIKELY( |
| 2198 | ! h_.on_number_part( | ||
| 2199 | {begin, cs.used(begin)}, ec_))) | ||
| 2200 | 120 | return fail(cs.begin()); | |
| 2201 | |||
| 2202 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2203 |
1/1✓ Branch 2 taken 64 times.
|
128 | num_buf_.append( begin, cs.used(begin) ); |
| 2204 |
1/1✓ Branch 2 taken 602 times.
|
1204 | return maybe_suspend( |
| 2205 | 1204 | cs.begin(), state::num1, num); | |
| 2206 | } | ||
| 2207 | |||
| 2208 | //---------------------------------- | ||
| 2209 | // | ||
| 2210 | // 1*DIGIT | ||
| 2211 | // significant digits left of decimal | ||
| 2212 | // | ||
| 2213 | 4100590 | do_num2: | |
| 2214 |
6/6✓ Branch 1 taken 6574 times.
✓ Branch 2 taken 2037462 times.
✓ Branch 3 taken 1567 times.
✓ Branch 4 taken 5007 times.
✓ Branch 5 taken 1567 times.
✓ Branch 6 taken 2042469 times.
|
4088072 | if(negative || (!stack_empty && num.neg)) |
| 2215 | { | ||
| 2216 | 44800 | for(;;) | |
| 2217 | { | ||
| 2218 |
2/2✓ Branch 1 taken 1921 times.
✓ Branch 2 taken 28305 times.
|
60452 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2219 | { | ||
| 2220 |
2/2✓ Branch 0 taken 1469 times.
✓ Branch 1 taken 452 times.
|
3842 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2221 | { | ||
| 2222 |
3/6✓ Branch 3 taken 397 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 328 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 796 times.
|
2938 | if(BOOST_JSON_UNLIKELY( |
| 2223 | ! h_.on_number_part( | ||
| 2224 | {begin, cs.used(begin)}, ec_))) | ||
| 2225 | 138 | return fail(cs.begin()); | |
| 2226 | |||
| 2227 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2228 |
1/1✓ Branch 2 taken 32 times.
|
64 | num_buf_.append( begin, cs.used(begin) ); |
| 2229 |
1/1✓ Branch 2 taken 1331 times.
|
2662 | return suspend(cs.begin(), state::num2, num); |
| 2230 | } | ||
| 2231 | 904 | goto finish_int; | |
| 2232 | } | ||
| 2233 | 56610 | char const c = *cs; | |
| 2234 |
6/6✓ Branch 0 taken 26030 times.
✓ Branch 1 taken 2275 times.
✓ Branch 2 taken 23223 times.
✓ Branch 3 taken 2807 times.
✓ Branch 4 taken 23223 times.
✓ Branch 5 taken 5082 times.
|
56610 | if(BOOST_JSON_LIKELY( |
| 2235 | c >= '0' && c <= '9')) | ||
| 2236 | { | ||
| 2237 | 46446 | ++cs; | |
| 2238 | // 9223372036854775808 INT64_MIN | ||
| 2239 |
2/2✓ Branch 0 taken 22508 times.
✓ Branch 1 taken 715 times.
|
46446 | if( num.mant > 922337203685477580 || ( |
| 2240 |
4/4✓ Branch 0 taken 367 times.
✓ Branch 1 taken 22141 times.
✓ Branch 2 taken 259 times.
✓ Branch 3 taken 108 times.
|
45016 | num.mant == 922337203685477580 && c > '8')) |
| 2241 | break; | ||
| 2242 | BOOST_IF_CONSTEXPR( !no_parsing ) | ||
| 2243 | 44282 | num.mant = 10 * num.mant + ( c - '0' ); | |
| 2244 | 44800 | continue; | |
| 2245 | } | ||
| 2246 | 10164 | goto do_num6; // [.eE] | |
| 2247 | } | ||
| 2248 | } | ||
| 2249 | else | ||
| 2250 | { | ||
| 2251 | 13770074 | for(;;) | |
| 2252 | { | ||
| 2253 |
2/2✓ Branch 1 taken 6426 times.
✓ Branch 2 taken 8921080 times.
|
17855012 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2254 | { | ||
| 2255 |
2/2✓ Branch 0 taken 5813 times.
✓ Branch 1 taken 613 times.
|
12852 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2256 | { | ||
| 2257 |
4/6✓ Branch 3 taken 2195 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 1789 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 1790 times.
|
11626 | if(BOOST_JSON_UNLIKELY( |
| 2258 | ! h_.on_number_part( | ||
| 2259 | {begin, cs.used(begin)}, ec_))) | ||
| 2260 | 812 | return fail(cs.begin()); | |
| 2261 | |||
| 2262 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2263 |
1/1✓ Branch 2 taken 174 times.
|
348 | num_buf_.append( begin, cs.used(begin) ); |
| 2264 |
1/1✓ Branch 2 taken 5007 times.
|
10014 | return suspend(cs.begin(), state::num2, num); |
| 2265 | } | ||
| 2266 | 1226 | goto finish_int; | |
| 2267 | } | ||
| 2268 | 17842160 | char const c = *cs; | |
| 2269 |
6/6✓ Branch 0 taken 6898090 times.
✓ Branch 1 taken 2022990 times.
✓ Branch 2 taken 6888862 times.
✓ Branch 3 taken 9228 times.
✓ Branch 4 taken 6888862 times.
✓ Branch 5 taken 2032218 times.
|
17842160 | if(BOOST_JSON_LIKELY( |
| 2270 | c >= '0' && c <= '9')) | ||
| 2271 | { | ||
| 2272 | 13777724 | ++cs; | |
| 2273 | // 18446744073709551615 UINT64_MAX | ||
| 2274 |
2/2✓ Branch 0 taken 6885459 times.
✓ Branch 1 taken 3403 times.
|
13777724 | if( num.mant > 1844674407370955161 || ( |
| 2275 |
4/4✓ Branch 0 taken 680 times.
✓ Branch 1 taken 6884779 times.
✓ Branch 2 taken 258 times.
✓ Branch 3 taken 422 times.
|
13770918 | num.mant == 1844674407370955161 && c > '5')) |
| 2276 | break; | ||
| 2277 | BOOST_IF_CONSTEXPR( !no_parsing ) | ||
| 2278 | 13758878 | num.mant = 10 * num.mant + ( c - '0' ); | |
| 2279 | } | ||
| 2280 | else | ||
| 2281 | { | ||
| 2282 | 4064436 | goto do_num6; // [.eE] | |
| 2283 | } | ||
| 2284 | } | ||
| 2285 | } | ||
| 2286 | 9296 | ++num.bias; | |
| 2287 | |||
| 2288 | //---------------------------------- | ||
| 2289 | // | ||
| 2290 | // 1*DIGIT | ||
| 2291 | // non-significant digits left of decimal | ||
| 2292 | // | ||
| 2293 | 10900 | do_num3: | |
| 2294 | 23116 | for(;;) | |
| 2295 | { | ||
| 2296 |
2/2✓ Branch 1 taken 1527 times.
✓ Branch 2 taken 15481 times.
|
34016 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2297 | { | ||
| 2298 |
2/2✓ Branch 0 taken 894 times.
✓ Branch 1 taken 633 times.
|
3054 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2299 | { | ||
| 2300 |
3/6✓ Branch 3 taken 181 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 135 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 539 times.
|
1788 | if(BOOST_JSON_UNLIKELY( |
| 2301 | ! h_.on_number_part( | ||
| 2302 | {begin, cs.used(begin)}, ec_))) | ||
| 2303 | 92 | return fail(cs.begin()); | |
| 2304 | |||
| 2305 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2306 |
1/1✓ Branch 2 taken 12 times.
|
24 | num_buf_.append( begin, cs.used(begin) ); |
| 2307 |
1/1✓ Branch 2 taken 802 times.
|
1604 | return suspend(cs.begin(), state::num3, num); |
| 2308 | } | ||
| 2309 | 1266 | goto finish_dub; | |
| 2310 | } | ||
| 2311 | 30962 | char const c = *cs; | |
| 2312 |
6/6✓ Branch 0 taken 12194 times.
✓ Branch 1 taken 3287 times.
✓ Branch 2 taken 11558 times.
✓ Branch 3 taken 636 times.
✓ Branch 4 taken 11558 times.
✓ Branch 5 taken 3923 times.
|
30962 | if(BOOST_JSON_UNLIKELY( |
| 2313 | c >= '0' && c <= '9')) | ||
| 2314 | { | ||
| 2315 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11558 times.
|
23116 | if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX )) |
| 2316 | { | ||
| 2317 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2318 | = BOOST_CURRENT_LOCATION; | ||
| 2319 | ✗ | return fail(cs.begin(), error::exponent_overflow, &loc); | |
| 2320 | } | ||
| 2321 | 23116 | ++cs; | |
| 2322 | 23116 | ++num.bias; | |
| 2323 | } | ||
| 2324 |
2/2✓ Branch 0 taken 2028 times.
✓ Branch 1 taken 1895 times.
|
7846 | else if(BOOST_JSON_LIKELY( |
| 2325 | c == '.')) | ||
| 2326 | { | ||
| 2327 | 4056 | ++cs; | |
| 2328 | 4056 | break; | |
| 2329 | } | ||
| 2330 |
2/2✓ Branch 0 taken 546 times.
✓ Branch 1 taken 1349 times.
|
3790 | else if((c | 32) == 'e') |
| 2331 | { | ||
| 2332 | 1092 | ++cs; | |
| 2333 | 1092 | goto do_exp1; | |
| 2334 | } | ||
| 2335 | else | ||
| 2336 | { | ||
| 2337 | 2698 | goto finish_dub; | |
| 2338 | } | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | //---------------------------------- | ||
| 2342 | // | ||
| 2343 | // DIGIT | ||
| 2344 | // first non-significant digit | ||
| 2345 | // to the right of decimal | ||
| 2346 | // | ||
| 2347 | 4160 | do_num4: | |
| 2348 | { | ||
| 2349 |
2/2✓ Branch 1 taken 64 times.
✓ Branch 2 taken 2016 times.
|
4160 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2350 | { | ||
| 2351 |
3/6✓ Branch 3 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 20 times.
|
128 | if(BOOST_JSON_UNLIKELY( |
| 2352 | ! h_.on_number_part( | ||
| 2353 | {begin, cs.used(begin)}, ec_))) | ||
| 2354 | 12 | return fail(cs.begin()); | |
| 2355 | |||
| 2356 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2357 |
1/1✓ Branch 2 taken 4 times.
|
8 | num_buf_.append( begin, cs.used(begin) ); |
| 2358 |
1/1✓ Branch 2 taken 52 times.
|
104 | return maybe_suspend( |
| 2359 | 104 | cs.begin(), state::num4, num); | |
| 2360 | } | ||
| 2361 | 4032 | char const c = *cs; | |
| 2362 |
5/6✓ Branch 0 taken 2016 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1949 times.
✓ Branch 3 taken 67 times.
✓ Branch 4 taken 1949 times.
✓ Branch 5 taken 67 times.
|
4032 | if(BOOST_JSON_LIKELY( |
| 2363 | //static_cast<unsigned char>(c - '0') < 10)) | ||
| 2364 | c >= '0' && c <= '9')) | ||
| 2365 | { | ||
| 2366 | 3898 | ++cs; | |
| 2367 | } | ||
| 2368 | else | ||
| 2369 | { | ||
| 2370 | // digit required | ||
| 2371 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2372 | = BOOST_CURRENT_LOCATION; | ||
| 2373 | 134 | return fail(cs.begin(), error::syntax, &loc); | |
| 2374 | } | ||
| 2375 | } | ||
| 2376 | |||
| 2377 | //---------------------------------- | ||
| 2378 | // | ||
| 2379 | // 1*DIGIT | ||
| 2380 | // non-significant digits | ||
| 2381 | // to the right of decimal | ||
| 2382 | // | ||
| 2383 | 4026940 | do_num5: | |
| 2384 | 75779664 | for(;;) | |
| 2385 | { | ||
| 2386 |
2/2✓ Branch 1 taken 6112 times.
✓ Branch 2 taken 39897190 times.
|
79806604 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2387 | { | ||
| 2388 |
2/2✓ Branch 0 taken 4577 times.
✓ Branch 1 taken 1535 times.
|
12224 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2389 | { | ||
| 2390 |
3/6✓ Branch 3 taken 94 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 74 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 4403 times.
|
9154 | if(BOOST_JSON_UNLIKELY( |
| 2391 | ! h_.on_number_part( | ||
| 2392 | {begin, cs.used(begin)}, ec_))) | ||
| 2393 | 40 | return fail(cs.begin()); | |
| 2394 | |||
| 2395 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2396 |
1/1✓ Branch 2 taken 178 times.
|
356 | num_buf_.append( begin, cs.used(begin) ); |
| 2397 |
1/1✓ Branch 2 taken 4537 times.
|
9074 | return suspend(cs.begin(), state::num5, num); |
| 2398 | } | ||
| 2399 | 3070 | goto finish_dub; | |
| 2400 | } | ||
| 2401 | 79794380 | char const c = *cs; | |
| 2402 |
6/6✓ Branch 0 taken 39893068 times.
✓ Branch 1 taken 4122 times.
✓ Branch 2 taken 37889832 times.
✓ Branch 3 taken 2003236 times.
✓ Branch 4 taken 37889832 times.
✓ Branch 5 taken 2007358 times.
|
79794380 | if(BOOST_JSON_LIKELY( |
| 2403 | c >= '0' && c <= '9')) | ||
| 2404 | { | ||
| 2405 | 75779664 | ++cs; | |
| 2406 | } | ||
| 2407 |
2/2✓ Branch 0 taken 2003236 times.
✓ Branch 1 taken 4122 times.
|
4014716 | else if((c | 32) == 'e') |
| 2408 | { | ||
| 2409 | 4006472 | ++cs; | |
| 2410 | 4006472 | goto do_exp1; | |
| 2411 | } | ||
| 2412 | else | ||
| 2413 | { | ||
| 2414 | 8244 | goto finish_dub; | |
| 2415 | } | ||
| 2416 | } | ||
| 2417 | |||
| 2418 | //---------------------------------- | ||
| 2419 | // | ||
| 2420 | // [.eE] | ||
| 2421 | // | ||
| 2422 | 4110622 | do_num6: | |
| 2423 | { | ||
| 2424 |
2/2✓ Branch 1 taken 798 times.
✓ Branch 2 taken 2054513 times.
|
4110622 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2425 | { | ||
| 2426 |
2/2✓ Branch 0 taken 751 times.
✓ Branch 1 taken 47 times.
|
1596 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2427 | { | ||
| 2428 |
3/6✓ Branch 3 taken 161 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 119 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 431 times.
|
1502 | if(BOOST_JSON_UNLIKELY( |
| 2429 | ! h_.on_number_part( | ||
| 2430 | {begin, cs.used(begin)}, ec_))) | ||
| 2431 | 84 | return fail(cs.begin()); | |
| 2432 | |||
| 2433 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2434 |
1/1✓ Branch 2 taken 98 times.
|
196 | num_buf_.append( begin, cs.used(begin) ); |
| 2435 |
1/1✓ Branch 2 taken 667 times.
|
1334 | return suspend(cs.begin(), state::num6, num); |
| 2436 | } | ||
| 2437 | 94 | goto finish_int; | |
| 2438 | } | ||
| 2439 | 4109026 | char const c = *cs; | |
| 2440 |
2/2✓ Branch 0 taken 2016097 times.
✓ Branch 1 taken 38416 times.
|
4109026 | if(BOOST_JSON_LIKELY( |
| 2441 | c == '.')) | ||
| 2442 | { | ||
| 2443 | 4032194 | ++cs; | |
| 2444 | } | ||
| 2445 |
2/2✓ Branch 0 taken 9140 times.
✓ Branch 1 taken 29276 times.
|
76832 | else if((c | 32) == 'e') |
| 2446 | { | ||
| 2447 | 18280 | ++cs; | |
| 2448 | 18280 | goto do_exp1; | |
| 2449 | } | ||
| 2450 | else | ||
| 2451 | { | ||
| 2452 | 58552 | goto finish_int; | |
| 2453 | } | ||
| 2454 | } | ||
| 2455 | |||
| 2456 | //---------------------------------- | ||
| 2457 | // | ||
| 2458 | // DIGIT | ||
| 2459 | // first significant digit | ||
| 2460 | // to the right of decimal | ||
| 2461 | // | ||
| 2462 | 4033670 | do_num7: | |
| 2463 | { | ||
| 2464 |
2/2✓ Branch 1 taken 691 times.
✓ Branch 2 taken 2016144 times.
|
4033670 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2465 | { | ||
| 2466 |
2/2✓ Branch 0 taken 687 times.
✓ Branch 1 taken 4 times.
|
1382 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2467 | { | ||
| 2468 |
3/6✓ Branch 3 taken 144 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 109 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 412 times.
|
1374 | if(BOOST_JSON_UNLIKELY( |
| 2469 | ! h_.on_number_part( | ||
| 2470 | {begin, cs.used(begin)}, ec_))) | ||
| 2471 | 70 | return fail(cs.begin()); | |
| 2472 | |||
| 2473 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2474 |
1/1✓ Branch 2 taken 96 times.
|
192 | num_buf_.append( begin, cs.used(begin) ); |
| 2475 |
1/1✓ Branch 2 taken 617 times.
|
1234 | return suspend(cs.begin(), state::num7, num); |
| 2476 | } | ||
| 2477 | // digit required | ||
| 2478 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2479 | = BOOST_CURRENT_LOCATION; | ||
| 2480 | 8 | return fail(cs.begin(), error::syntax, &loc); | |
| 2481 | } | ||
| 2482 | 4032288 | char const c = *cs; | |
| 2483 |
6/6✓ Branch 0 taken 2016080 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 2015975 times.
✓ Branch 4 taken 169 times.
✓ Branch 5 taken 2015975 times.
|
4032288 | if(BOOST_JSON_UNLIKELY( |
| 2484 | c < '0' || c > '9')) | ||
| 2485 | { | ||
| 2486 | // digit required | ||
| 2487 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2488 | = BOOST_CURRENT_LOCATION; | ||
| 2489 | 338 | return fail(cs.begin(), error::syntax, &loc); | |
| 2490 | } | ||
| 2491 | } | ||
| 2492 | |||
| 2493 | //---------------------------------- | ||
| 2494 | // | ||
| 2495 | // 1*DIGIT | ||
| 2496 | // significant digits | ||
| 2497 | // to the right of decimal | ||
| 2498 | // | ||
| 2499 | 4068872 | do_num8: | |
| 2500 | 6555852 | for(;;) | |
| 2501 | { | ||
| 2502 |
2/2✓ Branch 1 taken 12816 times.
✓ Branch 2 taken 5302046 times.
|
10629724 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2503 | { | ||
| 2504 |
2/2✓ Branch 0 taken 11080 times.
✓ Branch 1 taken 1736 times.
|
25632 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2505 | { | ||
| 2506 |
3/6✓ Branch 3 taken 341 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 274 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 10478 times.
|
22160 | if(BOOST_JSON_UNLIKELY( |
| 2507 | ! h_.on_number_part( | ||
| 2508 | {begin, cs.used(begin)}, ec_))) | ||
| 2509 | 134 | return fail(cs.begin()); | |
| 2510 | |||
| 2511 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2512 |
1/1✓ Branch 2 taken 3441 times.
|
6884 | num_buf_.append( begin, cs.used(begin) ); |
| 2513 |
1/1✓ Branch 2 taken 10945 times.
|
21890 | return suspend(cs.begin(), state::num8, num); |
| 2514 | } | ||
| 2515 | 3472 | goto finish_dub; | |
| 2516 | } | ||
| 2517 | 10604092 | char const c = *cs; | |
| 2518 |
6/6✓ Branch 0 taken 5296119 times.
✓ Branch 1 taken 5927 times.
✓ Branch 2 taken 5284910 times.
✓ Branch 3 taken 11209 times.
✓ Branch 4 taken 5284910 times.
✓ Branch 5 taken 17136 times.
|
10604092 | if(BOOST_JSON_LIKELY( |
| 2519 | c >= '0' && c <= '9')) | ||
| 2520 | { | ||
| 2521 | 10569820 | ++cs; | |
| 2522 |
2/2✓ Branch 0 taken 3277926 times.
✓ Branch 1 taken 2001891 times.
|
10559634 | if(!no_parsing && BOOST_JSON_LIKELY( |
| 2523 | num.mant <= 9007199254740991)) // 2^53-1 | ||
| 2524 | { | ||
| 2525 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3277926 times.
|
6555852 | if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN )) |
| 2526 | { | ||
| 2527 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2528 | = BOOST_CURRENT_LOCATION; | ||
| 2529 | ✗ | return fail(cs.begin(), error::exponent_overflow, &loc); | |
| 2530 | } | ||
| 2531 | 6555852 | --num.bias; | |
| 2532 | 6555852 | num.mant = 10 * num.mant + ( c - '0' ); | |
| 2533 | } | ||
| 2534 | else | ||
| 2535 | { | ||
| 2536 | 4013968 | goto do_num5; | |
| 2537 | } | ||
| 2538 | } | ||
| 2539 |
2/2✓ Branch 0 taken 11133 times.
✓ Branch 1 taken 6003 times.
|
34272 | else if((c | 32) == 'e') |
| 2540 | { | ||
| 2541 | 22266 | ++cs; | |
| 2542 | 22266 | goto do_exp1; | |
| 2543 | } | ||
| 2544 | else | ||
| 2545 | { | ||
| 2546 | 12006 | goto finish_dub; | |
| 2547 | } | ||
| 2548 | } | ||
| 2549 | |||
| 2550 | //---------------------------------- | ||
| 2551 | // | ||
| 2552 | // *[+-] | ||
| 2553 | // | ||
| 2554 | 4062420 | do_exp1: | |
| 2555 |
2/2✓ Branch 1 taken 565 times.
✓ Branch 2 taken 2030645 times.
|
4062420 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2556 | { | ||
| 2557 |
3/6✓ Branch 3 taken 196 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 148 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 187 times.
|
1130 | if(BOOST_JSON_UNLIKELY( |
| 2558 | ! h_.on_number_part( | ||
| 2559 | {begin, cs.used(begin)}, ec_))) | ||
| 2560 | 96 | return fail(cs.begin()); | |
| 2561 | |||
| 2562 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2563 |
1/1✓ Branch 2 taken 46 times.
|
92 | num_buf_.append( begin, cs.used(begin) ); |
| 2564 |
1/1✓ Branch 2 taken 469 times.
|
938 | return maybe_suspend( |
| 2565 | 938 | cs.begin(), state::exp1, num); | |
| 2566 | } | ||
| 2567 |
2/2✓ Branch 1 taken 1931 times.
✓ Branch 2 taken 2028714 times.
|
4061290 | if(*cs == '+') |
| 2568 | { | ||
| 2569 | 3862 | ++cs; | |
| 2570 | } | ||
| 2571 |
2/2✓ Branch 1 taken 1026779 times.
✓ Branch 2 taken 1001935 times.
|
4057428 | else if(*cs == '-') |
| 2572 | { | ||
| 2573 | 2003870 | ++cs; | |
| 2574 | 2003870 | num.frac = true; | |
| 2575 | } | ||
| 2576 | |||
| 2577 | //---------------------------------- | ||
| 2578 | // | ||
| 2579 | // DIGIT | ||
| 2580 | // first digit of the exponent | ||
| 2581 | // | ||
| 2582 | 2053558 | do_exp2: | |
| 2583 | { | ||
| 2584 |
2/2✓ Branch 1 taken 172 times.
✓ Branch 2 taken 2030598 times.
|
4061540 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2585 | { | ||
| 2586 |
2/2✓ Branch 0 taken 163 times.
✓ Branch 1 taken 9 times.
|
344 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2587 | { | ||
| 2588 |
3/6✓ Branch 3 taken 75 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 56 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 16 times.
|
326 | if(BOOST_JSON_UNLIKELY( |
| 2589 | ! h_.on_number_part( | ||
| 2590 | {begin, cs.used(begin)}, ec_))) | ||
| 2591 | 38 | return fail(cs.begin()); | |
| 2592 | |||
| 2593 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2594 |
1/1✓ Branch 2 taken 4 times.
|
8 | num_buf_.append( begin, cs.used(begin) ); |
| 2595 |
1/1✓ Branch 2 taken 125 times.
|
250 | return suspend(cs.begin(), state::exp2, num); |
| 2596 | } | ||
| 2597 | // digit required | ||
| 2598 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2599 | = BOOST_CURRENT_LOCATION; | ||
| 2600 | 18 | return fail(cs.begin(), error::syntax, &loc); | |
| 2601 | } | ||
| 2602 | 4061196 | char const c = *cs; | |
| 2603 |
6/6✓ Branch 0 taken 2030352 times.
✓ Branch 1 taken 246 times.
✓ Branch 2 taken 262 times.
✓ Branch 3 taken 2030090 times.
✓ Branch 4 taken 508 times.
✓ Branch 5 taken 2030090 times.
|
4061196 | if(BOOST_JSON_UNLIKELY( |
| 2604 | c < '0' || c > '9')) | ||
| 2605 | { | ||
| 2606 | // digit required | ||
| 2607 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2608 | = BOOST_CURRENT_LOCATION; | ||
| 2609 | 1016 | return fail(cs.begin(), error::syntax, &loc); | |
| 2610 | } | ||
| 2611 | 4060180 | ++cs; | |
| 2612 | 4060180 | num.exp = c - '0'; | |
| 2613 | } | ||
| 2614 | |||
| 2615 | //---------------------------------- | ||
| 2616 | // | ||
| 2617 | // 1*DIGIT | ||
| 2618 | // subsequent digits in the exponent | ||
| 2619 | // | ||
| 2620 | 4084226 | do_exp3: | |
| 2621 | 10932204 | for(;;) | |
| 2622 | { | ||
| 2623 |
2/2✓ Branch 1 taken 2020530 times.
✓ Branch 2 taken 5487685 times.
|
15016430 | if(BOOST_JSON_UNLIKELY(! cs)) |
| 2624 | { | ||
| 2625 |
2/2✓ Branch 0 taken 12177 times.
✓ Branch 1 taken 2008353 times.
|
4041060 | if(BOOST_JSON_UNLIKELY(more_)) |
| 2626 | { | ||
| 2627 |
3/6✓ Branch 3 taken 329 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 252 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 11540 times.
|
24354 | if(BOOST_JSON_UNLIKELY( |
| 2628 | ! h_.on_number_part( | ||
| 2629 | {begin, cs.used(begin)}, ec_))) | ||
| 2630 | 154 | return fail(cs.begin()); | |
| 2631 | |||
| 2632 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2633 |
1/1✓ Branch 2 taken 2873 times.
|
5746 | num_buf_.append( begin, cs.used(begin) ); |
| 2634 |
1/1✓ Branch 2 taken 12023 times.
|
24046 | return suspend(cs.begin(), state::exp3, num); |
| 2635 | } | ||
| 2636 | } | ||
| 2637 | else | ||
| 2638 | { | ||
| 2639 | 10975370 | char const c = *cs; | |
| 2640 |
6/6✓ Branch 0 taken 5466517 times.
✓ Branch 1 taken 21168 times.
✓ Branch 2 taken 5466102 times.
✓ Branch 3 taken 415 times.
✓ Branch 4 taken 5466102 times.
✓ Branch 5 taken 21583 times.
|
10975370 | if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' )) |
| 2641 | { | ||
| 2642 |
9/10✓ Branch 0 taken 5462502 times.
✓ Branch 1 taken 3600 times.
✓ Branch 2 taken 255 times.
✓ Branch 3 taken 5462247 times.
✓ Branch 4 taken 255 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 255 times.
✓ Branch 7 taken 5462247 times.
✓ Branch 8 taken 3855 times.
✓ Branch 9 taken 5462247 times.
|
10932204 | if(BOOST_JSON_UNLIKELY( |
| 2643 | // 2147483647 INT_MAX | ||
| 2644 | num.exp > 214748364 || | ||
| 2645 | (num.exp == 214748364 && c > '7') | ||
| 2646 | )) | ||
| 2647 | 7710 | num.exp = INT_MAX; | |
| 2648 | else BOOST_IF_CONSTEXPR( !no_parsing ) | ||
| 2649 | 9842790 | num.exp = 10 * num.exp + ( c - '0' ); | |
| 2650 | |||
| 2651 | 10932204 | ++cs; | |
| 2652 | 10932204 | continue; | |
| 2653 | } | ||
| 2654 | } | ||
| 2655 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2029936 times.
|
4059872 | BOOST_ASSERT(num.exp >= 0); |
| 2656 |
2/2✓ Branch 0 taken 1001799 times.
✓ Branch 1 taken 1028137 times.
|
4059872 | if ( num.frac ) |
| 2657 | { | ||
| 2658 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 1001708 times.
|
2003598 | if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) )) |
| 2659 | { | ||
| 2660 | // if exponent overflowed, bias is a very large negative | ||
| 2661 | // number, and mantissa isn't zero, then we cannot parse the | ||
| 2662 | // number correctly | ||
| 2663 |
6/14✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 91 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 91 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 91 times.
|
182 | if(BOOST_JSON_UNLIKELY( |
| 2664 | (num.exp == INT_MAX) && | ||
| 2665 | (num.bias < 0) && | ||
| 2666 | (num.exp + num.bias < 308) && | ||
| 2667 | num.mant )) | ||
| 2668 | { | ||
| 2669 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2670 | = BOOST_CURRENT_LOCATION; | ||
| 2671 | ✗ | return fail(cs.begin(), error::exponent_overflow, &loc); | |
| 2672 | } | ||
| 2673 | |||
| 2674 | 182 | num.bias = 0; | |
| 2675 | 182 | num.exp = INT_MAX; | |
| 2676 | } | ||
| 2677 | } | ||
| 2678 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1028137 times.
|
2056274 | else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) )) |
| 2679 | { | ||
| 2680 | // if exponent overflowed, bias is a very large positive number, | ||
| 2681 | // and mantissa isn't zero, then we cannot parse the | ||
| 2682 | // number correctly | ||
| 2683 | ✗ | if(BOOST_JSON_UNLIKELY( | |
| 2684 | (num.exp == INT_MAX) && | ||
| 2685 | (num.bias > 0) && | ||
| 2686 | (num.exp - num.bias < 308) && | ||
| 2687 | num.mant )) | ||
| 2688 | { | ||
| 2689 | BOOST_STATIC_CONSTEXPR source_location loc | ||
| 2690 | = BOOST_CURRENT_LOCATION; | ||
| 2691 | ✗ | return fail(cs.begin(), error::exponent_overflow, &loc); | |
| 2692 | } | ||
| 2693 | |||
| 2694 | ✗ | num.bias = 0; | |
| 2695 | ✗ | num.exp = INT_MAX; | |
| 2696 | } | ||
| 2697 | 4059872 | goto finish_dub; | |
| 2698 | } | ||
| 2699 | |||
| 2700 | 60776 | finish_int: | |
| 2701 |
6/6✓ Branch 1 taken 2893 times.
✓ Branch 2 taken 25565 times.
✓ Branch 3 taken 602 times.
✓ Branch 4 taken 2291 times.
✓ Branch 5 taken 602 times.
✓ Branch 6 taken 27856 times.
|
56916 | if(negative || (!stack_empty && num.neg)) |
| 2702 | { | ||
| 2703 |
3/6✓ Branch 3 taken 1497 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 1187 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
5064 | if(BOOST_JSON_UNLIKELY( |
| 2704 | ! h_.on_int64(static_cast< | ||
| 2705 | int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_))) | ||
| 2706 | 620 | return fail(cs.begin()); | |
| 2707 | 3828 | return cs.begin(); | |
| 2708 | } | ||
| 2709 |
2/2✓ Branch 0 taken 27535 times.
✓ Branch 1 taken 321 times.
|
55712 | if(num.mant <= INT64_MAX) |
| 2710 | { | ||
| 2711 | 55108 | finish_signed: | |
| 2712 |
4/6✓ Branch 3 taken 17870 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 15603 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✓ Branch 4 taken 1 times.
|
61658 | if(BOOST_JSON_UNLIKELY( |
| 2713 | ! h_.on_int64(static_cast< | ||
| 2714 | int64_t>(num.mant), {begin, cs.used(begin)}, ec_))) | ||
| 2715 | 4534 | return fail(cs.begin()); | |
| 2716 | 52604 | return cs.begin(); | |
| 2717 | } | ||
| 2718 |
3/6✓ Branch 3 taken 224 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 189 times.
✗ Branch 1 not taken.
✗ Branch 7 not taken.
✗ Branch 4 not taken.
|
642 | if(BOOST_JSON_UNLIKELY( |
| 2719 | ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_))) | ||
| 2720 | 70 | return fail(cs.begin()); | |
| 2721 | 508 | return cs.begin(); | |
| 2722 | 4104522 | finish_dub: | |
| 2723 | double d; | ||
| 2724 | 4104522 | std::size_t const size = cs.used(begin); | |
| 2725 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1042951 times.
|
4104522 | BOOST_ASSERT( !num_buf_.size() || precise_parsing ); |
| 2726 | BOOST_IF_CONSTEXPR( precise_parsing ) | ||
| 2727 | { | ||
| 2728 | 2018620 | char const* data = begin; | |
| 2729 | 2018620 | std::size_t full_size = size; | |
| 2730 | // if we previously suspended or if the current input ends with the | ||
| 2731 | // number, we need to copy the current part of the number to the | ||
| 2732 | // temporary buffer | ||
| 2733 |
2/2✓ Branch 1 taken 4771 times.
✓ Branch 2 taken 1004539 times.
|
2018620 | if(BOOST_JSON_UNLIKELY( num_buf_.size() )) |
| 2734 | { | ||
| 2735 |
1/1✓ Branch 1 taken 4771 times.
|
9542 | data = num_buf_.append( begin, size ); |
| 2736 | 9542 | full_size = num_buf_.size(); | |
| 2737 | } | ||
| 2738 | 2018620 | auto const err = detail::charconv::from_chars( | |
| 2739 | data, data + full_size, d ); | ||
| 2740 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1009310 times.
|
2018620 | BOOST_ASSERT( err.ec != std::errc::invalid_argument ); |
| 2741 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1009310 times.
|
2018620 | BOOST_ASSERT( err.ptr == data + full_size ); |
| 2742 | (void)err; | ||
| 2743 | } | ||
| 2744 | else BOOST_IF_CONSTEXPR( no_parsing ) | ||
| 2745 | 18516 | d = 0; | |
| 2746 | else | ||
| 2747 | 2067386 | d = detail::dec_to_float( | |
| 2748 | num.mant, | ||
| 2749 | 1063482 | num.bias + (num.frac ? | |
| 2750 | 1003904 | -num.exp : num.exp), | |
| 2751 |
2/2✓ Branch 0 taken 501952 times.
✓ Branch 1 taken 531741 times.
|
2067386 | num.neg); |
| 2752 |
2/6✗ Branch 4 not taken.
✓ Branch 5 taken 2043759 times.
✗ Branch 1 not taken.
✗ Branch 6 not taken.
✓ Branch 2 taken 2039799 times.
✗ Branch 3 not taken.
|
4104522 | if(BOOST_JSON_UNLIKELY( |
| 2753 | ! h_.on_double(d, {begin, size}, ec_))) | ||
| 2754 | 3806 | return fail(cs.begin()); | |
| 2755 | 4096910 | return cs.begin(); | |
| 2756 | } | ||
| 2757 | |||
| 2758 | //---------------------------------------------------------- | ||
| 2759 | |||
| 2760 | template<class Handler> | ||
| 2761 | template<class... Args> | ||
| 2762 | 4329207 | basic_parser<Handler>:: | |
| 2763 | basic_parser( | ||
| 2764 | parse_options const& opt, | ||
| 2765 | Args&&... args) | ||
| 2766 | 4329191 | : h_(std::forward<Args>(args)...) | |
| 2767 | 4329207 | , opt_(opt) | |
| 2768 | { | ||
| 2769 | 4329207 | } | |
| 2770 | |||
| 2771 | //---------------------------------------------------------- | ||
| 2772 | |||
| 2773 | template<class Handler> | ||
| 2774 | void | ||
| 2775 | 4153129 | basic_parser<Handler>:: | |
| 2776 | reset() noexcept | ||
| 2777 | { | ||
| 2778 | 4153129 | ec_ = {}; | |
| 2779 | 4153129 | st_.clear(); | |
| 2780 | 4153129 | more_ = true; | |
| 2781 | 4153129 | done_ = false; | |
| 2782 | 4153129 | clean_ = true; | |
| 2783 | 4153129 | num_buf_.clear(); | |
| 2784 | 4153129 | } | |
| 2785 | |||
| 2786 | template<class Handler> | ||
| 2787 | void | ||
| 2788 | 16 | basic_parser<Handler>:: | |
| 2789 | fail(system::error_code ec) noexcept | ||
| 2790 | { | ||
| 2791 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
16 | if(! ec) |
| 2792 | { | ||
| 2793 | // assign an arbitrary | ||
| 2794 | // error code to prevent UB | ||
| 2795 | ✗ | BOOST_JSON_FAIL(ec_, error::incomplete); | |
| 2796 | } | ||
| 2797 | else | ||
| 2798 | { | ||
| 2799 | 16 | ec_ = ec; | |
| 2800 | } | ||
| 2801 | 16 | done_ = false; | |
| 2802 | 16 | } | |
| 2803 | |||
| 2804 | //---------------------------------------------------------- | ||
| 2805 | |||
| 2806 | template<class Handler> | ||
| 2807 | std::size_t | ||
| 2808 | 2458220 | basic_parser<Handler>:: | |
| 2809 | write_some( | ||
| 2810 | bool more, | ||
| 2811 | char const* data, | ||
| 2812 | std::size_t size, | ||
| 2813 | system::error_code& ec) | ||
| 2814 | { | ||
| 2815 | // see if we exited via exception | ||
| 2816 | // on the last call to write_some | ||
| 2817 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2331155 times.
|
2458220 | if(! clean_) |
| 2818 | { | ||
| 2819 | // prevent UB | ||
| 2820 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | if(! ec_) |
| 2821 | { | ||
| 2822 | 2 | BOOST_JSON_FAIL(ec_, error::exception); | |
| 2823 | } | ||
| 2824 | } | ||
| 2825 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2331151 times.
|
2458220 | if(ec_) |
| 2826 | { | ||
| 2827 | // error is sticky | ||
| 2828 | 7 | ec = ec_; | |
| 2829 | 7 | return 0; | |
| 2830 | } | ||
| 2831 | 2458213 | clean_ = false; | |
| 2832 | 2458213 | more_ = more; | |
| 2833 | 2458213 | end_ = data + size; | |
| 2834 | const char* p; | ||
| 2835 |
2/2✓ Branch 1 taken 2164070 times.
✓ Branch 2 taken 167081 times.
|
2458213 | if(BOOST_JSON_LIKELY(st_.empty())) |
| 2836 | { | ||
| 2837 | // first time | ||
| 2838 | 2251785 | depth_ = opt_.max_depth; | |
| 2839 |
3/3✓ Branch 2 taken 2148290 times.
✓ Branch 3 taken 1 times.
✓ Branch 1 taken 7889 times.
|
2251785 | if(BOOST_JSON_UNLIKELY( |
| 2840 | ! h_.on_document_begin(ec_))) | ||
| 2841 | { | ||
| 2842 | 15778 | ec = ec_; | |
| 2843 | 15778 | return 0; | |
| 2844 | } | ||
| 2845 | 2220227 | p = parse_document(data, std::true_type()); | |
| 2846 | } | ||
| 2847 | else | ||
| 2848 | { | ||
| 2849 | 206428 | p = parse_document(data, std::false_type()); | |
| 2850 | } | ||
| 2851 | |||
| 2852 |
2/2✓ Branch 1 taken 2098579 times.
✓ Branch 2 taken 197694 times.
|
2388599 | if(BOOST_JSON_LIKELY(p != sentinel())) |
| 2853 | { | ||
| 2854 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2098579 times.
|
2120951 | BOOST_ASSERT(! ec_); |
| 2855 |
2/2✓ Branch 0 taken 2031361 times.
✓ Branch 1 taken 67218 times.
|
2120951 | if(! done_) |
| 2856 | { | ||
| 2857 | 2050248 | done_ = true; | |
| 2858 | 2050248 | h_.on_document_end(ec_); | |
| 2859 | } | ||
| 2860 | } | ||
| 2861 | else | ||
| 2862 | { | ||
| 2863 |
2/2✓ Branch 1 taken 170965 times.
✓ Branch 2 taken 26729 times.
|
267648 | if(! ec_) |
| 2864 | { | ||
| 2865 |
2/2✓ Branch 0 taken 572 times.
✓ Branch 1 taken 170393 times.
|
214164 | if(! more_) |
| 2866 | { | ||
| 2867 | 1119 | BOOST_JSON_FAIL(ec_, error::incomplete); | |
| 2868 | } | ||
| 2869 |
1/2✓ Branch 1 taken 170393 times.
✗ Branch 2 not taken.
|
213045 | else if(! st_.empty()) |
| 2870 | { | ||
| 2871 | // consume as much trailing whitespace in | ||
| 2872 | // the JSON document as possible, but still | ||
| 2873 | // consider the parse complete | ||
| 2874 | state st; | ||
| 2875 | 213045 | st_.peek(st); | |
| 2876 |
2/2✓ Branch 0 taken 88354 times.
✓ Branch 1 taken 82039 times.
|
213045 | if( st == state::doc3 && |
| 2877 |
2/2✓ Branch 0 taken 70527 times.
✓ Branch 1 taken 17827 times.
|
95143 | ! done_) |
| 2878 | { | ||
| 2879 | 77316 | done_ = true; | |
| 2880 |
1/1✓ Branch 1 taken 1645 times.
|
77316 | h_.on_document_end(ec_); |
| 2881 | } | ||
| 2882 | } | ||
| 2883 | } | ||
| 2884 | 264360 | p = end_; | |
| 2885 | } | ||
| 2886 | 2377391 | ec = ec_; | |
| 2887 | 2377391 | clean_ = true; | |
| 2888 | 2377391 | return p - data; | |
| 2889 | } | ||
| 2890 | |||
| 2891 | template<class Handler> | ||
| 2892 | std::size_t | ||
| 2893 | 1 | basic_parser<Handler>:: | |
| 2894 | write_some( | ||
| 2895 | bool more, | ||
| 2896 | char const* data, | ||
| 2897 | std::size_t size, | ||
| 2898 | std::error_code& ec) | ||
| 2899 | { | ||
| 2900 | 1 | system::error_code jec; | |
| 2901 |
1/1✓ Branch 1 taken 1 times.
|
1 | std::size_t const result = write_some(more, data, size, jec); |
| 2902 |
1/1✓ Branch 1 taken 1 times.
|
1 | ec = jec; |
| 2903 | 1 | return result; | |
| 2904 | } | ||
| 2905 | |||
| 2906 | #endif | ||
| 2907 | |||
| 2908 | } // namespace json | ||
| 2909 | } // namespace boost | ||
| 2910 | |||
| 2911 | #ifdef _MSC_VER | ||
| 2912 | #pragma warning(pop) | ||
| 2913 | #endif | ||
| 2914 | |||
| 2915 | #endif | ||
| 2916 |