98.29% Lines (1262/1284) 100.00% Functions (30/30)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) 3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4   // 4   //
5   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7   // 7   //
8   // Official repository: https://github.com/boostorg/json 8   // Official repository: https://github.com/boostorg/json
9   // 9   //
10   10  
11   #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP 11   #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP
12   #define BOOST_JSON_BASIC_PARSER_IMPL_HPP 12   #define BOOST_JSON_BASIC_PARSER_IMPL_HPP
13   13  
14   #include <boost/json/detail/config.hpp> 14   #include <boost/json/detail/config.hpp>
15   #include <boost/json/detail/literals.hpp> 15   #include <boost/json/detail/literals.hpp>
16   #include <boost/json/basic_parser.hpp> 16   #include <boost/json/basic_parser.hpp>
17   #include <boost/json/error.hpp> 17   #include <boost/json/error.hpp>
18   #include <boost/json/detail/buffer.hpp> 18   #include <boost/json/detail/buffer.hpp>
19   #include <boost/json/detail/charconv/from_chars.hpp> 19   #include <boost/json/detail/charconv/from_chars.hpp>
20   #include <boost/json/detail/sse2.hpp> 20   #include <boost/json/detail/sse2.hpp>
21   #include <boost/mp11/algorithm.hpp> 21   #include <boost/mp11/algorithm.hpp>
22   #include <boost/mp11/integral.hpp> 22   #include <boost/mp11/integral.hpp>
23   #include <cmath> 23   #include <cmath>
24   #include <limits> 24   #include <limits>
25   #include <cstring> 25   #include <cstring>
26   26  
27   #ifdef _MSC_VER 27   #ifdef _MSC_VER
28   #pragma warning(push) 28   #pragma warning(push)
29   #pragma warning(disable: 4702) // unreachable code 29   #pragma warning(disable: 4702) // unreachable code
30   #pragma warning(disable: 4127) // conditional expression is constant 30   #pragma warning(disable: 4127) // conditional expression is constant
31   #endif 31   #endif
32   32  
33   /* This file must be manually included to get the 33   /* This file must be manually included to get the
34   function template definitions for basic_parser. 34   function template definitions for basic_parser.
35   */ 35   */
36   36  
37   /* Reference: 37   /* Reference:
38   38  
39   https://www.json.org/ 39   https://www.json.org/
40   40  
41   RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format 41   RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format
42   https://tools.ietf.org/html/rfc7159 42   https://tools.ietf.org/html/rfc7159
43   43  
44   https://ampl.com/netlib/fp/dtoa.c 44   https://ampl.com/netlib/fp/dtoa.c
45   */ 45   */
46   46  
47   #ifndef BOOST_JSON_DOCS 47   #ifndef BOOST_JSON_DOCS
48   48  
49   namespace boost { 49   namespace boost {
50   namespace json { 50   namespace json {
51   namespace detail { 51   namespace detail {
52   52  
53   inline 53   inline
54   double 54   double
HITCBC 55   1033693 pow10(int exp) noexcept 55   1033693 pow10(int exp) noexcept
56   { 56   {
57   static double const tab[618] = { 57   static double const tab[618] = {
58   1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 58   1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301,
59   59  
60   1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 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, 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, 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, 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, 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, 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, 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, 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, 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, 69   1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201,
70   70  
71   1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 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, 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, 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, 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, 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, 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, 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, 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, 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, 80   1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101,
81   81  
82   1e-100, 1e-099, 1e-098, 1e-097, 1e-096, 1e-095, 1e-094, 1e-093, 1e-092, 1e-091, 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, 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, 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, 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, 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, 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, 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, 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, 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, 91   1e-010, 1e-009, 1e-008, 1e-007, 1e-006, 1e-005, 1e-004, 1e-003, 1e-002, 1e-001,
92   92  
93   1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 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, 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, 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, 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, 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, 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, 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, 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, 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, 102   1e+090, 1e+091, 1e+092, 1e+093, 1e+094, 1e+095, 1e+096, 1e+097, 1e+098, 1e+099,
103   103  
104   1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, 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, 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, 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, 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, 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, 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, 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, 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, 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, 113   1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199,
114   114  
115   1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209, 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, 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, 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, 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, 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, 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, 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, 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, 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, 124   1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299,
125   125  
126   1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 }; 126   1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 };
127   127  
HITCBC 128   1033693 if( exp > 308 ) 128   1033693 if( exp > 308 )
129   { 129   {
HITCBC 130   341 return std::numeric_limits<double>::infinity(); 130   341 return std::numeric_limits<double>::infinity();
131   } 131   }
HITCBC 132   1033352 else if( exp < -308 ) 132   1033352 else if( exp < -308 )
133   { 133   {
134   // due to the way pow10 is used by dec_to_float, 134   // due to the way pow10 is used by dec_to_float,
135   // we can afford to return 0.0 here 135   // we can afford to return 0.0 here
HITCBC 136   151 return 0.0; 136   151 return 0.0;
137   } 137   }
138   else 138   else
139   { 139   {
HITCBC 140   1033201 exp += 308; 140   1033201 exp += 308;
HITCBC 141   1033201 BOOST_ASSERT(exp >= 0 && exp < 618); 141   1033201 BOOST_ASSERT(exp >= 0 && exp < 618);
HITCBC 142   1033201 return tab[exp]; 142   1033201 return tab[exp];
143   } 143   }
144   } 144   }
145   145  
146   inline 146   inline
147   double 147   double
HITCBC 148   1033693 dec_to_float( 148   1033693 dec_to_float(
149   std::uint64_t m, 149   std::uint64_t m,
150   std::int32_t e, 150   std::int32_t e,
151   bool neg) noexcept 151   bool neg) noexcept
152   { 152   {
153   // convert to double explicitly to silence warnings 153   // convert to double explicitly to silence warnings
HITCBC 154   1033693 double x = static_cast<double>(m); 154   1033693 double x = static_cast<double>(m);
HITCBC 155   1033693 if(neg) 155   1033693 if(neg)
HITCBC 156   13164 x = -x; 156   13164 x = -x;
157   157  
HITCBC 158   1033693 if(e < -305) 158   1033693 if(e < -305)
159   { 159   {
HITCBC 160   5187 x *= 1e-305 ; 160   5187 x *= 1e-305 ;
HITCBC 161   5187 e += 305; 161   5187 e += 305;
162   } 162   }
163   163  
HITCBC 164   1033693 if(e >= -22 && e < 0) 164   1033693 if(e >= -22 && e < 0)
HITCBC 165   54813 return x / pow10(-e); 165   54813 return x / pow10(-e);
166   166  
HITCBC 167   978880 return x * pow10(e); 167   978880 return x * pow10(e);
168   } 168   }
169   169  
170   inline 170   inline
171   bool 171   bool
172   is_control(char c) noexcept 172   is_control(char c) noexcept
173   { 173   {
174   return static_cast<unsigned char>(c) < 32; 174   return static_cast<unsigned char>(c) < 32;
175   } 175   }
176   176  
177   inline 177   inline
178   int 178   int
HITCBC 179   66931 hex_digit(unsigned char c) noexcept 179   66931 hex_digit(unsigned char c) noexcept
180   { 180   {
181   // by Peter Dimov 181   // by Peter Dimov
HITCBC 182   66931 if( c >= '0' && c <= '9' ) 182   66931 if( c >= '0' && c <= '9' )
HITCBC 183   35759 return c - '0'; 183   35759 return c - '0';
HITCBC 184   31172 c &= ~0x20; 184   31172 c &= ~0x20;
HITCBC 185   31172 if( c >= 'A' && c <= 'F' ) 185   31172 if( c >= 'A' && c <= 'F' )
HITCBC 186   30562 return 10 + c - 'A'; 186   30562 return 10 + c - 'A';
HITCBC 187   610 return -1; 187   610 return -1;
188   } 188   }
189   189  
190   } // detail 190   } // detail
191   191  
192   //---------------------------------------------------------- 192   //----------------------------------------------------------
193   193  
194   template< class Handler > 194   template< class Handler >
195   template< bool StackEmpty_, char First_ > 195   template< bool StackEmpty_, char First_ >
196   struct basic_parser<Handler>:: 196   struct basic_parser<Handler>::
197   parse_number_helper 197   parse_number_helper
198   { 198   {
199   basic_parser* parser; 199   basic_parser* parser;
200   char const* p; 200   char const* p;
201   201  
202   template< std::size_t N > 202   template< std::size_t N >
203   char const* 203   char const*
HITCBC 204   2126888 operator()( mp11::mp_size_t<N> ) const 204   2126888 operator()( mp11::mp_size_t<N> ) const
205   { 205   {
HITCBC 206   4248335 return parser->parse_number( 206   4248335 return parser->parse_number(
HITCBC 207   2126888 p, 207   2126888 p,
208   std::integral_constant<bool, StackEmpty_>(), 208   std::integral_constant<bool, StackEmpty_>(),
209   std::integral_constant<char, First_>(), 209   std::integral_constant<char, First_>(),
210   std::integral_constant< 210   std::integral_constant<
HITCBC 211   2121448 number_precision, static_cast<number_precision>(N)>() ); 211   2121448 number_precision, static_cast<number_precision>(N)>() );
212   } 212   }
213   }; 213   };
214   214  
215   //---------------------------------------------------------- 215   //----------------------------------------------------------
216   216  
217   template<class Handler> 217   template<class Handler>
218   void 218   void
HITCBC 219   210572 basic_parser<Handler>:: 219   210572 basic_parser<Handler>::
220   reserve() 220   reserve()
221   { 221   {
HITCBC 222   210572 if(BOOST_JSON_LIKELY( 222   210572 if(BOOST_JSON_LIKELY(
223   ! st_.empty())) 223   ! st_.empty()))
HITCBC 224   37469 return; 224   37469 return;
225   // Reserve the largest stack we need, 225   // Reserve the largest stack we need,
226   // to avoid reallocation during suspend. 226   // to avoid reallocation during suspend.
HITCBC 227   346206 st_.reserve( 227   346206 st_.reserve(
228   sizeof(state) + // document parsing state 228   sizeof(state) + // document parsing state
229   (sizeof(state) + 229   (sizeof(state) +
HITCBC 230   173103 sizeof(std::size_t)) * depth() + // array and object state + size 230   173103 sizeof(std::size_t)) * depth() + // array and object state + size
231   sizeof(state) + // value parsing state 231   sizeof(state) + // value parsing state
232   sizeof(std::size_t) + // string size 232   sizeof(std::size_t) + // string size
233   sizeof(state)); // comment state 233   sizeof(state)); // comment state
234   } 234   }
235   235  
236   //---------------------------------------------------------- 236   //----------------------------------------------------------
237   // 237   //
238   // The sentinel value is returned by parse functions 238   // The sentinel value is returned by parse functions
239   // to indicate that the parser failed, or suspended. 239   // to indicate that the parser failed, or suspended.
240   // this is used as it is distinct from all valid values 240   // this is used as it is distinct from all valid values
241   // for data in write 241   // for data in write
242   242  
243   template<class Handler> 243   template<class Handler>
244   const char* 244   const char*
HITCBC 245   5341073 basic_parser<Handler>:: 245   5341073 basic_parser<Handler>::
246   sentinel() 246   sentinel()
247   { 247   {
248   // the "+1" ensures that the returned pointer is unique even if 248   // the "+1" ensures that the returned pointer is unique even if
249   // the given input buffer borders on this object 249   // the given input buffer borders on this object
250   return reinterpret_cast< 250   return reinterpret_cast<
HITCBC 251   5341073 const char*>(this) + 1; 251   5341073 const char*>(this) + 1;
252   } 252   }
253   253  
254   template<class Handler> 254   template<class Handler>
255   bool 255   bool
HITCBC 256   2459881 basic_parser<Handler>:: 256   2459881 basic_parser<Handler>::
257   incomplete( 257   incomplete(
258   const detail::const_stream_wrapper& cs) 258   const detail::const_stream_wrapper& cs)
259   { 259   {
HITCBC 260   2459881 return cs.begin() == sentinel(); 260   2459881 return cs.begin() == sentinel();
261   } 261   }
262   262  
263   //---------------------------------------------------------- 263   //----------------------------------------------------------
264   // 264   //
265   // These functions are declared with the BOOST_NOINLINE 265   // These functions are declared with the BOOST_NOINLINE
266   // attribute to avoid polluting the parsers hot-path. 266   // attribute to avoid polluting the parsers hot-path.
267   // They return the canary value to indicate suspension 267   // They return the canary value to indicate suspension
268   // or failure. 268   // or failure.
269   269  
270   template<class Handler> 270   template<class Handler>
271   const char* 271   const char*
272   basic_parser<Handler>:: 272   basic_parser<Handler>::
273   suspend_or_fail(state st) 273   suspend_or_fail(state st)
274   { 274   {
275   if(BOOST_JSON_LIKELY( 275   if(BOOST_JSON_LIKELY(
276   ! ec_ && more_)) 276   ! ec_ && more_))
277   { 277   {
278   // suspend 278   // suspend
279   reserve(); 279   reserve();
280   st_.push_unchecked(st); 280   st_.push_unchecked(st);
281   } 281   }
282   return sentinel(); 282   return sentinel();
283   } 283   }
284   284  
285   template<class Handler> 285   template<class Handler>
286   const char* 286   const char*
HITCBC 287   56176 basic_parser<Handler>:: 287   56176 basic_parser<Handler>::
288   suspend_or_fail( 288   suspend_or_fail(
289   state st, 289   state st,
290   std::size_t n) 290   std::size_t n)
291   { 291   {
HITCBC 292   56176 if(BOOST_JSON_LIKELY( 292   56176 if(BOOST_JSON_LIKELY(
293   ! ec_ && more_)) 293   ! ec_ && more_))
294   { 294   {
295   // suspend 295   // suspend
HITCBC 296   35861 reserve(); 296   35861 reserve();
HITCBC 297   35861 st_.push_unchecked(n); 297   35861 st_.push_unchecked(n);
HITCBC 298   35861 st_.push_unchecked(st); 298   35861 st_.push_unchecked(st);
299   } 299   }
HITCBC 300   56176 return sentinel(); 300   56176 return sentinel();
301   } 301   }
302   302  
303   303  
304   template<class Handler> 304   template<class Handler>
305   const char* 305   const char*
HITCBC 306   19005 basic_parser<Handler>:: 306   19005 basic_parser<Handler>::
307   fail(const char* p) noexcept 307   fail(const char* p) noexcept
308   { 308   {
HITCBC 309   19005 BOOST_ASSERT( p != sentinel() ); 309   19005 BOOST_ASSERT( p != sentinel() );
HITCBC 310   19005 end_ = p; 310   19005 end_ = p;
HITCBC 311   19005 return sentinel(); 311   19005 return sentinel();
312   } 312   }
313   313  
314   template<class Handler> 314   template<class Handler>
315   const char* 315   const char*
HITCBC 316   7774 basic_parser<Handler>:: 316   7774 basic_parser<Handler>::
317   fail( 317   fail(
318   const char* p, 318   const char* p,
319   error ev, 319   error ev,
320   source_location const* loc) noexcept 320   source_location const* loc) noexcept
321   { 321   {
HITCBC 322   7774 BOOST_ASSERT( p != sentinel() ); 322   7774 BOOST_ASSERT( p != sentinel() );
HITCBC 323   7774 end_ = p; 323   7774 end_ = p;
HITCBC 324   7774 ec_.assign(ev, loc); 324   7774 ec_.assign(ev, loc);
HITCBC 325   7774 return sentinel(); 325   7774 return sentinel();
326   } 326   }
327   327  
328   template<class Handler> 328   template<class Handler>
329   const char* 329   const char*
HITCBC 330   11289 basic_parser<Handler>:: 330   11289 basic_parser<Handler>::
331   maybe_suspend( 331   maybe_suspend(
332   const char* p, 332   const char* p,
333   state st) 333   state st)
334   { 334   {
HITCBC 335   11289 if( p != sentinel() ) 335   11289 if( p != sentinel() )
HITCBC 336   9424 end_ = p; 336   9424 end_ = p;
HITCBC 337   11289 if(BOOST_JSON_LIKELY(more_)) 337   11289 if(BOOST_JSON_LIKELY(more_))
338   { 338   {
339   // suspend 339   // suspend
HITCBC 340   11027 reserve(); 340   11027 reserve();
HITCBC 341   11027 st_.push_unchecked(st); 341   11027 st_.push_unchecked(st);
342   } 342   }
HITCBC 343   11289 return sentinel(); 343   11289 return sentinel();
344   } 344   }
345   345  
346   template<class Handler> 346   template<class Handler>
347   const char* 347   const char*
HITCBC 348   38234 basic_parser<Handler>:: 348   38234 basic_parser<Handler>::
349   maybe_suspend( 349   maybe_suspend(
350   const char* p, 350   const char* p,
351   state st, 351   state st,
352   std::size_t n) 352   std::size_t n)
353   { 353   {
HITCBC 354   38234 BOOST_ASSERT( p != sentinel() ); 354   38234 BOOST_ASSERT( p != sentinel() );
HITCBC 355   38234 end_ = p; 355   38234 end_ = p;
HITCBC 356   38234 if(BOOST_JSON_LIKELY(more_)) 356   38234 if(BOOST_JSON_LIKELY(more_))
357   { 357   {
358   // suspend 358   // suspend
HITCBC 359   37833 reserve(); 359   37833 reserve();
HITCBC 360   37833 st_.push_unchecked(n); 360   37833 st_.push_unchecked(n);
HITCBC 361   37833 st_.push_unchecked(st); 361   37833 st_.push_unchecked(st);
362   } 362   }
HITCBC 363   38234 return sentinel(); 363   38234 return sentinel();
364   } 364   }
365   365  
366   template<class Handler> 366   template<class Handler>
367   const char* 367   const char*
HITCBC 368   1123 basic_parser<Handler>:: 368   1123 basic_parser<Handler>::
369   maybe_suspend( 369   maybe_suspend(
370   const char* p, 370   const char* p,
371   state st, 371   state st,
372   const number& num) 372   const number& num)
373   { 373   {
HITCBC 374   1123 BOOST_ASSERT( p != sentinel() ); 374   1123 BOOST_ASSERT( p != sentinel() );
HITCBC 375   1123 end_ = p; 375   1123 end_ = p;
HITCBC 376   1123 if(BOOST_JSON_LIKELY(more_)) 376   1123 if(BOOST_JSON_LIKELY(more_))
377   { 377   {
378   // suspend 378   // suspend
HITCBC 379   1123 num_ = num; 379   1123 num_ = num;
HITCBC 380   1123 reserve(); 380   1123 reserve();
HITCBC 381   1123 st_.push_unchecked(st);; 381   1123 st_.push_unchecked(st);;
382   } 382   }
HITCBC 383   1123 return sentinel(); 383   1123 return sentinel();
384   } 384   }
385   385  
386   template<class Handler> 386   template<class Handler>
387   const char* 387   const char*
HITCBC 388   88657 basic_parser<Handler>:: 388   88657 basic_parser<Handler>::
389   suspend( 389   suspend(
390   const char* p, 390   const char* p,
391   state st) 391   state st)
392   { 392   {
HITCBC 393   88657 BOOST_ASSERT( p != sentinel() ); 393   88657 BOOST_ASSERT( p != sentinel() );
HITCBC 394   88657 end_ = p; 394   88657 end_ = p;
395   // suspend 395   // suspend
HITCBC 396   88657 reserve(); 396   88657 reserve();
HITCBC 397   88657 st_.push_unchecked(st); 397   88657 st_.push_unchecked(st);
HITCBC 398   88657 return sentinel(); 398   88657 return sentinel();
399   } 399   }
400   400  
401   template<class Handler> 401   template<class Handler>
402   const char* 402   const char*
HITCBC 403   36071 basic_parser<Handler>:: 403   36071 basic_parser<Handler>::
404   suspend( 404   suspend(
405   const char* p, 405   const char* p,
406   state st, 406   state st,
407   const number& num) 407   const number& num)
408   { 408   {
HITCBC 409   36071 BOOST_ASSERT( p != sentinel() ); 409   36071 BOOST_ASSERT( p != sentinel() );
HITCBC 410   36071 end_ = p; 410   36071 end_ = p;
411   // suspend 411   // suspend
HITCBC 412   36071 num_ = num; 412   36071 num_ = num;
HITCBC 413   36071 reserve(); 413   36071 reserve();
HITCBC 414   36071 st_.push_unchecked(st); 414   36071 st_.push_unchecked(st);
HITCBC 415   36071 return sentinel(); 415   36071 return sentinel();
416   } 416   }
417   417  
418   template<class Handler> 418   template<class Handler>
419   template< 419   template<
420   bool StackEmpty_/*, 420   bool StackEmpty_/*,
421   bool Terminal_*/> 421   bool Terminal_*/>
422   const char* 422   const char*
HITCBC 423   21737 basic_parser<Handler>:: 423   21737 basic_parser<Handler>::
424   parse_comment(const char* p, 424   parse_comment(const char* p,
425   std::integral_constant<bool, StackEmpty_> stack_empty, 425   std::integral_constant<bool, StackEmpty_> stack_empty,
426   /*std::integral_constant<bool, Terminal_>*/ bool terminal) 426   /*std::integral_constant<bool, Terminal_>*/ bool terminal)
427   { 427   {
HITCBC 428   21737 detail::const_stream_wrapper cs(p, end_); 428   21737 detail::const_stream_wrapper cs(p, end_);
HITCBC 429   21737 const char* start = cs.begin(); 429   21737 const char* start = cs.begin();
430   std::size_t remain; 430   std::size_t remain;
HITCBC 431   21737 if(! stack_empty && ! st_.empty()) 431   21737 if(! stack_empty && ! st_.empty())
432   { 432   {
433   state st; 433   state st;
HITCBC 434   3507 st_.pop(st); 434   3507 st_.pop(st);
HITCBC 435   3507 switch(st) 435   3507 switch(st)
436   { 436   {
MISUBC 437   default: BOOST_JSON_UNREACHABLE(); 437   default: BOOST_JSON_UNREACHABLE();
HITCBC 438   534 case state::com1: goto do_com1; 438   534 case state::com1: goto do_com1;
HITCBC 439   2319 case state::com2: goto do_com2; 439   2319 case state::com2: goto do_com2;
HITCBC 440   438 case state::com3: goto do_com3; 440   438 case state::com3: goto do_com3;
HITCBC 441   216 case state::com4: goto do_com4; 441   216 case state::com4: goto do_com4;
442   } 442   }
443   } 443   }
HITCBC 444   18230 BOOST_ASSERT(*cs == '/'); 444   18230 BOOST_ASSERT(*cs == '/');
HITCBC 445   18230 ++cs; 445   18230 ++cs;
HITCBC 446   18764 do_com1: 446   18764 do_com1:
HITCBC 447   18764 if(BOOST_JSON_UNLIKELY(! cs)) 447   18764 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 448   551 return maybe_suspend(cs.begin(), state::com1); 448   551 return maybe_suspend(cs.begin(), state::com1);
HITCBC 449   18213 switch(*cs) 449   18213 switch(*cs)
450   { 450   {
HITCBC 451   5 default: 451   5 default:
452   { 452   {
453   BOOST_STATIC_CONSTEXPR source_location loc 453   BOOST_STATIC_CONSTEXPR source_location loc
454   = BOOST_CURRENT_LOCATION; 454   = BOOST_CURRENT_LOCATION;
HITCBC 455   5 return fail(cs.begin(), error::syntax, &loc); 455   5 return fail(cs.begin(), error::syntax, &loc);
456   } 456   }
HITCBC 457   10524 case '/': 457   10524 case '/':
HITCBC 458   10524 ++cs; 458   10524 ++cs;
HITCBC 459   12843 do_com2: 459   12843 do_com2:
460   // KRYSTIAN TODO: this is a mess, we have to fix this 460   // KRYSTIAN TODO: this is a mess, we have to fix this
HITCBC 461   12843 remain = cs.remain(); 461   12843 remain = cs.remain();
HITCBC 462   25686 cs = remain ? static_cast<const char*>( 462   25686 cs = remain ? static_cast<const char*>(
HITCBC 463   12843 std::memchr(cs.begin(), '\n', remain)) : sentinel(); 463   12843 std::memchr(cs.begin(), '\n', remain)) : sentinel();
HITCBC 464   12843 if(! cs.begin()) 464   12843 if(! cs.begin())
HITCBC 465   2143 cs = sentinel(); 465   2143 cs = sentinel();
HITCBC 466   12843 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 466   12843 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
467   { 467   {
468   // if the doc does not terminate 468   // if the doc does not terminate
469   // with a newline, treat it as the 469   // with a newline, treat it as the
470   // end of the comment 470   // end of the comment
HITCBC 471   2568 if(terminal && ! more_) 471   2568 if(terminal && ! more_)
472   { 472   {
HITCBC 473   39 if(BOOST_JSON_UNLIKELY(! h_.on_comment( 473   39 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
474   {start, cs.remain(start)}, ec_))) 474   {start, cs.remain(start)}, ec_)))
HITCBC 475   2 return fail(cs.end()); 475   2 return fail(cs.end());
HITCBC 476   35 return cs.end(); 476   35 return cs.end();
477   } 477   }
HITCBC 478   2529 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 478   2529 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
479   {start, cs.remain(start)}, ec_))) 479   {start, cs.remain(start)}, ec_)))
HITCBC 480   95 return fail(cs.end()); 480   95 return fail(cs.end());
HITCBC 481   2339 if(terminal) 481   2339 if(terminal)
HITCBC 482   106 return suspend(cs.end(), state::com2); 482   106 return suspend(cs.end(), state::com2);
HITCBC 483   2233 return maybe_suspend(cs.end(), state::com2); 483   2233 return maybe_suspend(cs.end(), state::com2);
484   } 484   }
HITCBC 485   10275 break; 485   10275 break;
HITCBC 486   1684 case '*': 486   1684 case '*':
487   do 487   do
488   { 488   {
HITCBC 489   9368 ++cs; 489   9368 ++cs;
HITCBC 490   9806 do_com3: 490   9806 do_com3:
491   // KRYSTIAN TODO: this is a mess, we have to fix this 491   // KRYSTIAN TODO: this is a mess, we have to fix this
HITCBC 492   9806 remain = cs.remain(); 492   9806 remain = cs.remain();
HITCBC 493   19612 cs = remain ? static_cast<const char*>( 493   19612 cs = remain ? static_cast<const char*>(
HITCBC 494   9806 std::memchr(cs.begin(), '*', remain)) : sentinel(); 494   9806 std::memchr(cs.begin(), '*', remain)) : sentinel();
HITCBC 495   9806 if(! cs.begin()) 495   9806 if(! cs.begin())
HITCBC 496   242 cs = sentinel(); 496   242 cs = sentinel();
497   // stopped inside a c comment 497   // stopped inside a c comment
HITCBC 498   9806 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 498   9806 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
499   { 499   {
HITCBC 500   503 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 500   503 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
501   {start, cs.remain(start)}, ec_))) 501   {start, cs.remain(start)}, ec_)))
HITCBC 502   30 return fail(cs.end()); 502   30 return fail(cs.end());
HITCBC 503   443 return maybe_suspend(cs.end(), state::com3); 503   443 return maybe_suspend(cs.end(), state::com3);
504   } 504   }
505   // found a asterisk, check if the next char is a slash 505   // found a asterisk, check if the next char is a slash
HITCBC 506   9303 ++cs; 506   9303 ++cs;
HITCBC 507   9519 do_com4: 507   9519 do_com4:
HITCBC 508   9519 if(BOOST_JSON_UNLIKELY(! cs)) 508   9519 if(BOOST_JSON_UNLIKELY(! cs))
509   { 509   {
HITCBC 510   259 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 510   259 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
511   {start, cs.used(start)}, ec_))) 511   {start, cs.used(start)}, ec_)))
HITCBC 512   18 return fail(cs.begin()); 512   18 return fail(cs.begin());
HITCBC 513   223 return maybe_suspend(cs.begin(), state::com4); 513   223 return maybe_suspend(cs.begin(), state::com4);
514   } 514   }
515   } 515   }
HITCBC 516   9260 while(*cs != '/'); 516   9260 while(*cs != '/');
517   } 517   }
HITCBC 518   17851 ++cs; 518   17851 ++cs;
HITCBC 519   17851 if(BOOST_JSON_UNLIKELY(! h_.on_comment( 519   17851 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
520   {start, cs.used(start)}, ec_))) 520   {start, cs.used(start)}, ec_)))
HITCBC 521   964 return fail(cs.begin()); 521   964 return fail(cs.begin());
HITCBC 522   15923 return cs.begin(); 522   15923 return cs.begin();
523   } 523   }
524   524  
525   template<class Handler> 525   template<class Handler>
526   template<bool StackEmpty_> 526   template<bool StackEmpty_>
527   const char* 527   const char*
HITCBC 528   2318439 basic_parser<Handler>:: 528   2318439 basic_parser<Handler>::
529   parse_document(const char* p, 529   parse_document(const char* p,
530   std::integral_constant<bool, StackEmpty_> stack_empty) 530   std::integral_constant<bool, StackEmpty_> stack_empty)
531   { 531   {
HITCBC 532   2318439 detail::const_stream_wrapper cs(p, end_); 532   2318439 detail::const_stream_wrapper cs(p, end_);
HITCBC 533   2318439 if(! stack_empty && ! st_.empty()) 533   2318439 if(! stack_empty && ! st_.empty())
534   { 534   {
535   state st; 535   state st;
HITCBC 536   169624 st_.peek(st); 536   169624 st_.peek(st);
HITCBC 537   169624 switch(st) 537   169624 switch(st)
538   { 538   {
HITCBC 539   83559 default: goto do_doc2; 539   83559 default: goto do_doc2;
HITCBC 540   601 case state::doc1: 540   601 case state::doc1:
HITCBC 541   601 st_.pop(st); 541   601 st_.pop(st);
HITCBC 542   601 goto do_doc1; 542   601 goto do_doc1;
HITCBC 543   85244 case state::doc3: 543   85244 case state::doc3:
HITCBC 544   85244 st_.pop(st); 544   85244 st_.pop(st);
HITCBC 545   85244 goto do_doc3; 545   85244 goto do_doc3;
HITCBC 546   220 case state::com1: case state::com2: 546   220 case state::com1: case state::com2:
547   case state::com3: case state::com4: 547   case state::com3: case state::com4:
HITCBC 548   220 goto do_doc4; 548   220 goto do_doc4;
549   } 549   }
550   } 550   }
HITCBC 551   2148815 do_doc1: 551   2148815 do_doc1:
HITCBC 552   2149416 cs = detail::count_whitespace(cs.begin(), cs.end()); 552   2149416 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 553   2149416 if(BOOST_JSON_UNLIKELY(! cs)) 553   2149416 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 554   633 return maybe_suspend(cs.begin(), state::doc1); 554   633 return maybe_suspend(cs.begin(), state::doc1);
HITCBC 555   2148783 do_doc2: 555   2148783 do_doc2:
HITCBC 556   2232342 switch(+opt_.allow_comments | 556   2232342 switch(+opt_.allow_comments |
HITCBC 557   2232342 (opt_.allow_trailing_commas << 1) | 557   2232342 (opt_.allow_trailing_commas << 1) |
HITCBC 558   2232342 (opt_.allow_invalid_utf8 << 2)) 558   2232342 (opt_.allow_invalid_utf8 << 2))
559   { 559   {
560   // no extensions 560   // no extensions
HITCBC 561   2208660 default: 561   2208660 default:
HITCBC 562   2208660 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); 562   2208660 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 563   2193502 break; 563   2193502 break;
564   // comments 564   // comments
HITCBC 565   13551 case 1: 565   13551 case 1:
HITCBC 566   13551 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); 566   13551 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 567   11288 break; 567   11288 break;
568   // trailing 568   // trailing
HITCBC 569   6710 case 2: 569   6710 case 2:
HITCBC 570   6710 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); 570   6710 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 571   5117 break; 571   5117 break;
572   // comments & trailing 572   // comments & trailing
HITCBC 573   761 case 3: 573   761 case 3:
HITCBC 574   761 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); 574   761 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 575   761 break; 575   761 break;
576   // skip validation 576   // skip validation
HITCBC 577   760 case 4: 577   760 case 4:
HITCBC 578   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); 578   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 579   760 break; 579   760 break;
580   // comments & skip validation 580   // comments & skip validation
HITCBC 581   760 case 5: 581   760 case 5:
HITCBC 582   760 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); 582   760 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 583   760 break; 583   760 break;
584   // trailing & skip validation 584   // trailing & skip validation
HITCBC 585   760 case 6: 585   760 case 6:
HITCBC 586   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); 586   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 587   760 break; 587   760 break;
588   // comments & trailing & skip validation 588   // comments & trailing & skip validation
HITCBC 589   380 case 7: 589   380 case 7:
HITCBC 590   380 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); 590   380 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 591   380 break; 591   380 break;
592   } 592   }
HITCBC 593   2213328 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 593   2213328 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
594   // the appropriate state has already been pushed into stack 594   // the appropriate state has already been pushed into stack
HITCBC 595   110765 return sentinel(); 595   110765 return sentinel();
HITCBC 596   2102563 do_doc3: 596   2102563 do_doc3:
HITCBC 597   2188139 cs = detail::count_whitespace(cs.begin(), cs.end()); 597   2188139 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 598   2188139 if(BOOST_JSON_UNLIKELY(! cs)) 598   2188139 if(BOOST_JSON_UNLIKELY(! cs))
599   { 599   {
HITCBC 600   2185541 if(more_) 600   2185541 if(more_)
HITCBC 601   88551 return suspend(cs.begin(), state::doc3); 601   88551 return suspend(cs.begin(), state::doc3);
602   } 602   }
HITCBC 603   2598 else if(opt_.allow_comments && *cs == '/') 603   2598 else if(opt_.allow_comments && *cs == '/')
604   { 604   {
HITCBC 605   536 do_doc4: 605   536 do_doc4:
HITCBC 606   756 cs = parse_comment(cs.begin(), stack_empty, std::true_type()); 606   756 cs = parse_comment(cs.begin(), stack_empty, std::true_type());
HITCBC 607   671 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 607   671 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 608   339 return sentinel(); 608   339 return sentinel();
HITCBC 609   332 goto do_doc3; 609   332 goto do_doc3;
610   } 610   }
HITCBC 611   2099052 return cs.begin(); 611   2099052 return cs.begin();
612   } 612   }
613   613  
614   template<class Handler> 614   template<class Handler>
615   template< 615   template<
616   bool StackEmpty_, 616   bool StackEmpty_,
617   bool AllowComments_/*, 617   bool AllowComments_/*,
618   bool AllowTrailing_, 618   bool AllowTrailing_,
619   bool AllowBadUTF8_*/> 619   bool AllowBadUTF8_*/>
620   const char* 620   const char*
HITCBC 621   2349972 basic_parser<Handler>:: 621   2349972 basic_parser<Handler>::
622   parse_value(const char* p, 622   parse_value(const char* p,
623   std::integral_constant<bool, StackEmpty_> stack_empty, 623   std::integral_constant<bool, StackEmpty_> stack_empty,
624   std::integral_constant<bool, AllowComments_> allow_comments, 624   std::integral_constant<bool, AllowComments_> allow_comments,
625   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 625   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
626   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 626   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
627   bool allow_bad_utf16) 627   bool allow_bad_utf16)
628   { 628   {
HITCBC 629   2349972 if(stack_empty || st_.empty()) 629   2349972 if(stack_empty || st_.empty())
630   { 630   {
HITCBC 631   2248027 loop: 631   2248027 loop:
HITCBC 632   2252943 switch(*p) 632   2252943 switch(*p)
633   { 633   {
HITCBC 634   22753 case '0': 634   22753 case '0':
HITCBC 635   22753 return mp11::mp_with_index<3>( 635   22753 return mp11::mp_with_index<3>(
HITCBC 636   22753 static_cast<unsigned char>(opt_.numbers), 636   22753 static_cast<unsigned char>(opt_.numbers),
HITCBC 637   22092 parse_number_helper<true, '0'>{ this, p }); 637   22092 parse_number_helper<true, '0'>{ this, p });
HITCBC 638   25178 case '-': 638   25178 case '-':
HITCBC 639   25178 return mp11::mp_with_index<3>( 639   25178 return mp11::mp_with_index<3>(
HITCBC 640   25178 static_cast<unsigned char>(opt_.numbers), 640   25178 static_cast<unsigned char>(opt_.numbers),
HITCBC 641   24066 parse_number_helper<true, '-'>{ this, p }); 641   24066 parse_number_helper<true, '-'>{ this, p });
HITCBC 642   2041766 case '1': case '2': case '3': 642   2041766 case '1': case '2': case '3':
643   case '4': case '5': case '6': 643   case '4': case '5': case '6':
644   case '7': case '8': case '9': 644   case '7': case '8': case '9':
HITCBC 645   2041766 return mp11::mp_with_index<3>( 645   2041766 return mp11::mp_with_index<3>(
HITCBC 646   2041766 static_cast<unsigned char>(opt_.numbers), 646   2041766 static_cast<unsigned char>(opt_.numbers),
HITCBC 647   2038922 parse_number_helper<true, '+'>{ this, p }); 647   2038922 parse_number_helper<true, '+'>{ this, p });
HITCBC 648   11380 case 'n': 648   11380 case 'n':
HITCBC 649   11380 return parse_literal( p, detail::literals_c<detail::literals::null>() ); 649   11380 return parse_literal( p, detail::literals_c<detail::literals::null>() );
HITCBC 650   664 case 't': 650   664 case 't':
HITCBC 651   664 return parse_literal( p, detail::literals_c<detail::literals::true_>() ); 651   664 return parse_literal( p, detail::literals_c<detail::literals::true_>() );
HITCBC 652   722 case 'f': 652   722 case 'f':
HITCBC 653   722 return parse_literal( p, detail::literals_c<detail::literals::false_>() ); 653   722 return parse_literal( p, detail::literals_c<detail::literals::false_>() );
HITCBC 654   681 case 'I': 654   681 case 'I':
HITCBC 655   681 if( !opt_.allow_infinity_and_nan ) 655   681 if( !opt_.allow_infinity_and_nan )
656   { 656   {
657   BOOST_STATIC_CONSTEXPR source_location loc 657   BOOST_STATIC_CONSTEXPR source_location loc
658   = BOOST_CURRENT_LOCATION; 658   = BOOST_CURRENT_LOCATION;
HITCBC 659   24 return fail(p, error::syntax, &loc); 659   24 return fail(p, error::syntax, &loc);
660   } 660   }
HITCBC 661   657 return parse_literal( p, detail::literals_c<detail::literals::infinity>() ); 661   657 return parse_literal( p, detail::literals_c<detail::literals::infinity>() );
HITCBC 662   231 case 'N': 662   231 case 'N':
HITCBC 663   231 if( !opt_.allow_infinity_and_nan ) 663   231 if( !opt_.allow_infinity_and_nan )
664   { 664   {
665   BOOST_STATIC_CONSTEXPR source_location loc 665   BOOST_STATIC_CONSTEXPR source_location loc
666   = BOOST_CURRENT_LOCATION; 666   = BOOST_CURRENT_LOCATION;
HITCBC 667   30 return fail(p, error::syntax, &loc); 667   30 return fail(p, error::syntax, &loc);
668   } 668   }
HITCBC 669   201 return parse_literal(p, detail::literals_c<detail::literals::nan>() ); 669   201 return parse_literal(p, detail::literals_c<detail::literals::nan>() );
HITCBC 670   47577 case '"': 670   47577 case '"':
HITCBC 671   47577 return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); 671   47577 return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
HITCBC 672   20618 case '[': 672   20618 case '[':
HITCBC 673   20618 return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 673   20618 return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 674   74131 case '{': 674   74131 case '{':
HITCBC 675   74131 return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 675   74131 return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 676   6125 case '/': 676   6125 case '/':
HITCBC 677   6125 if(! allow_comments) 677   6125 if(! allow_comments)
678   { 678   {
679   BOOST_STATIC_CONSTEXPR source_location loc 679   BOOST_STATIC_CONSTEXPR source_location loc
680   = BOOST_CURRENT_LOCATION; 680   = BOOST_CURRENT_LOCATION;
HITCBC 681   284 return fail(p, error::syntax, &loc); 681   284 return fail(p, error::syntax, &loc);
682   } 682   }
HITCBC 683   5841 p = parse_comment(p, stack_empty, std::false_type()); 683   5841 p = parse_comment(p, stack_empty, std::false_type());
684   // KRYSTIAN NOTE: incomplete takes const_stream, we either 684   // KRYSTIAN NOTE: incomplete takes const_stream, we either
685   // can add an overload, change the existing one to take a pointer, 685   // can add an overload, change the existing one to take a pointer,
686   // or just leave it as is 686   // or just leave it as is
HITCBC 687   5605 if(BOOST_JSON_UNLIKELY(p == sentinel())) 687   5605 if(BOOST_JSON_UNLIKELY(p == sentinel()))
HITCBC 688   591 return maybe_suspend(p, state::val2); 688   591 return maybe_suspend(p, state::val2);
689   BOOST_FALLTHROUGH; 689   BOOST_FALLTHROUGH;
690   case ' ': 690   case ' ':
691   case '\t': 691   case '\t':
692   case '\n': 692   case '\n':
693   case '\r': 693   case '\r':
HITCBC 694   5026 p = detail::count_whitespace(p, end_); 694   5026 p = detail::count_whitespace(p, end_);
HITCBC 695   5026 if(BOOST_JSON_UNLIKELY(p == end_)) 695   5026 if(BOOST_JSON_UNLIKELY(p == end_))
HITCBC 696   110 return maybe_suspend(p, state::val1); 696   110 return maybe_suspend(p, state::val1);
HITCBC 697   4916 goto loop; 697   4916 goto loop;
HITCBC 698   1105 default: 698   1105 default:
699   { 699   {
700   BOOST_STATIC_CONSTEXPR source_location loc 700   BOOST_STATIC_CONSTEXPR source_location loc
701   = BOOST_CURRENT_LOCATION; 701   = BOOST_CURRENT_LOCATION;
HITCBC 702   1105 return fail(p, error::syntax, &loc); 702   1105 return fail(p, error::syntax, &loc);
703   } 703   }
704   } 704   }
705   } 705   }
HITCBC 706   101945 return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 706   101945 return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
707   } 707   }
708   708  
709   template<class Handler> 709   template<class Handler>
710   template< 710   template<
711   bool AllowComments_/*, 711   bool AllowComments_/*,
712   bool AllowTrailing_, 712   bool AllowTrailing_,
713   bool AllowBadUTF8_*/> 713   bool AllowBadUTF8_*/>
714   const char* 714   const char*
HITCBC 715   101945 basic_parser<Handler>:: 715   101945 basic_parser<Handler>::
716   resume_value(const char* p, 716   resume_value(const char* p,
717   std::integral_constant<bool, AllowComments_> allow_comments, 717   std::integral_constant<bool, AllowComments_> allow_comments,
718   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 718   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
719   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 719   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
720   bool allow_bad_utf16) 720   bool allow_bad_utf16)
721   { 721   {
722   state st; 722   state st;
HITCBC 723   101945 st_.peek(st); 723   101945 st_.peek(st);
HITCBC 724   101945 switch(st) 724   101945 switch(st)
725   { 725   {
MISUBC 726   default: BOOST_JSON_UNREACHABLE(); 726   default: BOOST_JSON_UNREACHABLE();
HITCBC 727   1924 case state::lit1: 727   1924 case state::lit1:
HITCBC 728   1924 return parse_literal(p, detail::literals_c<detail::literals::resume>() ); 728   1924 return parse_literal(p, detail::literals_c<detail::literals::resume>() );
729   729  
HITCBC 730   20259 case state::str1: case state::str2: 730   20259 case state::str1: case state::str2:
731   case state::str8: 731   case state::str8:
HITCBC 732   20259 return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); 732   20259 return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
733   733  
HITCBC 734   5730 case state::arr1: case state::arr2: 734   5730 case state::arr1: case state::arr2:
735   case state::arr3: case state::arr4: 735   case state::arr3: case state::arr4:
736   case state::arr5: case state::arr6: 736   case state::arr5: case state::arr6:
HITCBC 737   5730 return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 737   5730 return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
738   738  
HITCBC 739   35058 case state::obj1: case state::obj2: 739   35058 case state::obj1: case state::obj2:
740   case state::obj3: case state::obj4: 740   case state::obj3: case state::obj4:
741   case state::obj5: case state::obj6: 741   case state::obj5: case state::obj6:
742   case state::obj7: case state::obj8: 742   case state::obj7: case state::obj8:
743   case state::obj9: case state::obj10: 743   case state::obj9: case state::obj10:
744   case state::obj11: 744   case state::obj11:
HITCBC 745   35058 return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 745   35058 return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
746   746  
HITCBC 747   37191 case state::num1: case state::num2: 747   37191 case state::num1: case state::num2:
748   case state::num3: case state::num4: 748   case state::num3: case state::num4:
749   case state::num5: case state::num6: 749   case state::num5: case state::num6:
750   case state::num7: case state::num8: 750   case state::num7: case state::num8:
751   case state::exp1: case state::exp2: 751   case state::exp1: case state::exp2:
752   case state::exp3: 752   case state::exp3:
HITCBC 753   37191 return mp11::mp_with_index<3>( 753   37191 return mp11::mp_with_index<3>(
HITCBC 754   37191 static_cast<unsigned char>(opt_.numbers), 754   37191 static_cast<unsigned char>(opt_.numbers),
HITCBC 755   36368 parse_number_helper<false, 0>{ this, p }); 755   36368 parse_number_helper<false, 0>{ this, p });
756   756  
757   // KRYSTIAN NOTE: these are special cases 757   // KRYSTIAN NOTE: these are special cases
HITCBC 758   108 case state::val1: 758   108 case state::val1:
759   { 759   {
HITCBC 760   108 st_.pop(st); 760   108 st_.pop(st);
HITCBC 761   108 BOOST_ASSERT(st_.empty()); 761   108 BOOST_ASSERT(st_.empty());
HITCBC 762   108 p = detail::count_whitespace(p, end_); 762   108 p = detail::count_whitespace(p, end_);
HITCBC 763   108 if(BOOST_JSON_UNLIKELY(p == end_)) 763   108 if(BOOST_JSON_UNLIKELY(p == end_))
MISUBC 764   return maybe_suspend(p, state::val1); 764   return maybe_suspend(p, state::val1);
HITCBC 765   108 return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 765   108 return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
766   } 766   }
767   767  
HITCBC 768   1608 case state::val2: 768   1608 case state::val2:
769   { 769   {
HITCBC 770   1608 st_.pop(st); 770   1608 st_.pop(st);
HITCBC 771   1608 p = parse_comment(p, std::false_type(), std::false_type()); 771   1608 p = parse_comment(p, std::false_type(), std::false_type());
HITCBC 772   1590 if(BOOST_JSON_UNLIKELY(p == sentinel())) 772   1590 if(BOOST_JSON_UNLIKELY(p == sentinel()))
HITCBC 773   1274 return maybe_suspend(p, state::val2); 773   1274 return maybe_suspend(p, state::val2);
HITCBC 774   316 if(BOOST_JSON_UNLIKELY( p == end_ )) 774   316 if(BOOST_JSON_UNLIKELY( p == end_ ))
HITCBC 775   77 return maybe_suspend(p, state::val3); 775   77 return maybe_suspend(p, state::val3);
HITCBC 776   239 BOOST_ASSERT(st_.empty()); 776   239 BOOST_ASSERT(st_.empty());
HITCBC 777   239 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); 777   239 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
778   } 778   }
779   779  
HITCBC 780   67 case state::val3: 780   67 case state::val3:
781   { 781   {
HITCBC 782   67 st_.pop(st); 782   67 st_.pop(st);
HITCBC 783   67 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); 783   67 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
784   } 784   }
785   } 785   }
786   } 786   }
787   787  
788   template<class Handler> 788   template<class Handler>
789   template<class Literal> 789   template<class Literal>
790   const char* 790   const char*
HITCBC 791   16564 basic_parser<Handler>:: 791   16564 basic_parser<Handler>::
792   parse_literal(const char* p, Literal) 792   parse_literal(const char* p, Literal)
793   { 793   {
794   using L = detail::literals; 794   using L = detail::literals;
795   795  
796   std::size_t cur_lit; 796   std::size_t cur_lit;
797   std::size_t offset; 797   std::size_t offset;
798   798  
HITCBC 799   16564 detail::const_stream_wrapper cs(p, end_); 799   16564 detail::const_stream_wrapper cs(p, end_);
800   BOOST_IF_CONSTEXPR( Literal::value != L::resume ) 800   BOOST_IF_CONSTEXPR( Literal::value != L::resume )
801   { 801   {
HITCBC 802   13633 constexpr std::size_t index = literal_index(Literal::value); 802   13633 constexpr std::size_t index = literal_index(Literal::value);
HITCBC 803   13633 constexpr char const* literal = detail::literal_strings[index]; 803   13633 constexpr char const* literal = detail::literal_strings[index];
HITCBC 804   13633 constexpr std::size_t sz = detail::literal_sizes[index]; 804   13633 constexpr std::size_t sz = detail::literal_sizes[index];
805   805  
HITCBC 806   13633 if(BOOST_JSON_LIKELY( cs.remain() >= sz )) 806   13633 if(BOOST_JSON_LIKELY( cs.remain() >= sz ))
807   { 807   {
HITCBC 808   11983 int const cmp = std::memcmp(cs.begin(), literal, sz); 808   11983 int const cmp = std::memcmp(cs.begin(), literal, sz);
HITCBC 809   11983 if( cmp != 0 ) 809   11983 if( cmp != 0 )
810   { 810   {
811   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 811   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 812   197 return fail(cs.begin(), error::syntax, &loc); 812   197 return fail(cs.begin(), error::syntax, &loc);
813   } 813   }
814   814  
815   BOOST_IF_CONSTEXPR( Literal::value == L::null ) 815   BOOST_IF_CONSTEXPR( Literal::value == L::null )
816   { 816   {
HITCBC 817   10788 if(BOOST_JSON_UNLIKELY( 817   10788 if(BOOST_JSON_UNLIKELY(
818   ! h_.on_null(ec_))) 818   ! h_.on_null(ec_)))
HITCBC 819   161 return fail(cs.begin()); 819   161 return fail(cs.begin());
820   } 820   }
821   else BOOST_IF_CONSTEXPR( Literal::value == L::true_ ) 821   else BOOST_IF_CONSTEXPR( Literal::value == L::true_ )
822   { 822   {
HITCBC 823   384 if(BOOST_JSON_UNLIKELY( 823   384 if(BOOST_JSON_UNLIKELY(
824   ! h_.on_bool(true, ec_))) 824   ! h_.on_bool(true, ec_)))
HITCBC 825   14 return fail(cs.begin()); 825   14 return fail(cs.begin());
826   } 826   }
827   else BOOST_IF_CONSTEXPR( Literal::value == L::false_ ) 827   else BOOST_IF_CONSTEXPR( Literal::value == L::false_ )
828   { 828   {
HITCBC 829   406 if(BOOST_JSON_UNLIKELY( 829   406 if(BOOST_JSON_UNLIKELY(
830   ! h_.on_bool(false, ec_))) 830   ! h_.on_bool(false, ec_)))
HITCBC 831   13 return fail(cs.begin()); 831   13 return fail(cs.begin());
832   } 832   }
833   else BOOST_IF_CONSTEXPR( Literal::value == L::infinity ) 833   else BOOST_IF_CONSTEXPR( Literal::value == L::infinity )
834   { 834   {
HITCBC 835   103 if(BOOST_JSON_UNLIKELY( 835   103 if(BOOST_JSON_UNLIKELY(
836   ! h_.on_double( 836   ! h_.on_double(
837   std::numeric_limits<double>::infinity(), 837   std::numeric_limits<double>::infinity(),
838   string_view(literal, sz), 838   string_view(literal, sz),
839   ec_))) 839   ec_)))
HITCBC 840   13 return fail(cs.begin()); 840   13 return fail(cs.begin());
841   } 841   }
842   else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity ) 842   else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity )
843   { 843   {
HITCBC 844   9 if(BOOST_JSON_UNLIKELY( 844   9 if(BOOST_JSON_UNLIKELY(
845   ! h_.on_double( 845   ! h_.on_double(
846   -std::numeric_limits<double>::infinity(), 846   -std::numeric_limits<double>::infinity(),
847   string_view(literal, sz), 847   string_view(literal, sz),
848   ec_))) 848   ec_)))
HITCBC 849   1 return fail(cs.begin()); 849   1 return fail(cs.begin());
850   } 850   }
851   else BOOST_IF_CONSTEXPR( Literal::value == L::nan ) 851   else BOOST_IF_CONSTEXPR( Literal::value == L::nan )
852   { 852   {
HITCBC 853   96 if(BOOST_JSON_UNLIKELY( 853   96 if(BOOST_JSON_UNLIKELY(
854   ! h_.on_double( 854   ! h_.on_double(
855   std::numeric_limits<double>::quiet_NaN(), 855   std::numeric_limits<double>::quiet_NaN(),
856   string_view(literal, sz), 856   string_view(literal, sz),
857   ec_))) 857   ec_)))
HITCBC 858   12 return fail(cs.begin()); 858   12 return fail(cs.begin());
859   } 859   }
860   else 860   else
861   { 861   {
862   BOOST_JSON_UNREACHABLE(); 862   BOOST_JSON_UNREACHABLE();
863   } 863   }
864   864  
HITCBC 865   11362 cs += sz; 865   11362 cs += sz;
HITCBC 866   11362 return cs.begin(); 866   11362 return cs.begin();
867   } 867   }
868   868  
HITCBC 869   1650 offset = 0; 869   1650 offset = 0;
HITCBC 870   1650 cur_lit = index; 870   1650 cur_lit = index;
871   } 871   }
872   else 872   else
873   { 873   {
874   state st; 874   state st;
HITCBC 875   2931 st_.pop(st); 875   2931 st_.pop(st);
HITCBC 876   2931 BOOST_ASSERT( st == state::lit1 ); 876   2931 BOOST_ASSERT( st == state::lit1 );
877   877  
HITCBC 878   2931 cur_lit = cur_lit_; 878   2931 cur_lit = cur_lit_;
HITCBC 879   2931 offset = lit_offset_; 879   2931 offset = lit_offset_;
880   } 880   }
881   881  
HITCBC 882   4581 std::size_t const lit_size = detail::literal_sizes[cur_lit]; 882   4581 std::size_t const lit_size = detail::literal_sizes[cur_lit];
HITCBC 883   4581 std::size_t const size = (std::min)( lit_size - offset, cs.remain() ); 883   4581 std::size_t const size = (std::min)( lit_size - offset, cs.remain() );
HITCBC 884   4581 int cmp = 0; 884   4581 int cmp = 0;
HITCBC 885   4581 if(BOOST_JSON_LIKELY( cs.begin() )) 885   4581 if(BOOST_JSON_LIKELY( cs.begin() ))
HITCBC 886   4580 cmp = std::memcmp( 886   4580 cmp = std::memcmp(
HITCBC 887   4580 cs.begin(), detail::literal_strings[cur_lit] + offset, size ); 887   4580 cs.begin(), detail::literal_strings[cur_lit] + offset, size );
HITCBC 888   4581 if( cmp != 0 ) 888   4581 if( cmp != 0 )
889   { 889   {
890   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 890   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 891   699 return fail(cs.begin(), error::syntax, &loc); 891   699 return fail(cs.begin(), error::syntax, &loc);
892   } 892   }
893   893  
HITCBC 894   3882 if(BOOST_JSON_UNLIKELY( offset + size < lit_size )) 894   3882 if(BOOST_JSON_UNLIKELY( offset + size < lit_size ))
895   { 895   {
HITCBC 896   1990 BOOST_ASSERT( cur_lit < 256 ); 896   1990 BOOST_ASSERT( cur_lit < 256 );
HITCBC 897   1990 cur_lit_ = static_cast<unsigned char>( cur_lit ); 897   1990 cur_lit_ = static_cast<unsigned char>( cur_lit );
HITCBC 898   1990 BOOST_ASSERT( offset + size < 256 ); 898   1990 BOOST_ASSERT( offset + size < 256 );
HITCBC 899   1990 lit_offset_ = static_cast<unsigned char>( offset + size ); 899   1990 lit_offset_ = static_cast<unsigned char>( offset + size );
HITCBC 900   1990 return maybe_suspend(cs.begin() + size, state::lit1); 900   1990 return maybe_suspend(cs.begin() + size, state::lit1);
901   } 901   }
902   902  
HITCBC 903   1892 switch( static_cast<L>(cur_lit) ) 903   1892 switch( static_cast<L>(cur_lit) )
904   { 904   {
HITCBC 905   472 case L::null: 905   472 case L::null:
HITCBC 906   472 if(BOOST_JSON_UNLIKELY( 906   472 if(BOOST_JSON_UNLIKELY(
907   ! h_.on_null(ec_))) 907   ! h_.on_null(ec_)))
HITCBC 908   61 return fail(cs.begin()); 908   61 return fail(cs.begin());
HITCBC 909   351 break; 909   351 break;
HITCBC 910   152 case L::true_: 910   152 case L::true_:
HITCBC 911   152 if(BOOST_JSON_UNLIKELY( 911   152 if(BOOST_JSON_UNLIKELY(
912   ! h_.on_bool(true, ec_))) 912   ! h_.on_bool(true, ec_)))
HITCBC 913   22 return fail(cs.begin()); 913   22 return fail(cs.begin());
HITCBC 914   109 break; 914   109 break;
HITCBC 915   198 case L::false_: 915   198 case L::false_:
HITCBC 916   198 if(BOOST_JSON_UNLIKELY( 916   198 if(BOOST_JSON_UNLIKELY(
917   ! h_.on_bool(false, ec_))) 917   ! h_.on_bool(false, ec_)))
HITCBC 918   28 return fail(cs.begin()); 918   28 return fail(cs.begin());
HITCBC 919   142 break; 919   142 break;
HITCBC 920   308 case L::infinity: 920   308 case L::infinity:
HITCBC 921   308 if(BOOST_JSON_UNLIKELY( 921   308 if(BOOST_JSON_UNLIKELY(
922   ! h_.on_double( 922   ! h_.on_double(
923   std::numeric_limits<double>::infinity(), 923   std::numeric_limits<double>::infinity(),
924   string_view( 924   string_view(
925   detail::literal_strings[ literal_index(L::infinity) ], 925   detail::literal_strings[ literal_index(L::infinity) ],
926   detail::literal_sizes[ literal_index(L::infinity) ]), 926   detail::literal_sizes[ literal_index(L::infinity) ]),
927   ec_))) 927   ec_)))
HITCBC 928   49 return fail(cs.begin()); 928   49 return fail(cs.begin());
HITCBC 929   210 break; 929   210 break;
HITCBC 930   686 case L::neg_infinity: 930   686 case L::neg_infinity:
HITCBC 931   686 if(BOOST_JSON_UNLIKELY( 931   686 if(BOOST_JSON_UNLIKELY(
932   ! h_.on_double( 932   ! h_.on_double(
933   -std::numeric_limits<double>::infinity(), 933   -std::numeric_limits<double>::infinity(),
934   string_view( 934   string_view(
935   detail::literal_strings[ literal_index(L::neg_infinity) ], 935   detail::literal_strings[ literal_index(L::neg_infinity) ],
936   detail::literal_sizes[ literal_index(L::neg_infinity) ]), 936   detail::literal_sizes[ literal_index(L::neg_infinity) ]),
937   ec_))) 937   ec_)))
HITCBC 938   102 return fail(cs.begin()); 938   102 return fail(cs.begin());
HITCBC 939   482 break; 939   482 break;
HITCBC 940   76 case L::nan: 940   76 case L::nan:
HITCBC 941   76 if(BOOST_JSON_UNLIKELY( 941   76 if(BOOST_JSON_UNLIKELY(
942   ! h_.on_double( 942   ! h_.on_double(
943   std::numeric_limits<double>::quiet_NaN(), 943   std::numeric_limits<double>::quiet_NaN(),
944   string_view( 944   string_view(
945   detail::literal_strings[ literal_index(L::nan) ], 945   detail::literal_strings[ literal_index(L::nan) ],
946   detail::literal_sizes[ literal_index(L::nan) ]), 946   detail::literal_sizes[ literal_index(L::nan) ]),
947   ec_))) 947   ec_)))
HITCBC 948   12 return fail(cs.begin()); 948   12 return fail(cs.begin());
HITCBC 949   52 break; 949   52 break;
MISUBC 950   default: BOOST_JSON_UNREACHABLE(); 950   default: BOOST_JSON_UNREACHABLE();
951   } 951   }
952   952  
HITCBC 953   1346 cs += size; 953   1346 cs += size;
HITCBC 954   1346 return cs.begin(); 954   1346 return cs.begin();
955   } 955   }
956   956  
957   //---------------------------------------------------------- 957   //----------------------------------------------------------
958   958  
959   template<class Handler> 959   template<class Handler>
960   template<bool StackEmpty_, bool IsKey_> 960   template<bool StackEmpty_, bool IsKey_>
961   const char* 961   const char*
HITCBC 962   161311 basic_parser<Handler>:: 962   161311 basic_parser<Handler>::
963   parse_string(const char* p, 963   parse_string(const char* p,
964   std::integral_constant<bool, StackEmpty_> stack_empty, 964   std::integral_constant<bool, StackEmpty_> stack_empty,
965   std::integral_constant<bool, IsKey_> is_key, 965   std::integral_constant<bool, IsKey_> is_key,
966   bool allow_bad_utf8, 966   bool allow_bad_utf8,
967   bool allow_bad_utf16) 967   bool allow_bad_utf16)
968   { 968   {
HITCBC 969   161311 detail::const_stream_wrapper cs(p, end_); 969   161311 detail::const_stream_wrapper cs(p, end_);
970   std::size_t total; 970   std::size_t total;
971   char const* start; 971   char const* start;
972   std::size_t size; 972   std::size_t size;
HITCBC 973   161311 if(! stack_empty && ! st_.empty()) 973   161311 if(! stack_empty && ! st_.empty())
974   { 974   {
975   state st; 975   state st;
HITCBC 976   32906 st_.pop(st); 976   32906 st_.pop(st);
HITCBC 977   32906 st_.pop(total); 977   32906 st_.pop(total);
HITCBC 978   32906 switch(st) 978   32906 switch(st)
979   { 979   {
MISUBC 980   default: BOOST_JSON_UNREACHABLE(); 980   default: BOOST_JSON_UNREACHABLE();
HITCBC 981   3149 case state::str2: goto do_str2; 981   3149 case state::str2: goto do_str2;
HITCBC 982   1864 case state::str8: goto do_str8; 982   1864 case state::str8: goto do_str8;
HITCBC 983   27893 case state::str1: break; 983   27893 case state::str1: break;
984   } 984   }
985   } 985   }
986   else 986   else
987   { 987   {
HITCBC 988   128405 BOOST_ASSERT(*cs == '\x22'); // '"' 988   128405 BOOST_ASSERT(*cs == '\x22'); // '"'
HITCBC 989   128405 ++cs; 989   128405 ++cs;
HITCBC 990   128405 total = 0; 990   128405 total = 0;
991   } 991   }
992   992  
HITCBC 993   164791 do_str1: 993   164791 do_str1:
HITCBC 994   164791 start = cs.begin(); 994   164791 start = cs.begin();
HITCBC 995   329582 cs = allow_bad_utf8? 995   329582 cs = allow_bad_utf8?
HITCBC 996   2177 detail::count_valid<true>(cs.begin(), cs.end()): 996   2177 detail::count_valid<true>(cs.begin(), cs.end()):
HITCBC 997   162614 detail::count_valid<false>(cs.begin(), cs.end()); 997   162614 detail::count_valid<false>(cs.begin(), cs.end());
HITCBC 998   164791 size = cs.used(start); 998   164791 size = cs.used(start);
HITCBC 999   164791 if(is_key) 999   164791 if(is_key)
1000   { 1000   {
HITCBC 1001   46694 BOOST_ASSERT(total <= Handler::max_key_size); 1001   46694 BOOST_ASSERT(total <= Handler::max_key_size);
HITCBC 1002   94005 if(BOOST_JSON_UNLIKELY(size > 1002   94005 if(BOOST_JSON_UNLIKELY(size >
1003   Handler::max_key_size - total)) 1003   Handler::max_key_size - total))
1004   { 1004   {
1005   BOOST_STATIC_CONSTEXPR source_location loc 1005   BOOST_STATIC_CONSTEXPR source_location loc
1006   = BOOST_CURRENT_LOCATION; 1006   = BOOST_CURRENT_LOCATION;
HITCBC 1007   3 return fail(cs.begin(), error::key_too_large, &loc); 1007   3 return fail(cs.begin(), error::key_too_large, &loc);
1008   } 1008   }
1009   } 1009   }
1010   else 1010   else
1011   { 1011   {
HITCBC 1012   35324 BOOST_ASSERT(total <= Handler::max_string_size); 1012   35324 BOOST_ASSERT(total <= Handler::max_string_size);
HITCBC 1013   70786 if(BOOST_JSON_UNLIKELY(size > 1013   70786 if(BOOST_JSON_UNLIKELY(size >
1014   Handler::max_string_size - total)) 1014   Handler::max_string_size - total))
1015   { 1015   {
1016   BOOST_STATIC_CONSTEXPR source_location loc 1016   BOOST_STATIC_CONSTEXPR source_location loc
1017   = BOOST_CURRENT_LOCATION; 1017   = BOOST_CURRENT_LOCATION;
HITCBC 1018   3 return fail(cs.begin(), error::string_too_large, &loc); 1018   3 return fail(cs.begin(), error::string_too_large, &loc);
1019   } 1019   }
1020   } 1020   }
HITCBC 1021   164785 total += size; 1021   164785 total += size;
HITCBC 1022   164785 if(BOOST_JSON_UNLIKELY(! cs)) 1022   164785 if(BOOST_JSON_UNLIKELY(! cs))
1023   { 1023   {
1024   // call handler if the string isn't empty 1024   // call handler if the string isn't empty
HITCBC 1025   30227 if(BOOST_JSON_LIKELY(size)) 1025   30227 if(BOOST_JSON_LIKELY(size))
1026   { 1026   {
1027   { 1027   {
HITCBC 1028   27066 bool r = is_key? 1028   27066 bool r = is_key?
HITCBC 1029   12404 h_.on_key_part( {start, size}, total, ec_ ): 1029   12404 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1030   15996 h_.on_string_part( {start, size}, total, ec_ ); 1030   15996 h_.on_string_part( {start, size}, total, ec_ );
1031   1031  
HITCBC 1032   25958 if(BOOST_JSON_UNLIKELY(!r)) 1032   25958 if(BOOST_JSON_UNLIKELY(!r))
1033   { 1033   {
HITCBC 1034   1110 return fail(cs.begin()); 1034   1110 return fail(cs.begin());
1035   } 1035   }
1036   } 1036   }
1037   } 1037   }
HITCBC 1038   28009 return maybe_suspend(cs.begin(), state::str1, total); 1038   28009 return maybe_suspend(cs.begin(), state::str1, total);
1039   } 1039   }
1040   // at this point all valid characters have been skipped, so any remaining 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 1041   // if there are any more characters, they are either escaped, or incomplete
1042   // utf8, or invalid utf8 1042   // utf8, or invalid utf8
HITCBC 1043   134558 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"' 1043   134558 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"'
1044   { 1044   {
1045   // sequence is invalid or incomplete 1045   // sequence is invalid or incomplete
HITCBC 1046   15071 if((*cs & 0x80) && !allow_bad_utf8) 1046   15071 if((*cs & 0x80) && !allow_bad_utf8)
1047   { 1047   {
HITCBC 1048   3465 seq_.save(cs.begin(), cs.remain()); 1048   3465 seq_.save(cs.begin(), cs.remain());
HITCBC 1049   3465 if(BOOST_JSON_UNLIKELY(seq_.complete())) 1049   3465 if(BOOST_JSON_UNLIKELY(seq_.complete()))
1050   { 1050   {
1051   BOOST_STATIC_CONSTEXPR source_location loc 1051   BOOST_STATIC_CONSTEXPR source_location loc
1052   = BOOST_CURRENT_LOCATION; 1052   = BOOST_CURRENT_LOCATION;
HITCBC 1053   1557 return fail(cs.begin(), error::syntax, &loc); 1053   1557 return fail(cs.begin(), error::syntax, &loc);
1054   } 1054   }
HITCBC 1055   1908 if(BOOST_JSON_LIKELY(size)) 1055   1908 if(BOOST_JSON_LIKELY(size))
1056   { 1056   {
HITCBC 1057   245 bool const r = is_key? 1057   245 bool const r = is_key?
HITCBC 1058   22 h_.on_key_part( {start, size}, total, ec_ ): 1058   22 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1059   245 h_.on_string_part( {start, size}, total, ec_ ); 1059   245 h_.on_string_part( {start, size}, total, ec_ );
HITCBC 1060   223 if(BOOST_JSON_UNLIKELY( !r )) 1060   223 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1061   22 return fail( cs.begin() ); 1061   22 return fail( cs.begin() );
1062   } 1062   }
HITCBC 1063   1864 return maybe_suspend(cs.end(), state::str8, total); 1063   1864 return maybe_suspend(cs.end(), state::str8, total);
1064   } 1064   }
HITCBC 1065   11606 else if(BOOST_JSON_LIKELY(*cs == '\\')) 1065   11606 else if(BOOST_JSON_LIKELY(*cs == '\\'))
1066   { 1066   {
1067   // flush unescaped run from input 1067   // flush unescaped run from input
HITCBC 1068   11497 if(BOOST_JSON_LIKELY(size)) 1068   11497 if(BOOST_JSON_LIKELY(size))
1069   { 1069   {
HITCBC 1070   4250 bool const r = is_key? 1070   4250 bool const r = is_key?
HITCBC 1071   1226 h_.on_key_part( {start, size}, total, ec_ ): 1071   1226 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1072   3554 h_.on_string_part( {start, size}, total, ec_ ); 1072   3554 h_.on_string_part( {start, size}, total, ec_ );
HITCBC 1073   3766 if(BOOST_JSON_UNLIKELY( !r )) 1073   3766 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1074   484 return fail( cs.begin() ); 1074   484 return fail( cs.begin() );
1075   } 1075   }
HITCBC 1076   7247 do_str2: 1076   7247 do_str2:
HITCBC 1077   13678 cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16); 1077   13678 cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16);
HITCBC 1078   12716 if(BOOST_JSON_UNLIKELY( incomplete(cs) )) 1078   12716 if(BOOST_JSON_UNLIKELY( incomplete(cs) ))
HITCBC 1079   5473 return suspend_or_fail(state::str2, total); 1079   5473 return suspend_or_fail(state::str2, total);
1080   1080  
HITCBC 1081   7243 goto do_str1; 1081   7243 goto do_str1;
1082   } 1082   }
1083   // illegal control 1083   // illegal control
1084   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1084   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1085   109 return fail(cs.begin(), error::syntax, &loc); 1085   109 return fail(cs.begin(), error::syntax, &loc);
1086   } 1086   }
1087   1087  
1088   { 1088   {
HITCBC 1089   119487 bool r = is_key? 1089   119487 bool r = is_key?
HITCBC 1090   84511 h_.on_key( {start, size}, total, ec_ ): 1090   84511 h_.on_key( {start, size}, total, ec_ ):
HITCBC 1091   41985 h_.on_string( {start, size}, total, ec_ ); 1091   41985 h_.on_string( {start, size}, total, ec_ );
1092   1092  
HITCBC 1093   115113 if(BOOST_JSON_UNLIKELY(!r)) 1093   115113 if(BOOST_JSON_UNLIKELY(!r))
1094   { 1094   {
HITCBC 1095   4318 return fail(cs.begin()); 1095   4318 return fail(cs.begin());
1096   } 1096   }
1097   } 1097   }
1098   1098  
HITCBC 1099   110795 ++cs; 1099   110795 ++cs;
HITCBC 1100   110795 return cs.begin(); 1100   110795 return cs.begin();
1101   1101  
HITCBC 1102   1864 do_str8: 1102   1864 do_str8:
HITCBC 1103   1864 uint8_t needed = seq_.needed(); 1103   1864 uint8_t needed = seq_.needed();
HITCBC 1104   1864 if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) )) 1104   1864 if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) ))
MISUBC 1105   return maybe_suspend(cs.end(), state::str8, total); 1105   return maybe_suspend(cs.end(), state::str8, total);
HITCBC 1106   1864 if(BOOST_JSON_UNLIKELY( !seq_.valid() )) 1106   1864 if(BOOST_JSON_UNLIKELY( !seq_.valid() ))
1107   { 1107   {
1108   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1108   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1109   210 return fail(cs.begin(), error::syntax, &loc); 1109   210 return fail(cs.begin(), error::syntax, &loc);
1110   } 1110   }
1111   { 1111   {
HITCBC 1112   1654 std::size_t const n = seq_.length(); 1112   1654 std::size_t const n = seq_.length();
1113   bool r; 1113   bool r;
HITCBC 1114   1654 if(is_key) 1114   1654 if(is_key)
1115   { 1115   {
HITCBC 1116   2 BOOST_ASSERT(total <= Handler::max_key_size); 1116   2 BOOST_ASSERT(total <= Handler::max_key_size);
HITCBC 1117   2 if(BOOST_JSON_UNLIKELY(n > 1117   2 if(BOOST_JSON_UNLIKELY(n >
1118   Handler::max_key_size - total)) 1118   Handler::max_key_size - total))
1119   { 1119   {
1120   BOOST_STATIC_CONSTEXPR source_location loc 1120   BOOST_STATIC_CONSTEXPR source_location loc
1121   = BOOST_CURRENT_LOCATION; 1121   = BOOST_CURRENT_LOCATION;
HITCBC 1122   1 return fail(cs.begin(), error::key_too_large, &loc); 1122   1 return fail(cs.begin(), error::key_too_large, &loc);
1123   } 1123   }
HITCBC 1124   1 total += n; 1124   1 total += n;
HITCBC 1125   1 r = h_.on_key_part( {seq_.data(), n}, total, ec_ ); 1125   1 r = h_.on_key_part( {seq_.data(), n}, total, ec_ );
1126   } 1126   }
1127   else 1127   else
1128   { 1128   {
HITCBC 1129   1 BOOST_ASSERT(total <= Handler::max_string_size); 1129   1 BOOST_ASSERT(total <= Handler::max_string_size);
HITCBC 1130   1652 if(BOOST_JSON_UNLIKELY(n > 1130   1652 if(BOOST_JSON_UNLIKELY(n >
1131   Handler::max_string_size - total)) 1131   Handler::max_string_size - total))
1132   { 1132   {
1133   BOOST_STATIC_CONSTEXPR source_location loc 1133   BOOST_STATIC_CONSTEXPR source_location loc
1134   = BOOST_CURRENT_LOCATION; 1134   = BOOST_CURRENT_LOCATION;
HITCBC 1135   1 return fail(cs.begin(), error::string_too_large, &loc); 1135   1 return fail(cs.begin(), error::string_too_large, &loc);
1136   } 1136   }
HITCBC 1137   1651 total += n; 1137   1651 total += n;
HITCBC 1138   1651 r = h_.on_string_part( {seq_.data(), n}, total, ec_ ); 1138   1651 r = h_.on_string_part( {seq_.data(), n}, total, ec_ );
1139   } 1139   }
HITCBC 1140   1451 if(BOOST_JSON_UNLIKELY( !r )) 1140   1451 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1141   201 return fail( cs.begin() ); 1141   201 return fail( cs.begin() );
1142   } 1142   }
HITCBC 1143   1250 cs += needed; 1143   1250 cs += needed;
HITCBC 1144   1250 goto do_str1; 1144   1250 goto do_str1;
1145   } 1145   }
1146   1146  
1147   template<class Handler> 1147   template<class Handler>
1148   template<bool StackEmpty_> 1148   template<bool StackEmpty_>
1149   const char* 1149   const char*
HITCBC 1150   13678 basic_parser<Handler>:: 1150   13678 basic_parser<Handler>::
1151   parse_escaped( 1151   parse_escaped(
1152   const char* p, 1152   const char* p,
1153   std::size_t& total, 1153   std::size_t& total,
1154   std::integral_constant<bool, StackEmpty_> stack_empty, 1154   std::integral_constant<bool, StackEmpty_> stack_empty,
1155   bool is_key, 1155   bool is_key,
1156   bool allow_bad_utf16) 1156   bool allow_bad_utf16)
1157   { 1157   {
HITCBC 1158   13678 constexpr unsigned urc = 0xFFFD; // Unicode replacement character 1158   13678 constexpr unsigned urc = 0xFFFD; // Unicode replacement character
HITCBC 1159   13678 auto const ev_too_large = is_key? 1159   13678 auto const ev_too_large = is_key?
1160   error::key_too_large : error::string_too_large; 1160   error::key_too_large : error::string_too_large;
HITCBC 1161   13678 auto const max_size = is_key? 1161   13678 auto const max_size = is_key?
1162   Handler::max_key_size : Handler::max_string_size; 1162   Handler::max_key_size : Handler::max_string_size;
1163   int digit; 1163   int digit;
1164   1164  
1165   //--------------------------------------------------------------- 1165   //---------------------------------------------------------------
1166   // 1166   //
1167   // To handle escapes, a local temporary buffer accumulates 1167   // To handle escapes, a local temporary buffer accumulates
1168   // the unescaped result. The algorithm attempts to fill the 1168   // the unescaped result. The algorithm attempts to fill the
1169   // buffer to capacity before invoking the handler. 1169   // buffer to capacity before invoking the handler.
1170   // In some cases the temporary buffer needs to be flushed 1170   // In some cases the temporary buffer needs to be flushed
1171   // before it is full: 1171   // before it is full:
1172   // * When the closing double quote is seen 1172   // * When the closing double quote is seen
1173   // * When there in no more input (and more is expected later) 1173   // * When there in no more input (and more is expected later)
1174   // A goal of the algorithm is to call the handler as few times 1174   // A goal of the algorithm is to call the handler as few times
1175   // as possible. Thus, when the first escape is encountered, 1175   // as possible. Thus, when the first escape is encountered,
1176   // the algorithm attempts to fill the temporary buffer first. 1176   // the algorithm attempts to fill the temporary buffer first.
1177   // 1177   //
HITCBC 1178   13678 detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp; 1178   13678 detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp;
1179   1179  
1180   // Unescaped JSON is never larger than its escaped version. 1180   // Unescaped JSON is never larger than its escaped version.
1181   // To efficiently process only what will fit in the temporary buffer, 1181   // To efficiently process only what will fit in the temporary buffer,
1182   // the size of the input stream is temporarily "clipped" to the size 1182   // the size of the input stream is temporarily "clipped" to the size
1183   // of the temporary buffer. 1183   // of the temporary buffer.
1184   // handle escaped character 1184   // handle escaped character
HITCBC 1185   13678 detail::clipped_const_stream cs(p, end_); 1185   13678 detail::clipped_const_stream cs(p, end_);
HITCBC 1186   13678 cs.clip(temp.max_size()); 1186   13678 cs.clip(temp.max_size());
1187   1187  
HITCBC 1188   13678 if(! stack_empty && ! st_.empty()) 1188   13678 if(! stack_empty && ! st_.empty())
1189   { 1189   {
1190   state st; 1190   state st;
HITCBC 1191   3149 st_.pop(st); 1191   3149 st_.pop(st);
HITCBC 1192   3149 switch(st) 1192   3149 switch(st)
1193   { 1193   {
MISUBC 1194   default: BOOST_JSON_UNREACHABLE(); 1194   default: BOOST_JSON_UNREACHABLE();
HITCBC 1195   528 case state::str3: goto do_str3; 1195   528 case state::str3: goto do_str3;
HITCBC 1196   392 case state::str4: goto do_str4; 1196   392 case state::str4: goto do_str4;
HITCBC 1197   390 case state::str5: goto do_str5; 1197   390 case state::str5: goto do_str5;
HITCBC 1198   389 case state::str6: goto do_str6; 1198   389 case state::str6: goto do_str6;
HITCBC 1199   386 case state::str7: goto do_str7; 1199   386 case state::str7: goto do_str7;
HITCBC 1200   232 case state::sur1: goto do_sur1; 1200   232 case state::sur1: goto do_sur1;
HITCBC 1201   188 case state::sur2: goto do_sur2; 1201   188 case state::sur2: goto do_sur2;
HITCBC 1202   164 case state::sur3: goto do_sur3; 1202   164 case state::sur3: goto do_sur3;
HITCBC 1203   162 case state::sur4: goto do_sur4; 1203   162 case state::sur4: goto do_sur4;
HITCBC 1204   160 case state::sur5: goto do_sur5; 1204   160 case state::sur5: goto do_sur5;
HITCBC 1205   158 case state::sur6: goto do_sur6; 1205   158 case state::sur6: goto do_sur6;
1206   } 1206   }
1207   } 1207   }
1208   1208  
HITCBC 1209   3781 while(true) 1209   3781 while(true)
1210   { 1210   {
HITCBC 1211   14310 BOOST_ASSERT( temp.capacity() ); 1211   14310 BOOST_ASSERT( temp.capacity() );
HITCBC 1212   14310 BOOST_ASSERT(*cs == '\\'); 1212   14310 BOOST_ASSERT(*cs == '\\');
HITCBC 1213   14310 ++cs; 1213   14310 ++cs;
HITCBC 1214   15169 do_str3: 1214   15169 do_str3:
HITCBC 1215   15374 if(BOOST_JSON_UNLIKELY(! cs)) 1215   15374 if(BOOST_JSON_UNLIKELY(! cs))
1216   { 1216   {
HITCBC 1217   561 if(BOOST_JSON_LIKELY(! temp.empty())) 1217   561 if(BOOST_JSON_LIKELY(! temp.empty()))
1218   { 1218   {
MISUBC 1219   BOOST_ASSERT(total <= max_size); 1219   BOOST_ASSERT(total <= max_size);
HITCBC 1220   100 if(BOOST_JSON_UNLIKELY( 1220   100 if(BOOST_JSON_UNLIKELY(
1221   temp.size() > max_size - total)) 1221   temp.size() > max_size - total))
1222   { 1222   {
1223   BOOST_STATIC_CONSTEXPR source_location loc 1223   BOOST_STATIC_CONSTEXPR source_location loc
1224   = BOOST_CURRENT_LOCATION; 1224   = BOOST_CURRENT_LOCATION;
MISUBC 1225   return fail(cs.begin(), ev_too_large, &loc); 1225   return fail(cs.begin(), ev_too_large, &loc);
1226   } 1226   }
HITCBC 1227   100 total += temp.size(); 1227   100 total += temp.size();
1228   { 1228   {
HITCBC 1229   91 bool r = is_key 1229   91 bool r = is_key
HITCBC 1230   100 ? h_.on_key_part(temp.get(), total, ec_) 1230   100 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1231   100 : h_.on_string_part(temp.get(), total, ec_); 1231   100 : h_.on_string_part(temp.get(), total, ec_);
1232   1232  
HITCBC 1233   91 if(BOOST_JSON_UNLIKELY(!r)) 1233   91 if(BOOST_JSON_UNLIKELY(!r))
1234   { 1234   {
HITCBC 1235   9 return fail(cs.begin()); 1235   9 return fail(cs.begin());
1236   } 1236   }
1237   } 1237   }
HITCBC 1238   82 temp.clear(); 1238   82 temp.clear();
1239   } 1239   }
HITCBC 1240   543 cs.clip(temp.max_size()); 1240   543 cs.clip(temp.max_size());
HITCBC 1241   543 if(BOOST_JSON_UNLIKELY(! cs)) 1241   543 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1242   543 return maybe_suspend(cs.begin(), state::str3); 1242   543 return maybe_suspend(cs.begin(), state::str3);
1243   } 1243   }
HITCBC 1244   14813 switch(*cs) 1244   14813 switch(*cs)
1245   { 1245   {
HITCBC 1246   191 default: 1246   191 default:
1247   { 1247   {
1248   BOOST_STATIC_CONSTEXPR source_location loc 1248   BOOST_STATIC_CONSTEXPR source_location loc
1249   = BOOST_CURRENT_LOCATION; 1249   = BOOST_CURRENT_LOCATION;
HITCBC 1250   191 return fail(cs.begin(), error::syntax, &loc); 1250   191 return fail(cs.begin(), error::syntax, &loc);
1251   } 1251   }
HITCBC 1252   265 case '\x22': // '"' 1252   265 case '\x22': // '"'
HITCBC 1253   265 temp.push_back('\x22'); 1253   265 temp.push_back('\x22');
HITCBC 1254   265 ++cs; 1254   265 ++cs;
HITCBC 1255   265 break; 1255   265 break;
HITCBC 1256   178 case '\\': 1256   178 case '\\':
HITCBC 1257   178 temp.push_back('\\'); 1257   178 temp.push_back('\\');
HITCBC 1258   178 ++cs; 1258   178 ++cs;
HITCBC 1259   178 break; 1259   178 break;
HITCBC 1260   96 case '/': 1260   96 case '/':
HITCBC 1261   96 temp.push_back('/'); 1261   96 temp.push_back('/');
HITCBC 1262   96 ++cs; 1262   96 ++cs;
HITCBC 1263   96 break; 1263   96 break;
HITCBC 1264   112 case 'b': 1264   112 case 'b':
HITCBC 1265   112 temp.push_back('\x08'); 1265   112 temp.push_back('\x08');
HITCBC 1266   112 ++cs; 1266   112 ++cs;
HITCBC 1267   112 break; 1267   112 break;
HITCBC 1268   108 case 'f': 1268   108 case 'f':
HITCBC 1269   108 temp.push_back('\x0c'); 1269   108 temp.push_back('\x0c');
HITCBC 1270   108 ++cs; 1270   108 ++cs;
HITCBC 1271   108 break; 1271   108 break;
HITCBC 1272   1763 case 'n': 1272   1763 case 'n':
HITCBC 1273   1763 temp.push_back('\x0a'); 1273   1763 temp.push_back('\x0a');
HITCBC 1274   1763 ++cs; 1274   1763 ++cs;
HITCBC 1275   1763 break; 1275   1763 break;
HITCBC 1276   146 case 'r': 1276   146 case 'r':
HITCBC 1277   146 temp.push_back('\x0d'); 1277   146 temp.push_back('\x0d');
HITCBC 1278   146 ++cs; 1278   146 ++cs;
HITCBC 1279   146 break; 1279   146 break;
HITCBC 1280   266 case 't': 1280   266 case 't':
HITCBC 1281   266 temp.push_back('\x09'); 1281   266 temp.push_back('\x09');
HITCBC 1282   266 ++cs; 1282   266 ++cs;
HITCBC 1283   266 break; 1283   266 break;
HITCBC 1284   11688 case 'u': 1284   11688 case 'u':
1285   // utf16 escape 1285   // utf16 escape
1286   // 1286   //
1287   // fast path only when the buffer 1287   // fast path only when the buffer
1288   // is large enough for 2 surrogates 1288   // is large enough for 2 surrogates
HITCBC 1289   11688 if(BOOST_JSON_LIKELY(cs.remain() > 10)) 1289   11688 if(BOOST_JSON_LIKELY(cs.remain() > 10))
1290   { 1290   {
1291   // KRYSTIAN TODO: this could be done 1291   // KRYSTIAN TODO: this could be done
1292   // with fewer instructions 1292   // with fewer instructions
HITCBC 1293   11394 digit = detail::load_little_endian<4>( 1293   11394 digit = detail::load_little_endian<4>(
HITCBC 1294   5697 cs.begin() + 1); 1294   5697 cs.begin() + 1);
HITCBC 1295   5697 int d4 = detail::hex_digit(static_cast< 1295   5697 int d4 = detail::hex_digit(static_cast<
HITCBC 1296   5697 unsigned char>(digit >> 24)); 1296   5697 unsigned char>(digit >> 24));
HITCBC 1297   5697 int d3 = detail::hex_digit(static_cast< 1297   5697 int d3 = detail::hex_digit(static_cast<
HITCBC 1298   5697 unsigned char>(digit >> 16)); 1298   5697 unsigned char>(digit >> 16));
HITCBC 1299   5697 int d2 = detail::hex_digit(static_cast< 1299   5697 int d2 = detail::hex_digit(static_cast<
HITCBC 1300   5697 unsigned char>(digit >> 8)); 1300   5697 unsigned char>(digit >> 8));
HITCBC 1301   5697 int d1 = detail::hex_digit(static_cast< 1301   5697 int d1 = detail::hex_digit(static_cast<
1302   unsigned char>(digit)); 1302   unsigned char>(digit));
HITCBC 1303   5697 if(BOOST_JSON_UNLIKELY( 1303   5697 if(BOOST_JSON_UNLIKELY(
1304   (d1 | d2 | d3 | d4) == -1)) 1304   (d1 | d2 | d3 | d4) == -1))
1305   { 1305   {
HITCBC 1306   60 if(d1 != -1) 1306   60 if(d1 != -1)
HITCBC 1307   45 ++cs; 1307   45 ++cs;
HITCBC 1308   60 if(d2 != -1) 1308   60 if(d2 != -1)
HITCBC 1309   30 ++cs; 1309   30 ++cs;
HITCBC 1310   60 if(d3 != -1) 1310   60 if(d3 != -1)
HITCBC 1311   15 ++cs; 1311   15 ++cs;
1312   BOOST_STATIC_CONSTEXPR source_location loc 1312   BOOST_STATIC_CONSTEXPR source_location loc
1313   = BOOST_CURRENT_LOCATION; 1313   = BOOST_CURRENT_LOCATION;
HITCBC 1314   60 return fail(cs.begin(), error::expected_hex_digit, &loc); 1314   60 return fail(cs.begin(), error::expected_hex_digit, &loc);
1315   } 1315   }
1316   // 32 bit unicode scalar value 1316   // 32 bit unicode scalar value
HITCBC 1317   5637 unsigned u1 = 1317   5637 unsigned u1 =
HITCBC 1318   5637 (d1 << 12) + (d2 << 8) + 1318   5637 (d1 << 12) + (d2 << 8) +
HITCBC 1319   5637 (d3 << 4) + d4; 1319   5637 (d3 << 4) + d4;
1320   // valid unicode scalar values are 1320   // valid unicode scalar values are
1321   // [0, D7FF] and [E000, 10FFFF] 1321   // [0, D7FF] and [E000, 10FFFF]
1322   // values within this range are valid utf-8 1322   // values within this range are valid utf-8
1323   // code points and invalid leading surrogates. 1323   // code points and invalid leading surrogates.
HITCBC 1324   5637 if(BOOST_JSON_LIKELY( 1324   5637 if(BOOST_JSON_LIKELY(
1325   u1 < 0xd800 || u1 > 0xdfff)) 1325   u1 < 0xd800 || u1 > 0xdfff))
1326   { 1326   {
HITCBC 1327   1340 cs += 5; 1327   1340 cs += 5;
HITCBC 1328   1340 temp.append_utf8(u1); 1328   1340 temp.append_utf8(u1);
HITCBC 1329   1340 break; 1329   1340 break;
1330   } 1330   }
HITCBC 1331   4297 if(BOOST_JSON_UNLIKELY(u1 > 0xdbff)) 1331   4297 if(BOOST_JSON_UNLIKELY(u1 > 0xdbff))
1332   { 1332   {
1333   // If it's an illegal leading surrogate and 1333   // If it's an illegal leading surrogate and
1334   // the parser does not allow it, return an error. 1334   // the parser does not allow it, return an error.
HITCBC 1335   707 if(!allow_bad_utf16) 1335   707 if(!allow_bad_utf16)
1336   { 1336   {
1337   BOOST_STATIC_CONSTEXPR source_location loc 1337   BOOST_STATIC_CONSTEXPR source_location loc
1338   = BOOST_CURRENT_LOCATION; 1338   = BOOST_CURRENT_LOCATION;
HITCBC 1339   122 return fail(cs.begin(), error::illegal_leading_surrogate, 1339   122 return fail(cs.begin(), error::illegal_leading_surrogate,
HITCBC 1340   122 &loc); 1340   122 &loc);
1341   } 1341   }
1342   // Otherwise, append the Unicode replacement character 1342   // Otherwise, append the Unicode replacement character
1343   else 1343   else
1344   { 1344   {
HITCBC 1345   585 cs += 5; 1345   585 cs += 5;
HITCBC 1346   585 temp.append_utf8(urc); 1346   585 temp.append_utf8(urc);
HITCBC 1347   585 break; 1347   585 break;
1348   } 1348   }
1349   } 1349   }
HITCBC 1350   3590 cs += 5; 1350   3590 cs += 5;
1351   // KRYSTIAN TODO: this can be a two byte load 1351   // KRYSTIAN TODO: this can be a two byte load
1352   // and a single comparison. We lose error information, 1352   // and a single comparison. We lose error information,
1353   // but it's faster. 1353   // but it's faster.
HITCBC 1354   3590 if(BOOST_JSON_UNLIKELY(*cs != '\\')) 1354   3590 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
1355   { 1355   {
1356   // If the next character is not a backslash and 1356   // If the next character is not a backslash and
1357   // the parser does not allow it, return a syntax error. 1357   // the parser does not allow it, return a syntax error.
HITCBC 1358   156 if(!allow_bad_utf16) 1358   156 if(!allow_bad_utf16)
1359   { 1359   {
1360   BOOST_STATIC_CONSTEXPR source_location loc 1360   BOOST_STATIC_CONSTEXPR source_location loc
1361   = BOOST_CURRENT_LOCATION; 1361   = BOOST_CURRENT_LOCATION;
HITCBC 1362   15 return fail(cs.begin(), error::syntax, &loc); 1362   15 return fail(cs.begin(), error::syntax, &loc);
1363   } 1363   }
1364   // Otherwise, append the Unicode replacement character since 1364   // Otherwise, append the Unicode replacement character since
1365   // the first code point is a valid leading surrogate 1365   // the first code point is a valid leading surrogate
1366   else 1366   else
1367   { 1367   {
HITCBC 1368   141 temp.append_utf8(urc); 1368   141 temp.append_utf8(urc);
HITCBC 1369   141 break; 1369   141 break;
1370   } 1370   }
1371   } 1371   }
HITCBC 1372   3434 ++cs; 1372   3434 ++cs;
HITCBC 1373   3434 if(BOOST_JSON_UNLIKELY(*cs != 'u')) 1373   3434 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
1374   { 1374   {
HITCBC 1375   220 if (!allow_bad_utf16) 1375   220 if (!allow_bad_utf16)
1376   { 1376   {
1377   BOOST_STATIC_CONSTEXPR source_location loc 1377   BOOST_STATIC_CONSTEXPR source_location loc
1378   = BOOST_CURRENT_LOCATION; 1378   = BOOST_CURRENT_LOCATION;
HITCBC 1379   15 return fail(cs.begin(), error::syntax, &loc); 1379   15 return fail(cs.begin(), error::syntax, &loc);
1380   } 1380   }
1381   // Otherwise, append the Unicode replacement character since 1381   // Otherwise, append the Unicode replacement character since
1382   // the first code point is a valid leading surrogate 1382   // the first code point is a valid leading surrogate
1383   else 1383   else
1384   { 1384   {
HITCBC 1385   205 temp.append_utf8(urc); 1385   205 temp.append_utf8(urc);
HITCBC 1386   205 goto do_str3; 1386   205 goto do_str3;
1387   } 1387   }
1388   } 1388   }
HITCBC 1389   3214 ++cs; 1389   3214 ++cs;
HITCBC 1390   3214 digit = detail::load_little_endian<4>(cs.begin()); 1390   3214 digit = detail::load_little_endian<4>(cs.begin());
HITCBC 1391   3214 d4 = detail::hex_digit(static_cast< 1391   3214 d4 = detail::hex_digit(static_cast<
HITCBC 1392   3214 unsigned char>(digit >> 24)); 1392   3214 unsigned char>(digit >> 24));
HITCBC 1393   3214 d3 = detail::hex_digit(static_cast< 1393   3214 d3 = detail::hex_digit(static_cast<
HITCBC 1394   3214 unsigned char>(digit >> 16)); 1394   3214 unsigned char>(digit >> 16));
HITCBC 1395   3214 d2 = detail::hex_digit(static_cast< 1395   3214 d2 = detail::hex_digit(static_cast<
HITCBC 1396   3214 unsigned char>(digit >> 8)); 1396   3214 unsigned char>(digit >> 8));
HITCBC 1397   3214 d1 = detail::hex_digit(static_cast< 1397   3214 d1 = detail::hex_digit(static_cast<
1398   unsigned char>(digit)); 1398   unsigned char>(digit));
HITCBC 1399   3214 if(BOOST_JSON_UNLIKELY( 1399   3214 if(BOOST_JSON_UNLIKELY(
1400   (d1 | d2 | d3 | d4) == -1)) 1400   (d1 | d2 | d3 | d4) == -1))
1401   { 1401   {
HITCBC 1402   90 if(d1 != -1) 1402   90 if(d1 != -1)
HITCBC 1403   75 ++cs; 1403   75 ++cs;
HITCBC 1404   90 if(d2 != -1) 1404   90 if(d2 != -1)
HITCBC 1405   45 ++cs; 1405   45 ++cs;
HITCBC 1406   90 if(d3 != -1) 1406   90 if(d3 != -1)
HITCBC 1407   15 ++cs; 1407   15 ++cs;
1408   BOOST_STATIC_CONSTEXPR source_location loc 1408   BOOST_STATIC_CONSTEXPR source_location loc
1409   = BOOST_CURRENT_LOCATION; 1409   = BOOST_CURRENT_LOCATION;
HITCBC 1410   90 return fail(cs.begin(), error::expected_hex_digit, &loc); 1410   90 return fail(cs.begin(), error::expected_hex_digit, &loc);
1411   } 1411   }
HITCBC 1412   3124 unsigned u2 = 1412   3124 unsigned u2 =
HITCBC 1413   3124 (d1 << 12) + (d2 << 8) + 1413   3124 (d1 << 12) + (d2 << 8) +
HITCBC 1414   3124 (d3 << 4) + d4; 1414   3124 (d3 << 4) + d4;
1415   // Check if the second code point is a valid trailing surrogate. 1415   // Check if the second code point is a valid trailing surrogate.
1416   // Valid trailing surrogates are [DC00, DFFF] 1416   // Valid trailing surrogates are [DC00, DFFF]
HITCBC 1417   3124 if(BOOST_JSON_UNLIKELY( 1417   3124 if(BOOST_JSON_UNLIKELY(
1418   u2 < 0xdc00 || u2 > 0xdfff)) 1418   u2 < 0xdc00 || u2 > 0xdfff))
1419   { 1419   {
1420   // If not valid and the parser does not allow it, return an error. 1420   // If not valid and the parser does not allow it, return an error.
HITCBC 1421   1353 if(!allow_bad_utf16) 1421   1353 if(!allow_bad_utf16)
1422   { 1422   {
1423   BOOST_STATIC_CONSTEXPR source_location loc 1423   BOOST_STATIC_CONSTEXPR source_location loc
1424   = BOOST_CURRENT_LOCATION; 1424   = BOOST_CURRENT_LOCATION;
HITCBC 1425   136 return fail(cs.begin(), error::illegal_trailing_surrogate, 1425   136 return fail(cs.begin(), error::illegal_trailing_surrogate,
HITCBC 1426   136 &loc); 1426   136 &loc);
1427   } 1427   }
1428   // Append the replacement character for the 1428   // Append the replacement character for the
1429   // first leading surrogate. 1429   // first leading surrogate.
HITCBC 1430   1217 cs += 4; 1430   1217 cs += 4;
HITCBC 1431   1217 temp.append_utf8(urc); 1431   1217 temp.append_utf8(urc);
1432   // Check if the second code point is a 1432   // Check if the second code point is a
1433   // valid unicode scalar value (invalid leading 1433   // valid unicode scalar value (invalid leading
1434   // or trailing surrogate) 1434   // or trailing surrogate)
HITCBC 1435   1217 if (u2 < 0xd800 || u2 > 0xdbff) 1435   1217 if (u2 < 0xd800 || u2 > 0xdbff)
1436   { 1436   {
HITCBC 1437   524 temp.append_utf8(u2); 1437   524 temp.append_utf8(u2);
HITCBC 1438   524 break; 1438   524 break;
1439   } 1439   }
1440   // If it is a valid leading surrogate 1440   // If it is a valid leading surrogate
1441   else 1441   else
1442   { 1442   {
HITCBC 1443   693 u1_ = u2; 1443   693 u1_ = u2;
HITCBC 1444   693 goto do_sur1; 1444   693 goto do_sur1;
1445   } 1445   }
1446   } 1446   }
HITCBC 1447   1771 cs += 4; 1447   1771 cs += 4;
1448   // Calculate the Unicode code point from the surrogate pair and 1448   // Calculate the Unicode code point from the surrogate pair and
1449   // append the UTF-8 representation. 1449   // append the UTF-8 representation.
HITCBC 1450   1771 unsigned cp = 1450   1771 unsigned cp =
HITCBC 1451   1771 ((u1 - 0xd800) << 10) + 1451   1771 ((u1 - 0xd800) << 10) +
1452   ((u2 - 0xdc00)) + 1452   ((u2 - 0xdc00)) +
1453   0x10000; 1453   0x10000;
1454   // utf-16 surrogate pair 1454   // utf-16 surrogate pair
HITCBC 1455   1771 temp.append_utf8(cp); 1455   1771 temp.append_utf8(cp);
HITCBC 1456   1771 break; 1456   1771 break;
1457   } 1457   }
1458   // flush 1458   // flush
HITCBC 1459   5991 if(BOOST_JSON_LIKELY(! temp.empty())) 1459   5991 if(BOOST_JSON_LIKELY(! temp.empty()))
1460   { 1460   {
HITCBC 1461   3 BOOST_ASSERT(total <= max_size); 1461   3 BOOST_ASSERT(total <= max_size);
HITCBC 1462   1722 if(BOOST_JSON_UNLIKELY( 1462   1722 if(BOOST_JSON_UNLIKELY(
1463   temp.size() > max_size - total)) 1463   temp.size() > max_size - total))
1464   { 1464   {
1465   BOOST_STATIC_CONSTEXPR source_location loc 1465   BOOST_STATIC_CONSTEXPR source_location loc
1466   = BOOST_CURRENT_LOCATION; 1466   = BOOST_CURRENT_LOCATION;
MISUBC 1467   return fail(cs.begin(), ev_too_large, &loc); 1467   return fail(cs.begin(), ev_too_large, &loc);
1468   } 1468   }
HITCBC 1469   1722 total += temp.size(); 1469   1722 total += temp.size();
1470   { 1470   {
HITCBC 1471   1582 bool r = is_key 1471   1582 bool r = is_key
HITCBC 1472   1722 ? h_.on_key_part(temp.get(), total, ec_) 1472   1722 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1473   1722 : h_.on_string_part(temp.get(), total, ec_); 1473   1722 : h_.on_string_part(temp.get(), total, ec_);
1474   1474  
HITCBC 1475   1582 if(BOOST_JSON_UNLIKELY(!r)) 1475   1582 if(BOOST_JSON_UNLIKELY(!r))
1476   { 1476   {
HITCBC 1477   140 return fail(cs.begin()); 1477   140 return fail(cs.begin());
1478   } 1478   }
1479   } 1479   }
HITCBC 1480   1442 temp.clear(); 1480   1442 temp.clear();
HITCBC 1481   1442 cs.clip(temp.max_size()); 1481   1442 cs.clip(temp.max_size());
1482   } 1482   }
HITCBC 1483   5711 ++cs; 1483   5711 ++cs;
1484   // utf-16 escape 1484   // utf-16 escape
HITCBC 1485   6103 do_str4: 1485   6103 do_str4:
HITCBC 1486   6103 if(BOOST_JSON_UNLIKELY(! cs)) 1486   6103 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1487   392 return maybe_suspend(cs.begin(), state::str4); 1487   392 return maybe_suspend(cs.begin(), state::str4);
HITCBC 1488   5711 digit = detail::hex_digit(*cs); 1488   5711 digit = detail::hex_digit(*cs);
HITCBC 1489   5711 if(BOOST_JSON_UNLIKELY(digit == -1)) 1489   5711 if(BOOST_JSON_UNLIKELY(digit == -1))
1490   { 1490   {
1491   BOOST_STATIC_CONSTEXPR source_location loc 1491   BOOST_STATIC_CONSTEXPR source_location loc
1492   = BOOST_CURRENT_LOCATION; 1492   = BOOST_CURRENT_LOCATION;
HITCBC 1493   50 return fail(cs.begin(), error::expected_hex_digit, &loc); 1493   50 return fail(cs.begin(), error::expected_hex_digit, &loc);
1494   } 1494   }
HITCBC 1495   5661 ++cs; 1495   5661 ++cs;
HITCBC 1496   5661 u1_ = digit << 12; 1496   5661 u1_ = digit << 12;
HITCBC 1497   6051 do_str5: 1497   6051 do_str5:
HITCBC 1498   6051 if(BOOST_JSON_UNLIKELY(! cs)) 1498   6051 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1499   390 return maybe_suspend(cs.begin(), state::str5); 1499   390 return maybe_suspend(cs.begin(), state::str5);
HITCBC 1500   5661 digit = detail::hex_digit(*cs); 1500   5661 digit = detail::hex_digit(*cs);
HITCBC 1501   5661 if(BOOST_JSON_UNLIKELY(digit == -1)) 1501   5661 if(BOOST_JSON_UNLIKELY(digit == -1))
1502   { 1502   {
1503   BOOST_STATIC_CONSTEXPR source_location loc 1503   BOOST_STATIC_CONSTEXPR source_location loc
1504   = BOOST_CURRENT_LOCATION; 1504   = BOOST_CURRENT_LOCATION;
HITCBC 1505   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1505   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1506   } 1506   }
HITCBC 1507   5641 ++cs; 1507   5641 ++cs;
HITCBC 1508   5641 u1_ += digit << 8; 1508   5641 u1_ += digit << 8;
HITCBC 1509   6030 do_str6: 1509   6030 do_str6:
HITCBC 1510   6030 if(BOOST_JSON_UNLIKELY(! cs)) 1510   6030 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1511   389 return maybe_suspend(cs.begin(), state::str6); 1511   389 return maybe_suspend(cs.begin(), state::str6);
HITCBC 1512   5641 digit = detail::hex_digit(*cs); 1512   5641 digit = detail::hex_digit(*cs);
HITCBC 1513   5641 if(BOOST_JSON_UNLIKELY(digit == -1)) 1513   5641 if(BOOST_JSON_UNLIKELY(digit == -1))
1514   { 1514   {
1515   BOOST_STATIC_CONSTEXPR source_location loc 1515   BOOST_STATIC_CONSTEXPR source_location loc
1516   = BOOST_CURRENT_LOCATION; 1516   = BOOST_CURRENT_LOCATION;
HITCBC 1517   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1517   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1518   } 1518   }
HITCBC 1519   5621 ++cs; 1519   5621 ++cs;
HITCBC 1520   5621 u1_ += digit << 4; 1520   5621 u1_ += digit << 4;
HITCBC 1521   6007 do_str7: 1521   6007 do_str7:
HITCBC 1522   6007 if(BOOST_JSON_UNLIKELY(! cs)) 1522   6007 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1523   386 return maybe_suspend(cs.begin(), state::str7); 1523   386 return maybe_suspend(cs.begin(), state::str7);
HITCBC 1524   5621 digit = detail::hex_digit(*cs); 1524   5621 digit = detail::hex_digit(*cs);
HITCBC 1525   5621 if(BOOST_JSON_UNLIKELY(digit == -1)) 1525   5621 if(BOOST_JSON_UNLIKELY(digit == -1))
1526   { 1526   {
1527   BOOST_STATIC_CONSTEXPR source_location loc 1527   BOOST_STATIC_CONSTEXPR source_location loc
1528   = BOOST_CURRENT_LOCATION; 1528   = BOOST_CURRENT_LOCATION;
HITCBC 1529   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1529   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1530   } 1530   }
HITCBC 1531   5586 ++cs; 1531   5586 ++cs;
HITCBC 1532   5586 u1_ += digit; 1532   5586 u1_ += digit;
HITCBC 1533   5586 if(BOOST_JSON_LIKELY( 1533   5586 if(BOOST_JSON_LIKELY(
1534   u1_ < 0xd800 || u1_ > 0xdfff)) 1534   u1_ < 0xd800 || u1_ > 0xdfff))
1535   { 1535   {
HITCBC 1536   1434 BOOST_ASSERT(temp.empty()); 1536   1434 BOOST_ASSERT(temp.empty());
1537   // utf-8 codepoint 1537   // utf-8 codepoint
HITCBC 1538   1434 temp.append_utf8(u1_); 1538   1434 temp.append_utf8(u1_);
HITCBC 1539   1434 break; 1539   1434 break;
1540   } 1540   }
HITCBC 1541   4152 if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff)) 1541   4152 if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff))
1542   { 1542   {
1543   // If it's an illegal leading surrogate and 1543   // If it's an illegal leading surrogate and
1544   // the parser does not allow it, return an error. 1544   // the parser does not allow it, return an error.
HITCBC 1545   1585 if(!allow_bad_utf16) 1545   1585 if(!allow_bad_utf16)
1546   { 1546   {
1547   BOOST_STATIC_CONSTEXPR source_location loc 1547   BOOST_STATIC_CONSTEXPR source_location loc
1548   = BOOST_CURRENT_LOCATION; 1548   = BOOST_CURRENT_LOCATION;
HITCBC 1549   209 return fail(cs.begin(), error::illegal_leading_surrogate, &loc); 1549   209 return fail(cs.begin(), error::illegal_leading_surrogate, &loc);
1550   } 1550   }
1551   // Otherwise, append the Unicode replacement character 1551   // Otherwise, append the Unicode replacement character
1552   else 1552   else
1553   { 1553   {
HITCBC 1554   1376 BOOST_ASSERT(temp.empty()); 1554   1376 BOOST_ASSERT(temp.empty());
HITCBC 1555   1376 temp.append_utf8(urc); 1555   1376 temp.append_utf8(urc);
HITCBC 1556   1376 break; 1556   1376 break;
1557   } 1557   }
1558   } 1558   }
HITCBC 1559   2567 do_sur1: 1559   2567 do_sur1:
HITCBC 1560   3792 if(BOOST_JSON_UNLIKELY(! cs)) 1560   3792 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1561   232 return maybe_suspend(cs.begin(), state::sur1); 1561   232 return maybe_suspend(cs.begin(), state::sur1);
HITCBC 1562   3560 if(BOOST_JSON_UNLIKELY(*cs != '\\')) 1562   3560 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
1563   { 1563   {
1564   // If the next character is not a backslash and 1564   // If the next character is not a backslash and
1565   // the parser does not allow it, return a syntax error. 1565   // the parser does not allow it, return a syntax error.
HITCBC 1566   952 if(!allow_bad_utf16) 1566   952 if(!allow_bad_utf16)
1567   { 1567   {
1568   BOOST_STATIC_CONSTEXPR source_location loc 1568   BOOST_STATIC_CONSTEXPR source_location loc
1569   = BOOST_CURRENT_LOCATION; 1569   = BOOST_CURRENT_LOCATION;
HITCBC 1570   149 return fail(cs.begin(), error::syntax, &loc); 1570   149 return fail(cs.begin(), error::syntax, &loc);
1571   } 1571   }
1572   // Otherwise, append the Unicode replacement character since 1572   // Otherwise, append the Unicode replacement character since
1573   // the first code point is a valid leading surrogate 1573   // the first code point is a valid leading surrogate
1574   else 1574   else
1575   { 1575   {
HITCBC 1576   803 temp.append_utf8(urc); 1576   803 temp.append_utf8(urc);
HITCBC 1577   803 break; 1577   803 break;
1578   } 1578   }
1579   } 1579   }
HITCBC 1580   2608 ++cs; 1580   2608 ++cs;
HITCBC 1581   2796 do_sur2: 1581   2796 do_sur2:
HITCBC 1582   2796 if(BOOST_JSON_UNLIKELY(! cs)) 1582   2796 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1583   188 return maybe_suspend(cs.begin(), state::sur2); 1583   188 return maybe_suspend(cs.begin(), state::sur2);
HITCBC 1584   2608 if(BOOST_JSON_UNLIKELY(*cs != 'u')) 1584   2608 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
1585   { 1585   {
HITCBC 1586   396 if (!allow_bad_utf16) 1586   396 if (!allow_bad_utf16)
1587   { 1587   {
1588   BOOST_STATIC_CONSTEXPR source_location loc 1588   BOOST_STATIC_CONSTEXPR source_location loc
1589   = BOOST_CURRENT_LOCATION; 1589   = BOOST_CURRENT_LOCATION;
HITCBC 1590   65 return fail(cs.begin(), error::syntax, &loc); 1590   65 return fail(cs.begin(), error::syntax, &loc);
1591   } 1591   }
1592   // Otherwise, append the Unicode replacement character since 1592   // Otherwise, append the Unicode replacement character since
1593   // the first code point is a valid leading surrogate 1593   // the first code point is a valid leading surrogate
1594   else 1594   else
1595   { 1595   {
HITCBC 1596   331 temp.append_utf8(urc); 1596   331 temp.append_utf8(urc);
HITCBC 1597   331 goto do_str3; 1597   331 goto do_str3;
1598   } 1598   }
1599   } 1599   }
HITCBC 1600   2212 ++cs; 1600   2212 ++cs;
HITCBC 1601   2376 do_sur3: 1601   2376 do_sur3:
HITCBC 1602   2376 if(BOOST_JSON_UNLIKELY(! cs)) 1602   2376 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1603   164 return maybe_suspend(cs.begin(), state::sur3); 1603   164 return maybe_suspend(cs.begin(), state::sur3);
HITCBC 1604   2212 digit = detail::hex_digit(*cs); 1604   2212 digit = detail::hex_digit(*cs);
HITCBC 1605   2212 if(BOOST_JSON_UNLIKELY(digit == -1)) 1605   2212 if(BOOST_JSON_UNLIKELY(digit == -1))
1606   { 1606   {
1607   BOOST_STATIC_CONSTEXPR source_location loc 1607   BOOST_STATIC_CONSTEXPR source_location loc
1608   = BOOST_CURRENT_LOCATION; 1608   = BOOST_CURRENT_LOCATION;
HITCBC 1609   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1609   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1610   } 1610   }
HITCBC 1611   2177 ++cs; 1611   2177 ++cs;
HITCBC 1612   2177 u2_ = digit << 12; 1612   2177 u2_ = digit << 12;
HITCBC 1613   2339 do_sur4: 1613   2339 do_sur4:
HITCBC 1614   2339 if(BOOST_JSON_UNLIKELY(! cs)) 1614   2339 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1615   162 return maybe_suspend(cs.begin(), state::sur4); 1615   162 return maybe_suspend(cs.begin(), state::sur4);
HITCBC 1616   2177 digit = detail::hex_digit(*cs); 1616   2177 digit = detail::hex_digit(*cs);
HITCBC 1617   2177 if(BOOST_JSON_UNLIKELY(digit == -1)) 1617   2177 if(BOOST_JSON_UNLIKELY(digit == -1))
1618   { 1618   {
1619   BOOST_STATIC_CONSTEXPR source_location loc 1619   BOOST_STATIC_CONSTEXPR source_location loc
1620   = BOOST_CURRENT_LOCATION; 1620   = BOOST_CURRENT_LOCATION;
HITCBC 1621   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1621   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1622   } 1622   }
HITCBC 1623   2142 ++cs; 1623   2142 ++cs;
HITCBC 1624   2142 u2_ += digit << 8; 1624   2142 u2_ += digit << 8;
HITCBC 1625   2302 do_sur5: 1625   2302 do_sur5:
HITCBC 1626   2302 if(BOOST_JSON_UNLIKELY(! cs)) 1626   2302 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1627   160 return maybe_suspend(cs.begin(), state::sur5); 1627   160 return maybe_suspend(cs.begin(), state::sur5);
HITCBC 1628   2142 digit = detail::hex_digit(*cs); 1628   2142 digit = detail::hex_digit(*cs);
HITCBC 1629   2142 if(BOOST_JSON_UNLIKELY(digit == -1)) 1629   2142 if(BOOST_JSON_UNLIKELY(digit == -1))
1630   { 1630   {
1631   BOOST_STATIC_CONSTEXPR source_location loc 1631   BOOST_STATIC_CONSTEXPR source_location loc
1632   = BOOST_CURRENT_LOCATION; 1632   = BOOST_CURRENT_LOCATION;
HITCBC 1633   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1633   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1634   } 1634   }
HITCBC 1635   2122 ++cs; 1635   2122 ++cs;
HITCBC 1636   2122 u2_ += digit << 4; 1636   2122 u2_ += digit << 4;
HITCBC 1637   2280 do_sur6: 1637   2280 do_sur6:
HITCBC 1638   2280 if(BOOST_JSON_UNLIKELY(! cs)) 1638   2280 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1639   158 return maybe_suspend(cs.begin(), state::sur6); 1639   158 return maybe_suspend(cs.begin(), state::sur6);
HITCBC 1640   2122 digit = detail::hex_digit(*cs); 1640   2122 digit = detail::hex_digit(*cs);
HITCBC 1641   2122 if(BOOST_JSON_UNLIKELY(digit == -1)) 1641   2122 if(BOOST_JSON_UNLIKELY(digit == -1))
1642   { 1642   {
1643   BOOST_STATIC_CONSTEXPR source_location loc 1643   BOOST_STATIC_CONSTEXPR source_location loc
1644   = BOOST_CURRENT_LOCATION; 1644   = BOOST_CURRENT_LOCATION;
HITCBC 1645   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1645   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1646   } 1646   }
HITCBC 1647   2102 ++cs; 1647   2102 ++cs;
HITCBC 1648   2102 u2_ += digit; 1648   2102 u2_ += digit;
1649   // Check if the second code point is a valid trailing surrogate. 1649   // Check if the second code point is a valid trailing surrogate.
1650   // Valid trailing surrogates are [DC00, DFFF] 1650   // Valid trailing surrogates are [DC00, DFFF]
HITCBC 1651   2102 if(BOOST_JSON_UNLIKELY( 1651   2102 if(BOOST_JSON_UNLIKELY(
1652   u2_ < 0xdc00 || u2_ > 0xdfff)) 1652   u2_ < 0xdc00 || u2_ > 0xdfff))
1653   { 1653   {
1654   // If not valid and the parser does not allow it, return an error. 1654   // If not valid and the parser does not allow it, return an error.
HITCBC 1655   580 if(!allow_bad_utf16) 1655   580 if(!allow_bad_utf16)
1656   { 1656   {
1657   BOOST_STATIC_CONSTEXPR source_location loc 1657   BOOST_STATIC_CONSTEXPR source_location loc
1658   = BOOST_CURRENT_LOCATION; 1658   = BOOST_CURRENT_LOCATION;
HITCBC 1659   60 return fail(cs.begin(), error::illegal_trailing_surrogate, &loc); 1659   60 return fail(cs.begin(), error::illegal_trailing_surrogate, &loc);
1660   } 1660   }
1661   // Append the replacement character for the 1661   // Append the replacement character for the
1662   // first leading surrogate. 1662   // first leading surrogate.
HITCBC 1663   520 temp.append_utf8(urc); 1663   520 temp.append_utf8(urc);
1664   // Check if the second code point is a 1664   // Check if the second code point is a
1665   // valid unicode scalar value (invalid leading 1665   // valid unicode scalar value (invalid leading
1666   // or trailing surrogate) 1666   // or trailing surrogate)
HITCBC 1667   520 if (u2_ < 0xd800 || u2_ > 0xdbff) 1667   520 if (u2_ < 0xd800 || u2_ > 0xdbff)
1668   { 1668   {
HITCBC 1669   220 temp.append_utf8(u2_); 1669   220 temp.append_utf8(u2_);
HITCBC 1670   220 break; 1670   220 break;
1671   } 1671   }
1672   // If it is a valid leading surrogate 1672   // If it is a valid leading surrogate
1673   else 1673   else
1674   { 1674   {
HITCBC 1675   300 u1_ = u2_; 1675   300 u1_ = u2_;
HITCBC 1676   300 goto do_sur1; 1676   300 goto do_sur1;
1677   } 1677   }
1678   } 1678   }
1679   // Calculate the Unicode code point from the surrogate pair and 1679   // Calculate the Unicode code point from the surrogate pair and
1680   // append the UTF-8 representation. 1680   // append the UTF-8 representation.
HITCBC 1681   1522 unsigned cp = 1681   1522 unsigned cp =
HITCBC 1682   1522 ((u1_ - 0xd800) << 10) + 1682   1522 ((u1_ - 0xd800) << 10) +
HITCBC 1683   1522 ((u2_ - 0xdc00)) + 1683   1522 ((u2_ - 0xdc00)) +
1684   0x10000; 1684   0x10000;
1685   // utf-16 surrogate pair 1685   // utf-16 surrogate pair
HITCBC 1686   1522 temp.append_utf8(cp); 1686   1522 temp.append_utf8(cp);
1687   } 1687   }
1688   1688  
1689   // flush 1689   // flush
HITCBC 1690   12650 if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\') 1690   12650 if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\')
HITCBC 1691   8869 break; 1691   8869 break;
1692   } 1692   }
1693   1693  
HITCBC 1694   8869 if(BOOST_JSON_LIKELY( temp.size() )) 1694   8869 if(BOOST_JSON_LIKELY( temp.size() ))
1695   { 1695   {
HITCBC 1696   433 BOOST_ASSERT(total <= max_size); 1696   433 BOOST_ASSERT(total <= max_size);
HITCBC 1697   8869 if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total )) 1697   8869 if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total ))
1698   { 1698   {
1699   BOOST_STATIC_CONSTEXPR source_location loc 1699   BOOST_STATIC_CONSTEXPR source_location loc
1700   = BOOST_CURRENT_LOCATION; 1700   = BOOST_CURRENT_LOCATION;
MISUBC 1701   return fail(cs.begin(), ev_too_large, &loc); 1701   return fail(cs.begin(), ev_too_large, &loc);
1702   } 1702   }
1703   1703  
HITCBC 1704   8869 total += temp.size(); 1704   8869 total += temp.size();
HITCBC 1705   8056 bool const r = is_key 1705   8056 bool const r = is_key
HITCBC 1706   8869 ? h_.on_key_part(temp.get(), total, ec_) 1706   8869 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1707   8152 : h_.on_string_part(temp.get(), total, ec_); 1707   8152 : h_.on_string_part(temp.get(), total, ec_);
HITCBC 1708   8056 if(BOOST_JSON_UNLIKELY( !r )) 1708   8056 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1709   813 return fail( cs.begin() ); 1709   813 return fail( cs.begin() );
1710   } 1710   }
1711   1711  
HITCBC 1712   7243 return cs.begin(); 1712   7243 return cs.begin();
1713   } 1713   }
1714   1714  
1715   //---------------------------------------------------------- 1715   //----------------------------------------------------------
1716   1716  
1717   template<class Handler> 1717   template<class Handler>
1718   template< 1718   template<
1719   bool StackEmpty_, 1719   bool StackEmpty_,
1720   bool AllowComments_/*, 1720   bool AllowComments_/*,
1721   bool AllowTrailing_, 1721   bool AllowTrailing_,
1722   bool AllowBadUTF8_*/> 1722   bool AllowBadUTF8_*/>
1723   const char* 1723   const char*
HITCBC 1724   109189 basic_parser<Handler>:: 1724   109189 basic_parser<Handler>::
1725   parse_object(const char* p, 1725   parse_object(const char* p,
1726   std::integral_constant<bool, StackEmpty_> stack_empty, 1726   std::integral_constant<bool, StackEmpty_> stack_empty,
1727   std::integral_constant<bool, AllowComments_> allow_comments, 1727   std::integral_constant<bool, AllowComments_> allow_comments,
1728   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 1728   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
1729   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 1729   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
1730   bool allow_bad_utf16) 1730   bool allow_bad_utf16)
1731   { 1731   {
HITCBC 1732   109189 detail::const_stream_wrapper cs(p, end_); 1732   109189 detail::const_stream_wrapper cs(p, end_);
1733   std::size_t size; 1733   std::size_t size;
HITCBC 1734   109189 if(! stack_empty && ! st_.empty()) 1734   109189 if(! stack_empty && ! st_.empty())
1735   { 1735   {
1736   // resume 1736   // resume
1737   state st; 1737   state st;
HITCBC 1738   35058 st_.pop(st); 1738   35058 st_.pop(st);
HITCBC 1739   35058 st_.pop(size); 1739   35058 st_.pop(size);
HITCBC 1740   35058 switch(st) 1740   35058 switch(st)
1741   { 1741   {
MISUBC 1742   default: BOOST_JSON_UNREACHABLE(); 1742   default: BOOST_JSON_UNREACHABLE();
HITCBC 1743   1595 case state::obj1: goto do_obj1; 1743   1595 case state::obj1: goto do_obj1;
HITCBC 1744   235 case state::obj2: goto do_obj2; 1744   235 case state::obj2: goto do_obj2;
HITCBC 1745   12647 case state::obj3: goto do_obj3; 1745   12647 case state::obj3: goto do_obj3;
HITCBC 1746   1690 case state::obj4: goto do_obj4; 1746   1690 case state::obj4: goto do_obj4;
HITCBC 1747   251 case state::obj5: goto do_obj5; 1747   251 case state::obj5: goto do_obj5;
HITCBC 1748   1591 case state::obj6: goto do_obj6; 1748   1591 case state::obj6: goto do_obj6;
HITCBC 1749   15448 case state::obj7: goto do_obj7; 1749   15448 case state::obj7: goto do_obj7;
HITCBC 1750   426 case state::obj8: goto do_obj8; 1750   426 case state::obj8: goto do_obj8;
HITCBC 1751   660 case state::obj9: goto do_obj9; 1751   660 case state::obj9: goto do_obj9;
HITCBC 1752   181 case state::obj10: goto do_obj10; 1752   181 case state::obj10: goto do_obj10;
HITCBC 1753   334 case state::obj11: goto do_obj11; 1753   334 case state::obj11: goto do_obj11;
1754   } 1754   }
1755   } 1755   }
HITCBC 1756   74131 BOOST_ASSERT(*cs == '{'); 1756   74131 BOOST_ASSERT(*cs == '{');
HITCBC 1757   74131 size = 0; 1757   74131 size = 0;
HITCBC 1758   74131 if(BOOST_JSON_UNLIKELY(! depth_)) 1758   74131 if(BOOST_JSON_UNLIKELY(! depth_))
1759   { 1759   {
1760   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1760   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1761   3 return fail(cs.begin(), error::too_deep, &loc); 1761   3 return fail(cs.begin(), error::too_deep, &loc);
1762   } 1762   }
HITCBC 1763   74128 --depth_; 1763   74128 --depth_;
HITCBC 1764   74128 if(BOOST_JSON_UNLIKELY( 1764   74128 if(BOOST_JSON_UNLIKELY(
1765   ! h_.on_object_begin(ec_))) 1765   ! h_.on_object_begin(ec_)))
HITCBC 1766   2040 return fail(cs.begin()); 1766   2040 return fail(cs.begin());
HITCBC 1767   70050 ++cs; 1767   70050 ++cs;
1768   // object: 1768   // object:
1769   // '{' *ws '}' 1769   // '{' *ws '}'
1770   // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}' 1770   // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}'
HITCBC 1771   73616 do_obj1: 1771   73616 do_obj1:
HITCBC 1772   73616 cs = detail::count_whitespace(cs.begin(), cs.end()); 1772   73616 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1773   73616 if(BOOST_JSON_UNLIKELY(! cs)) 1773   73616 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1774   1629 return maybe_suspend(cs.begin(), state::obj1, size); 1774   1629 return maybe_suspend(cs.begin(), state::obj1, size);
HITCBC 1775   71987 if(BOOST_JSON_LIKELY(*cs != '}')) 1775   71987 if(BOOST_JSON_LIKELY(*cs != '}'))
1776   { 1776   {
HITCBC 1777   69088 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) 1777   69088 if(BOOST_JSON_UNLIKELY(*cs != '\x22'))
1778   { 1778   {
HITCBC 1779   2411 if(allow_comments && *cs == '/') 1779   2411 if(allow_comments && *cs == '/')
1780   { 1780   {
HITCBC 1781   2139 do_obj2: 1781   2139 do_obj2:
HITCBC 1782   2374 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1782   2374 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1783   2290 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1783   2290 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1784   319 return suspend_or_fail(state::obj2, size); 1784   319 return suspend_or_fail(state::obj2, size);
HITCBC 1785   1971 goto do_obj1; 1785   1971 goto do_obj1;
1786   } 1786   }
1787   BOOST_STATIC_CONSTEXPR source_location loc 1787   BOOST_STATIC_CONSTEXPR source_location loc
1788   = BOOST_CURRENT_LOCATION; 1788   = BOOST_CURRENT_LOCATION;
HITCBC 1789   272 return fail(cs.begin(), error::syntax, &loc); 1789   272 return fail(cs.begin(), error::syntax, &loc);
1790   } 1790   }
HITCBC 1791   66677 loop: 1791   66677 loop:
HITCBC 1792   80829 if(BOOST_JSON_UNLIKELY(++size > 1792   80829 if(BOOST_JSON_UNLIKELY(++size >
1793   Handler::max_object_size)) 1793   Handler::max_object_size))
1794   { 1794   {
1795   BOOST_STATIC_CONSTEXPR source_location loc 1795   BOOST_STATIC_CONSTEXPR source_location loc
1796   = BOOST_CURRENT_LOCATION; 1796   = BOOST_CURRENT_LOCATION;
HITCBC 1797   1 return fail(cs.begin(), error::object_too_large, &loc); 1797   1 return fail(cs.begin(), error::object_too_large, &loc);
1798   } 1798   }
HITCBC 1799   80828 do_obj3: 1799   80828 do_obj3:
HITCBC 1800   93475 cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16); 1800   93475 cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16);
HITCBC 1801   90519 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1801   90519 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1802   15592 return suspend_or_fail(state::obj3, size); 1802   15592 return suspend_or_fail(state::obj3, size);
HITCBC 1803   74927 do_obj4: 1803   74927 do_obj4:
HITCBC 1804   79088 cs = detail::count_whitespace(cs.begin(), cs.end()); 1804   79088 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1805   79088 if(BOOST_JSON_UNLIKELY(! cs)) 1805   79088 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1806   1705 return maybe_suspend(cs.begin(), state::obj4, size); 1806   1705 return maybe_suspend(cs.begin(), state::obj4, size);
HITCBC 1807   77383 if(BOOST_JSON_UNLIKELY(*cs != ':')) 1807   77383 if(BOOST_JSON_UNLIKELY(*cs != ':'))
1808   { 1808   {
HITCBC 1809   2925 if(allow_comments && *cs == '/') 1809   2925 if(allow_comments && *cs == '/')
1810   { 1810   {
HITCBC 1811   2779 do_obj5: 1811   2779 do_obj5:
HITCBC 1812   3030 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1812   3030 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1813   2876 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1813   2876 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1814   405 return suspend_or_fail(state::obj5, size); 1814   405 return suspend_or_fail(state::obj5, size);
HITCBC 1815   2471 goto do_obj4; 1815   2471 goto do_obj4;
1816   } 1816   }
1817   BOOST_STATIC_CONSTEXPR source_location loc 1817   BOOST_STATIC_CONSTEXPR source_location loc
1818   = BOOST_CURRENT_LOCATION; 1818   = BOOST_CURRENT_LOCATION;
HITCBC 1819   146 return fail(cs.begin(), error::syntax, &loc); 1819   146 return fail(cs.begin(), error::syntax, &loc);
1820   } 1820   }
HITCBC 1821   74458 ++cs; 1821   74458 ++cs;
HITCBC 1822   76049 do_obj6: 1822   76049 do_obj6:
HITCBC 1823   76049 cs = detail::count_whitespace(cs.begin(), cs.end()); 1823   76049 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1824   76049 if(BOOST_JSON_UNLIKELY(! cs)) 1824   76049 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1825   1622 return maybe_suspend(cs.begin(), state::obj6, size); 1825   1622 return maybe_suspend(cs.begin(), state::obj6, size);
HITCBC 1826   74427 do_obj7: 1826   74427 do_obj7:
HITCBC 1827   89875 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 1827   89875 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 1828   82526 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1828   82526 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1829   23593 return suspend_or_fail(state::obj7, size); 1829   23593 return suspend_or_fail(state::obj7, size);
HITCBC 1830   58933 do_obj8: 1830   58933 do_obj8:
HITCBC 1831   61195 cs = detail::count_whitespace(cs.begin(), cs.end()); 1831   61195 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1832   61195 if(BOOST_JSON_UNLIKELY(! cs)) 1832   61195 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1833   441 return maybe_suspend(cs.begin(), state::obj8, size); 1833   441 return maybe_suspend(cs.begin(), state::obj8, size);
HITCBC 1834   60754 if(BOOST_JSON_LIKELY(*cs == ',')) 1834   60754 if(BOOST_JSON_LIKELY(*cs == ','))
1835   { 1835   {
HITCBC 1836   17792 ++cs; 1836   17792 ++cs;
HITCBC 1837   19707 do_obj9: 1837   19707 do_obj9:
HITCBC 1838   19707 cs = detail::count_whitespace(cs.begin(), cs.end()); 1838   19707 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1839   19707 if(BOOST_JSON_UNLIKELY(! cs)) 1839   19707 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1840   690 return maybe_suspend(cs.begin(), state::obj9, size); 1840   690 return maybe_suspend(cs.begin(), state::obj9, size);
1841   1841  
1842   // loop for next element 1842   // loop for next element
HITCBC 1843   19017 if(BOOST_JSON_LIKELY(*cs == '\x22')) 1843   19017 if(BOOST_JSON_LIKELY(*cs == '\x22'))
HITCBC 1844   14152 goto loop; 1844   14152 goto loop;
HITCBC 1845   4865 if(! allow_trailing || *cs != '}') 1845   4865 if(! allow_trailing || *cs != '}')
1846   { 1846   {
HITCBC 1847   1644 if(allow_comments && *cs == '/') 1847   1644 if(allow_comments && *cs == '/')
1848   { 1848   {
HITCBC 1849   1433 do_obj10: 1849   1433 do_obj10:
HITCBC 1850   1614 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1850   1614 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1851   1525 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1851   1525 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1852   270 return suspend_or_fail(state::obj10, size); 1852   270 return suspend_or_fail(state::obj10, size);
HITCBC 1853   1255 goto do_obj9; 1853   1255 goto do_obj9;
1854   } 1854   }
1855   BOOST_STATIC_CONSTEXPR source_location loc 1855   BOOST_STATIC_CONSTEXPR source_location loc
1856   = BOOST_CURRENT_LOCATION; 1856   = BOOST_CURRENT_LOCATION;
HITCBC 1857   211 return fail(cs.begin(), error::syntax, &loc); 1857   211 return fail(cs.begin(), error::syntax, &loc);
1858   } 1858   }
1859   } 1859   }
HITCBC 1860   42962 else if(BOOST_JSON_UNLIKELY(*cs != '}')) 1860   42962 else if(BOOST_JSON_UNLIKELY(*cs != '}'))
1861   { 1861   {
HITCBC 1862   2325 if(allow_comments && *cs == '/') 1862   2325 if(allow_comments && *cs == '/')
1863   { 1863   {
HITCBC 1864   2172 do_obj11: 1864   2172 do_obj11:
HITCBC 1865   2506 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1865   2506 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1866   2338 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1866   2338 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1867   502 return suspend_or_fail(state::obj11, size); 1867   502 return suspend_or_fail(state::obj11, size);
HITCBC 1868   1836 goto do_obj8; 1868   1836 goto do_obj8;
1869   } 1869   }
1870   BOOST_STATIC_CONSTEXPR source_location loc 1870   BOOST_STATIC_CONSTEXPR source_location loc
1871   = BOOST_CURRENT_LOCATION; 1871   = BOOST_CURRENT_LOCATION;
HITCBC 1872   153 return fail(cs.begin(), error::syntax, &loc); 1872   153 return fail(cs.begin(), error::syntax, &loc);
1873   } 1873   }
1874   // got closing brace, fall through 1874   // got closing brace, fall through
1875   } 1875   }
HITCBC 1876   46757 if(BOOST_JSON_UNLIKELY( 1876   46757 if(BOOST_JSON_UNLIKELY(
1877   ! h_.on_object_end(size, ec_))) 1877   ! h_.on_object_end(size, ec_)))
HITCBC 1878   1502 return fail(cs.begin()); 1878   1502 return fail(cs.begin());
HITCBC 1879   43714 ++depth_; 1879   43714 ++depth_;
HITCBC 1880   43714 ++cs; 1880   43714 ++cs;
HITCBC 1881   43714 return cs.begin(); 1881   43714 return cs.begin();
1882   } 1882   }
1883   1883  
1884   //---------------------------------------------------------- 1884   //----------------------------------------------------------
1885   1885  
1886   template<class Handler> 1886   template<class Handler>
1887   template< 1887   template<
1888   bool StackEmpty_, 1888   bool StackEmpty_,
1889   bool AllowComments_/*, 1889   bool AllowComments_/*,
1890   bool AllowTrailing_, 1890   bool AllowTrailing_,
1891   bool AllowBadUTF8_*/> 1891   bool AllowBadUTF8_*/>
1892   const char* 1892   const char*
HITCBC 1893   26348 basic_parser<Handler>:: 1893   26348 basic_parser<Handler>::
1894   parse_array(const char* p, 1894   parse_array(const char* p,
1895   std::integral_constant<bool, StackEmpty_> stack_empty, 1895   std::integral_constant<bool, StackEmpty_> stack_empty,
1896   std::integral_constant<bool, AllowComments_> allow_comments, 1896   std::integral_constant<bool, AllowComments_> allow_comments,
1897   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 1897   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
1898   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 1898   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
1899   bool allow_bad_utf16) 1899   bool allow_bad_utf16)
1900   { 1900   {
HITCBC 1901   26348 detail::const_stream_wrapper cs(p, end_); 1901   26348 detail::const_stream_wrapper cs(p, end_);
1902   std::size_t size; 1902   std::size_t size;
HITCBC 1903   26348 if(! stack_empty && ! st_.empty()) 1903   26348 if(! stack_empty && ! st_.empty())
1904   { 1904   {
1905   // resume 1905   // resume
1906   state st; 1906   state st;
HITCBC 1907   5730 st_.pop(st); 1907   5730 st_.pop(st);
HITCBC 1908   5730 st_.pop(size); 1908   5730 st_.pop(size);
HITCBC 1909   5730 switch(st) 1909   5730 switch(st)
1910   { 1910   {
MISUBC 1911   default: BOOST_JSON_UNREACHABLE(); 1911   default: BOOST_JSON_UNREACHABLE();
HITCBC 1912   1052 case state::arr1: goto do_arr1; 1912   1052 case state::arr1: goto do_arr1;
HITCBC 1913   384 case state::arr2: goto do_arr2; 1913   384 case state::arr2: goto do_arr2;
HITCBC 1914   2938 case state::arr3: goto do_arr3; 1914   2938 case state::arr3: goto do_arr3;
HITCBC 1915   391 case state::arr4: goto do_arr4; 1915   391 case state::arr4: goto do_arr4;
HITCBC 1916   671 case state::arr5: goto do_arr5; 1916   671 case state::arr5: goto do_arr5;
HITCBC 1917   294 case state::arr6: goto do_arr6; 1917   294 case state::arr6: goto do_arr6;
1918   } 1918   }
1919   } 1919   }
HITCBC 1920   20618 BOOST_ASSERT(*cs == '['); 1920   20618 BOOST_ASSERT(*cs == '[');
HITCBC 1921   20618 size = 0; 1921   20618 size = 0;
HITCBC 1922   20618 if(BOOST_JSON_UNLIKELY(! depth_)) 1922   20618 if(BOOST_JSON_UNLIKELY(! depth_))
1923   { 1923   {
1924   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1924   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1925   34 return fail(cs.begin(), error::too_deep, &loc); 1925   34 return fail(cs.begin(), error::too_deep, &loc);
1926   } 1926   }
HITCBC 1927   20584 --depth_; 1927   20584 --depth_;
HITCBC 1928   20584 if(BOOST_JSON_UNLIKELY( 1928   20584 if(BOOST_JSON_UNLIKELY(
1929   ! h_.on_array_begin(ec_))) 1929   ! h_.on_array_begin(ec_)))
HITCBC 1930   812 return fail(cs.begin()); 1930   812 return fail(cs.begin());
HITCBC 1931   18966 ++cs; 1931   18966 ++cs;
1932   // array: 1932   // array:
1933   // '[' *ws ']' 1933   // '[' *ws ']'
1934   // '[' *ws value *ws *[ ',' *ws value *ws ] ']' 1934   // '[' *ws value *ws *[ ',' *ws value *ws ] ']'
HITCBC 1935   21551 do_arr1: 1935   21551 do_arr1:
HITCBC 1936   21551 cs = detail::count_whitespace(cs.begin(), cs.end()); 1936   21551 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1937   21551 if(BOOST_JSON_UNLIKELY(! cs)) 1937   21551 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1938   1073 return maybe_suspend(cs.begin(), state::arr1, size); 1938   1073 return maybe_suspend(cs.begin(), state::arr1, size);
HITCBC 1939   20478 if(BOOST_JSON_LIKELY(*cs != ']')) 1939   20478 if(BOOST_JSON_LIKELY(*cs != ']'))
1940   { 1940   {
HITCBC 1941   18730 loop: 1941   18730 loop:
HITCBC 1942   26193 if(allow_comments && *cs == '/') 1942   26193 if(allow_comments && *cs == '/')
1943   { 1943   {
HITCBC 1944   1789 do_arr2: 1944   1789 do_arr2:
HITCBC 1945   2173 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1945   2173 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1946   2045 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1946   2045 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1947   512 return suspend_or_fail(state::arr2, size); 1947   512 return suspend_or_fail(state::arr2, size);
HITCBC 1948   1533 goto do_arr1; 1948   1533 goto do_arr1;
1949   } 1949   }
HITCBC 1950   24404 if(BOOST_JSON_UNLIKELY(++size > 1950   24404 if(BOOST_JSON_UNLIKELY(++size >
1951   Handler::max_array_size)) 1951   Handler::max_array_size))
1952   { 1952   {
1953   BOOST_STATIC_CONSTEXPR source_location loc 1953   BOOST_STATIC_CONSTEXPR source_location loc
1954   = BOOST_CURRENT_LOCATION; 1954   = BOOST_CURRENT_LOCATION;
HITCBC 1955   1 return fail(cs.begin(), error::array_too_large, &loc); 1955   1 return fail(cs.begin(), error::array_too_large, &loc);
1956   } 1956   }
HITCBC 1957   24403 do_arr3: 1957   24403 do_arr3:
1958   // array is not empty, value required 1958   // array is not empty, value required
HITCBC 1959   27341 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 1959   27341 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 1960   24710 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1960   24710 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1961   9052 return suspend_or_fail(state::arr3, size); 1961   9052 return suspend_or_fail(state::arr3, size);
HITCBC 1962   15658 do_arr4: 1962   15658 do_arr4:
HITCBC 1963   17279 cs = detail::count_whitespace(cs.begin(), cs.end()); 1963   17279 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1964   17279 if(BOOST_JSON_UNLIKELY(! cs)) 1964   17279 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1965   500 return maybe_suspend(cs.begin(), state::arr4, size); 1965   500 return maybe_suspend(cs.begin(), state::arr4, size);
HITCBC 1966   16779 if(BOOST_JSON_LIKELY(*cs == ',')) 1966   16779 if(BOOST_JSON_LIKELY(*cs == ','))
1967   { 1967   {
HITCBC 1968   9176 ++cs; 1968   9176 ++cs;
HITCBC 1969   9847 do_arr5: 1969   9847 do_arr5:
HITCBC 1970   9847 cs = detail::count_whitespace(cs.begin(), cs.end()); 1970   9847 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1971   9847 if(BOOST_JSON_UNLIKELY(! cs)) 1971   9847 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1972   701 return maybe_suspend(cs.begin(), state::arr5, size); 1972   701 return maybe_suspend(cs.begin(), state::arr5, size);
1973   // loop for next element 1973   // loop for next element
HITCBC 1974   9146 if(! allow_trailing || *cs != ']') 1974   9146 if(! allow_trailing || *cs != ']')
HITCBC 1975   7463 goto loop; 1975   7463 goto loop;
1976   } 1976   }
HITCBC 1977   7603 else if(BOOST_JSON_UNLIKELY(*cs != ']')) 1977   7603 else if(BOOST_JSON_UNLIKELY(*cs != ']'))
1978   { 1978   {
HITCBC 1979   1969 if(allow_comments && *cs == '/') 1979   1969 if(allow_comments && *cs == '/')
1980   { 1980   {
HITCBC 1981   1541 do_arr6: 1981   1541 do_arr6:
HITCBC 1982   1835 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1982   1835 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1983   1688 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1983   1688 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1984   458 return suspend_or_fail(state::arr6, size); 1984   458 return suspend_or_fail(state::arr6, size);
HITCBC 1985   1230 goto do_arr4; 1985   1230 goto do_arr4;
1986   } 1986   }
1987   BOOST_STATIC_CONSTEXPR source_location loc 1987   BOOST_STATIC_CONSTEXPR source_location loc
1988   = BOOST_CURRENT_LOCATION; 1988   = BOOST_CURRENT_LOCATION;
HITCBC 1989   428 return fail(cs.begin(), error::syntax, &loc); 1989   428 return fail(cs.begin(), error::syntax, &loc);
1990   } 1990   }
1991   // got closing bracket; fall through 1991   // got closing bracket; fall through
1992   } 1992   }
HITCBC 1993   9065 if(BOOST_JSON_UNLIKELY( 1993   9065 if(BOOST_JSON_UNLIKELY(
1994   ! h_.on_array_end(size, ec_))) 1994   ! h_.on_array_end(size, ec_)))
HITCBC 1995   547 return fail(cs.begin()); 1995   547 return fail(cs.begin());
HITCBC 1996   7939 ++depth_; 1996   7939 ++depth_;
HITCBC 1997   7939 ++cs; 1997   7939 ++cs;
HITCBC 1998   7939 return cs.begin(); 1998   7939 return cs.begin();
1999   } 1999   }
2000   2000  
2001   //---------------------------------------------------------- 2001   //----------------------------------------------------------
2002   2002  
2003   template<class Handler> 2003   template<class Handler>
2004   template<bool StackEmpty_, char First_, number_precision Numbers_> 2004   template<bool StackEmpty_, char First_, number_precision Numbers_>
2005   const char* 2005   const char*
HITCBC 2006   2126888 basic_parser<Handler>:: 2006   2126888 basic_parser<Handler>::
2007   parse_number(const char* p, 2007   parse_number(const char* p,
2008   std::integral_constant<bool, StackEmpty_> stack_empty, 2008   std::integral_constant<bool, StackEmpty_> stack_empty,
2009   std::integral_constant<char, First_> first, 2009   std::integral_constant<char, First_> first,
2010   std::integral_constant<number_precision, Numbers_> mode) 2010   std::integral_constant<number_precision, Numbers_> mode)
2011   { 2011   {
HITCBC 2012   2126888 constexpr bool precise_parsing = mode == number_precision::precise; 2012   2126888 constexpr bool precise_parsing = mode == number_precision::precise;
HITCBC 2013   2126888 constexpr bool no_parsing = mode == number_precision::none; 2013   2126888 constexpr bool no_parsing = mode == number_precision::none;
2014   2014  
2015   // only one of these will be true if we are not resuming 2015   // only one of these will be true if we are not resuming
2016   // if negative then !zero_first && !nonzero_first 2016   // if negative then !zero_first && !nonzero_first
2017   // if zero_first then !nonzero_first && !negative 2017   // if zero_first then !nonzero_first && !negative
2018   // if nonzero_first then !zero_first && !negative 2018   // if nonzero_first then !zero_first && !negative
HITCBC 2019   2126888 bool const negative = first == '-'; 2019   2126888 bool const negative = first == '-';
HITCBC 2020   2126888 bool const zero_first = first == '0'; 2020   2126888 bool const zero_first = first == '0';
HITCBC 2021   2126888 bool const nonzero_first = first == '+'; 2021   2126888 bool const nonzero_first = first == '+';
HITCBC 2022   2126888 detail::const_stream_wrapper cs(p, end_); 2022   2126888 detail::const_stream_wrapper cs(p, end_);
2023   number num; 2023   number num;
HITCBC 2024   2126888 const char* begin = cs.begin(); 2024   2126888 const char* begin = cs.begin();
HITCBC 2025   2126888 if(stack_empty || st_.empty()) 2025   2126888 if(stack_empty || st_.empty())
2026   { 2026   {
HITCBC 2027   2089697 num.bias = 0; 2027   2089697 num.bias = 0;
HITCBC 2028   2089697 num.exp = 0; 2028   2089697 num.exp = 0;
HITCBC 2029   2089697 num.frac = false; 2029   2089697 num.frac = false;
HITCBC 2030   2089697 num_buf_.clear(); 2030   2089697 num_buf_.clear();
2031   2031  
2032   //---------------------------------- 2032   //----------------------------------
2033   // 2033   //
2034   // '-' 2034   // '-'
2035   // leading minus sign 2035   // leading minus sign
2036   // 2036   //
HITCBC 2037   2089697 BOOST_ASSERT(cs); 2037   2089697 BOOST_ASSERT(cs);
2038   if(negative) 2038   if(negative)
HITCBC 2039   25178 ++cs; 2039   25178 ++cs;
2040   2040  
HITCBC 2041   2089697 num.neg = negative; 2041   2089697 num.neg = negative;
HITCBC 2042   2089697 num.frac = false; 2042   2089697 num.frac = false;
HITCBC 2043   2089697 num.exp = 0; 2043   2089697 num.exp = 0;
HITCBC 2044   2089697 num.bias = 0; 2044   2089697 num.bias = 0;
2045   2045  
2046   // fast path 2046   // fast path
HITCBC 2047   2089697 if( cs.remain() >= 16 + 1 + 16 ) // digits . digits 2047   2089697 if( cs.remain() >= 16 + 1 + 16 ) // digits . digits
2048   { 2048   {
2049   int n1; 2049   int n1;
2050   2050  
HITCBC 2051   9989 if( nonzero_first || 2051   9989 if( nonzero_first ||
HITCBC 2052   9989 (negative && *cs != '0') ) 2052   9989 (negative && *cs != '0') )
2053   { 2053   {
HITCBC 2054   2007318 n1 = detail::count_digits( cs.begin() ); 2054   2007318 n1 = detail::count_digits( cs.begin() );
HITCBC 2055   2007318 BOOST_ASSERT(n1 >= 0 && n1 <= 16); 2055   2007318 BOOST_ASSERT(n1 >= 0 && n1 <= 16);
2056   2056  
HITCBC 2057   1837 if( negative && n1 == 0 && opt_.allow_infinity_and_nan ) 2057   1837 if( negative && n1 == 0 && opt_.allow_infinity_and_nan )
2058   { 2058   {
HITCBC 2059   9 return parse_literal( 2059   9 return parse_literal(
2060   p - 1, 2060   p - 1,
HITCBC 2061   8 detail::literals_c<detail::literals::neg_infinity>()); 2061   8 detail::literals_c<detail::literals::neg_infinity>());
2062   } 2062   }
2063   2063  
HITCBC 2064   1828 if( ! nonzero_first && n1 == 0 ) 2064   1828 if( ! nonzero_first && n1 == 0 )
2065   { 2065   {
2066   // digit required 2066   // digit required
2067   BOOST_STATIC_CONSTEXPR source_location loc 2067   BOOST_STATIC_CONSTEXPR source_location loc
2068   = BOOST_CURRENT_LOCATION; 2068   = BOOST_CURRENT_LOCATION;
HITCBC 2069   2 return fail(cs.begin(), error::syntax, &loc); 2069   2 return fail(cs.begin(), error::syntax, &loc);
2070   } 2070   }
2071   2071  
2072   BOOST_IF_CONSTEXPR( !no_parsing ) 2072   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2073   2006459 num.mant = detail::parse_unsigned( 0, cs.begin(), n1 ); 2073   2006459 num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );
2074   else 2074   else
HITCBC 2075   848 num.mant = 0; 2075   848 num.mant = 0;
2076   2076  
HITCBC 2077   2007307 cs += n1; 2077   2007307 cs += n1;
2078   2078  
2079   // integer or floating-point with 2079   // integer or floating-point with
2080   // >= 16 leading digits 2080   // >= 16 leading digits
HITCBC 2081   2007307 if( n1 == 16 ) 2081   2007307 if( n1 == 16 )
2082   { 2082   {
HITCBC 2083   2001424 goto do_num2; 2083   2001424 goto do_num2;
2084   } 2084   }
2085   } 2085   }
2086   else 2086   else
2087   { 2087   {
2088   // 0. floating-point or 0e integer 2088   // 0. floating-point or 0e integer
HITCBC 2089   21187 num.mant = 0; 2089   21187 num.mant = 0;
HITCBC 2090   21187 n1 = 0; 2090   21187 n1 = 0;
HITCBC 2091   21187 ++cs; 2091   21187 ++cs;
2092   } 2092   }
2093   2093  
2094   { 2094   {
HITCBC 2095   27070 const char c = *cs; 2095   27070 const char c = *cs;
HITCBC 2096   27070 if(c != '.') 2096   27070 if(c != '.')
2097   { 2097   {
HITCBC 2098   9871 if((c | 32) == 'e') 2098   9871 if((c | 32) == 'e')
2099   { 2099   {
HITCBC 2100   6576 ++cs; 2100   6576 ++cs;
HITCBC 2101   6576 goto do_exp1; 2101   6576 goto do_exp1;
2102   } 2102   }
2103   BOOST_IF_CONSTEXPR( negative && !no_parsing ) 2103   BOOST_IF_CONSTEXPR( negative && !no_parsing )
HITCBC 2104   20 num.mant = ~num.mant + 1; 2104   20 num.mant = ~num.mant + 1;
HITCBC 2105   3295 goto finish_signed; 2105   3295 goto finish_signed;
2106   } 2106   }
2107   } 2107   }
2108   2108  
2109   // floating-point number 2109   // floating-point number
2110   2110  
HITCBC 2111   17199 ++cs; 2111   17199 ++cs;
2112   2112  
HITCBC 2113   17199 int n2 = detail::count_digits( cs.begin() ); 2113   17199 int n2 = detail::count_digits( cs.begin() );
HITCBC 2114   17199 BOOST_ASSERT(n2 >= 0 && n2 <= 16); 2114   17199 BOOST_ASSERT(n2 >= 0 && n2 <= 16);
2115   2115  
HITCBC 2116   17199 if( n2 == 0 ) 2116   17199 if( n2 == 0 )
2117   { 2117   {
2118   // digit required 2118   // digit required
2119   BOOST_STATIC_CONSTEXPR source_location loc 2119   BOOST_STATIC_CONSTEXPR source_location loc
2120   = BOOST_CURRENT_LOCATION; 2120   = BOOST_CURRENT_LOCATION;
HITCBC 2121   3 return fail(cs.begin(), error::syntax, &loc); 2121   3 return fail(cs.begin(), error::syntax, &loc);
2122   } 2122   }
2123   2123  
2124   // floating-point mantissa overflow 2124   // floating-point mantissa overflow
HITCBC 2125   17196 if( n1 + n2 >= 19 ) 2125   17196 if( n1 + n2 >= 19 )
2126   { 2126   {
HITCBC 2127   122 goto do_num7; 2127   122 goto do_num7;
2128   } 2128   }
2129   2129  
2130   BOOST_IF_CONSTEXPR( !no_parsing ) 2130   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2131   12855 num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 ); 2131   12855 num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );
2132   2132  
HITCBC 2133   17074 BOOST_ASSERT(num.bias == 0); 2133   17074 BOOST_ASSERT(num.bias == 0);
2134   2134  
HITCBC 2135   17074 num.bias -= n2; 2135   17074 num.bias -= n2;
2136   2136  
HITCBC 2137   17074 cs += n2; 2137   17074 cs += n2;
2138   2138  
HITCBC 2139   17074 char ch = *cs; 2139   17074 char ch = *cs;
2140   2140  
HITCBC 2141   17074 if( (ch | 32) == 'e' ) 2141   17074 if( (ch | 32) == 'e' )
2142   { 2142   {
HITCBC 2143   110 ++cs; 2143   110 ++cs;
HITCBC 2144   110 goto do_exp1; 2144   110 goto do_exp1;
2145   } 2145   }
HITCBC 2146   16964 else if( ch >= '0' && ch <= '9' ) 2146   16964 else if( ch >= '0' && ch <= '9' )
2147   { 2147   {
HITCBC 2148   10017 goto do_num8; 2148   10017 goto do_num8;
2149   } 2149   }
2150   2150  
HITCBC 2151   6947 goto finish_dub; 2151   6947 goto finish_dub;
2152   } 2152   }
2153   } 2153   }
2154   else 2154   else
2155   { 2155   {
HITCBC 2156   37191 num = num_; 2156   37191 num = num_;
2157   state st; 2157   state st;
HITCBC 2158   37191 st_.pop(st); 2158   37191 st_.pop(st);
HITCBC 2159   37191 switch(st) 2159   37191 switch(st)
2160   { 2160   {
MISUBC 2161   default: BOOST_JSON_UNREACHABLE(); 2161   default: BOOST_JSON_UNREACHABLE();
HITCBC 2162   602 case state::num1: goto do_num1; 2162   602 case state::num1: goto do_num1;
HITCBC 2163   6338 case state::num2: goto do_num2; 2163   6338 case state::num2: goto do_num2;
HITCBC 2164   802 case state::num3: goto do_num3; 2164   802 case state::num3: goto do_num3;
HITCBC 2165   52 case state::num4: goto do_num4; 2165   52 case state::num4: goto do_num4;
HITCBC 2166   4537 case state::num5: goto do_num5; 2166   4537 case state::num5: goto do_num5;
HITCBC 2167   666 case state::num6: goto do_num6; 2167   666 case state::num6: goto do_num6;
HITCBC 2168   616 case state::num7: goto do_num7; 2168   616 case state::num7: goto do_num7;
HITCBC 2169   10944 case state::num8: goto do_num8; 2169   10944 case state::num8: goto do_num8;
HITCBC 2170   469 case state::exp1: goto do_exp1; 2170   469 case state::exp1: goto do_exp1;
HITCBC 2171   133 case state::exp2: goto do_exp2; 2171   133 case state::exp2: goto do_exp2;
HITCBC 2172   12032 case state::exp3: goto do_exp3; 2172   12032 case state::exp3: goto do_exp3;
2173   } 2173   }
2174   } 2174   }
2175   2175  
2176   //---------------------------------- 2176   //----------------------------------
2177   // 2177   //
2178   // DIGIT 2178   // DIGIT
2179   // first digit 2179   // first digit
2180   // 2180   //
HITCBC 2181   61794 do_num1: 2181   61794 do_num1:
HITCBC 2182   15791 if(zero_first || nonzero_first || 2182   15791 if(zero_first || nonzero_first ||
HITCBC 2183   15791 BOOST_JSON_LIKELY(cs)) 2183   15791 BOOST_JSON_LIKELY(cs))
2184   { 2184   {
HITCBC 2185   61072 char const c = *cs; 2185   61072 char const c = *cs;
2186   if(zero_first) 2186   if(zero_first)
2187   { 2187   {
HITCBC 2188   9718 ++cs; 2188   9718 ++cs;
HITCBC 2189   9718 num.mant = 0; 2189   9718 num.mant = 0;
HITCBC 2190   9718 goto do_num6; 2190   9718 goto do_num6;
2191   } 2191   }
HITCBC 2192   15069 else if(nonzero_first || BOOST_JSON_LIKELY( 2192   15069 else if(nonzero_first || BOOST_JSON_LIKELY(
2193   c >= '1' && c <= '9')) 2193   c >= '1' && c <= '9'))
2194   { 2194   {
HITCBC 2195   42532 ++cs; 2195   42532 ++cs;
HITCBC 2196   42532 num.mant = c - '0'; 2196   42532 num.mant = c - '0';
2197   } 2197   }
HITCBC 2198   8822 else if(BOOST_JSON_UNLIKELY( 2198   8822 else if(BOOST_JSON_UNLIKELY(
2199   c == '0')) 2199   c == '0'))
2200   { 2200   {
HITCBC 2201   7627 ++cs; 2201   7627 ++cs;
HITCBC 2202   7627 num.mant = 0; 2202   7627 num.mant = 0;
HITCBC 2203   7627 goto do_num6; 2203   7627 goto do_num6;
2204   } 2204   }
HITCBC 2205   1195 else if( (negative || num.neg) && opt_.allow_infinity_and_nan ) 2205   1195 else if( (negative || num.neg) && opt_.allow_infinity_and_nan )
2206   { 2206   {
HITCBC 2207   1007 st_.push(state::lit1); 2207   1007 st_.push(state::lit1);
HITCBC 2208   1007 cur_lit_ = literal_index(detail::literals::neg_infinity); 2208   1007 cur_lit_ = literal_index(detail::literals::neg_infinity);
HITCBC 2209   1007 lit_offset_ = 1; 2209   1007 lit_offset_ = 1;
HITCBC 2210   1007 return parse_literal( 2210   1007 return parse_literal(
HITCBC 2211   961 cs.begin(), detail::literals_c<detail::literals::resume>() ); 2211   961 cs.begin(), detail::literals_c<detail::literals::resume>() );
2212   } 2212   }
2213   else 2213   else
2214   { 2214   {
2215   BOOST_STATIC_CONSTEXPR source_location loc 2215   BOOST_STATIC_CONSTEXPR source_location loc
2216   = BOOST_CURRENT_LOCATION; 2216   = BOOST_CURRENT_LOCATION;
HITCBC 2217   188 return fail(cs.begin(), error::syntax, &loc); 2217   188 return fail(cs.begin(), error::syntax, &loc);
2218   } 2218   }
2219   } 2219   }
2220   else 2220   else
2221   { 2221   {
HITCBC 2222   722 if(BOOST_JSON_UNLIKELY( 2222   722 if(BOOST_JSON_UNLIKELY(
2223   ! h_.on_number_part( 2223   ! h_.on_number_part(
2224   {begin, cs.used(begin)}, ec_))) 2224   {begin, cs.used(begin)}, ec_)))
HITCBC 2225   60 return fail(cs.begin()); 2225   60 return fail(cs.begin());
2226   2226  
2227   BOOST_IF_CONSTEXPR( precise_parsing ) 2227   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2228   64 num_buf_.append( begin, cs.used(begin) ); 2228   64 num_buf_.append( begin, cs.used(begin) );
HITCBC 2229   602 return maybe_suspend( 2229   602 return maybe_suspend(
HITCBC 2230   602 cs.begin(), state::num1, num); 2230   602 cs.begin(), state::num1, num);
2231   } 2231   }
2232   2232  
2233   //---------------------------------- 2233   //----------------------------------
2234   // 2234   //
2235   // 1*DIGIT 2235   // 1*DIGIT
2236   // significant digits left of decimal 2236   // significant digits left of decimal
2237   // 2237   //
HITCBC 2238   2050294 do_num2: 2238   2050294 do_num2:
HITCBC 2239   2044036 if(negative || (!stack_empty && num.neg)) 2239   2044036 if(negative || (!stack_empty && num.neg))
2240   { 2240   {
HITCBC 2241   22400 for(;;) 2241   22400 for(;;)
2242   { 2242   {
HITCBC 2243   30225 if(BOOST_JSON_UNLIKELY(! cs)) 2243   30225 if(BOOST_JSON_UNLIKELY(! cs))
2244   { 2244   {
HITCBC 2245   1921 if(BOOST_JSON_UNLIKELY(more_)) 2245   1921 if(BOOST_JSON_UNLIKELY(more_))
2246   { 2246   {
HITCBC 2247   1469 if(BOOST_JSON_UNLIKELY( 2247   1469 if(BOOST_JSON_UNLIKELY(
2248   ! h_.on_number_part( 2248   ! h_.on_number_part(
2249   {begin, cs.used(begin)}, ec_))) 2249   {begin, cs.used(begin)}, ec_)))
HITCBC 2250   69 return fail(cs.begin()); 2250   69 return fail(cs.begin());
2251   2251  
2252   BOOST_IF_CONSTEXPR( precise_parsing ) 2252   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2253   32 num_buf_.append( begin, cs.used(begin) ); 2253   32 num_buf_.append( begin, cs.used(begin) );
HITCBC 2254   1331 return suspend(cs.begin(), state::num2, num); 2254   1331 return suspend(cs.begin(), state::num2, num);
2255   } 2255   }
HITCBC 2256   452 goto finish_int; 2256   452 goto finish_int;
2257   } 2257   }
HITCBC 2258   28304 char const c = *cs; 2258   28304 char const c = *cs;
HITCBC 2259   28304 if(BOOST_JSON_LIKELY( 2259   28304 if(BOOST_JSON_LIKELY(
2260   c >= '0' && c <= '9')) 2260   c >= '0' && c <= '9'))
2261   { 2261   {
HITCBC 2262   23223 ++cs; 2262   23223 ++cs;
2263   // 9223372036854775808 INT64_MIN 2263   // 9223372036854775808 INT64_MIN
HITCBC 2264   23223 if( num.mant > 922337203685477580 || ( 2264   23223 if( num.mant > 922337203685477580 || (
HITCBC 2265   22508 num.mant == 922337203685477580 && c > '8')) 2265   22508 num.mant == 922337203685477580 && c > '8'))
2266   break; 2266   break;
2267   BOOST_IF_CONSTEXPR( !no_parsing ) 2267   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2268   22141 num.mant = 10 * num.mant + ( c - '0' ); 2268   22141 num.mant = 10 * num.mant + ( c - '0' );
HITCBC 2269   22400 continue; 2269   22400 continue;
2270   } 2270   }
HITCBC 2271   5081 goto do_num6; // [.eE] 2271   5081 goto do_num6; // [.eE]
2272   } 2272   }
2273   } 2273   }
2274   else 2274   else
2275   { 2275   {
HITCBC 2276   6885037 for(;;) 2276   6885037 for(;;)
2277   { 2277   {
HITCBC 2278   8927506 if(BOOST_JSON_UNLIKELY(! cs)) 2278   8927506 if(BOOST_JSON_UNLIKELY(! cs))
2279   { 2279   {
HITCBC 2280   6426 if(BOOST_JSON_UNLIKELY(more_)) 2280   6426 if(BOOST_JSON_UNLIKELY(more_))
2281   { 2281   {
HITCBC 2282   5813 if(BOOST_JSON_UNLIKELY( 2282   5813 if(BOOST_JSON_UNLIKELY(
2283   ! h_.on_number_part( 2283   ! h_.on_number_part(
2284   {begin, cs.used(begin)}, ec_))) 2284   {begin, cs.used(begin)}, ec_)))
HITCBC 2285   406 return fail(cs.begin()); 2285   406 return fail(cs.begin());
2286   2286  
2287   BOOST_IF_CONSTEXPR( precise_parsing ) 2287   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2288   174 num_buf_.append( begin, cs.used(begin) ); 2288   174 num_buf_.append( begin, cs.used(begin) );
HITCBC 2289   5007 return suspend(cs.begin(), state::num2, num); 2289   5007 return suspend(cs.begin(), state::num2, num);
2290   } 2290   }
HITCBC 2291   613 goto finish_int; 2291   613 goto finish_int;
2292   } 2292   }
HITCBC 2293   8921080 char const c = *cs; 2293   8921080 char const c = *cs;
HITCBC 2294   8921080 if(BOOST_JSON_LIKELY( 2294   8921080 if(BOOST_JSON_LIKELY(
2295   c >= '0' && c <= '9')) 2295   c >= '0' && c <= '9'))
2296   { 2296   {
HITCBC 2297   6888862 ++cs; 2297   6888862 ++cs;
2298   // 18446744073709551615 UINT64_MAX 2298   // 18446744073709551615 UINT64_MAX
HITCBC 2299   6888862 if( num.mant > 1844674407370955161 || ( 2299   6888862 if( num.mant > 1844674407370955161 || (
HITCBC 2300   6885459 num.mant == 1844674407370955161 && c > '5')) 2300   6885459 num.mant == 1844674407370955161 && c > '5'))
2301   break; 2301   break;
2302   BOOST_IF_CONSTEXPR( !no_parsing ) 2302   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2303   6879439 num.mant = 10 * num.mant + ( c - '0' ); 2303   6879439 num.mant = 10 * num.mant + ( c - '0' );
2304   } 2304   }
2305   else 2305   else
2306   { 2306   {
HITCBC 2307   2032218 goto do_num6; // [.eE] 2307   2032218 goto do_num6; // [.eE]
2308   } 2308   }
2309   } 2309   }
2310   } 2310   }
HITCBC 2311   4648 ++num.bias; 2311   4648 ++num.bias;
2312   2312  
2313   //---------------------------------- 2313   //----------------------------------
2314   // 2314   //
2315   // 1*DIGIT 2315   // 1*DIGIT
2316   // non-significant digits left of decimal 2316   // non-significant digits left of decimal
2317   // 2317   //
HITCBC 2318   5450 do_num3: 2318   5450 do_num3:
HITCBC 2319   11558 for(;;) 2319   11558 for(;;)
2320   { 2320   {
HITCBC 2321   17008 if(BOOST_JSON_UNLIKELY(! cs)) 2321   17008 if(BOOST_JSON_UNLIKELY(! cs))
2322   { 2322   {
HITCBC 2323   1527 if(BOOST_JSON_UNLIKELY(more_)) 2323   1527 if(BOOST_JSON_UNLIKELY(more_))
2324   { 2324   {
HITCBC 2325   894 if(BOOST_JSON_UNLIKELY( 2325   894 if(BOOST_JSON_UNLIKELY(
2326   ! h_.on_number_part( 2326   ! h_.on_number_part(
2327   {begin, cs.used(begin)}, ec_))) 2327   {begin, cs.used(begin)}, ec_)))
HITCBC 2328   46 return fail(cs.begin()); 2328   46 return fail(cs.begin());
2329   2329  
2330   BOOST_IF_CONSTEXPR( precise_parsing ) 2330   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2331   12 num_buf_.append( begin, cs.used(begin) ); 2331   12 num_buf_.append( begin, cs.used(begin) );
HITCBC 2332   802 return suspend(cs.begin(), state::num3, num); 2332   802 return suspend(cs.begin(), state::num3, num);
2333   } 2333   }
HITCBC 2334   633 goto finish_dub; 2334   633 goto finish_dub;
2335   } 2335   }
HITCBC 2336   15481 char const c = *cs; 2336   15481 char const c = *cs;
HITCBC 2337   15481 if(BOOST_JSON_UNLIKELY( 2337   15481 if(BOOST_JSON_UNLIKELY(
2338   c >= '0' && c <= '9')) 2338   c >= '0' && c <= '9'))
2339   { 2339   {
HITCBC 2340   11558 if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX )) 2340   11558 if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX ))
2341   { 2341   {
2342   BOOST_STATIC_CONSTEXPR source_location loc 2342   BOOST_STATIC_CONSTEXPR source_location loc
2343   = BOOST_CURRENT_LOCATION; 2343   = BOOST_CURRENT_LOCATION;
MISUBC 2344   return fail(cs.begin(), error::exponent_overflow, &loc); 2344   return fail(cs.begin(), error::exponent_overflow, &loc);
2345   } 2345   }
HITCBC 2346   11558 ++cs; 2346   11558 ++cs;
HITCBC 2347   11558 ++num.bias; 2347   11558 ++num.bias;
2348   } 2348   }
HITCBC 2349   3923 else if(BOOST_JSON_LIKELY( 2349   3923 else if(BOOST_JSON_LIKELY(
2350   c == '.')) 2350   c == '.'))
2351   { 2351   {
HITCBC 2352   2028 ++cs; 2352   2028 ++cs;
HITCBC 2353   2028 break; 2353   2028 break;
2354   } 2354   }
HITCBC 2355   1895 else if((c | 32) == 'e') 2355   1895 else if((c | 32) == 'e')
2356   { 2356   {
HITCBC 2357   546 ++cs; 2357   546 ++cs;
HITCBC 2358   546 goto do_exp1; 2358   546 goto do_exp1;
2359   } 2359   }
2360   else 2360   else
2361   { 2361   {
HITCBC 2362   1349 goto finish_dub; 2362   1349 goto finish_dub;
2363   } 2363   }
2364   } 2364   }
2365   2365  
2366   //---------------------------------- 2366   //----------------------------------
2367   // 2367   //
2368   // DIGIT 2368   // DIGIT
2369   // first non-significant digit 2369   // first non-significant digit
2370   // to the right of decimal 2370   // to the right of decimal
2371   // 2371   //
HITCBC 2372   2080 do_num4: 2372   2080 do_num4:
2373   { 2373   {
HITCBC 2374   2080 if(BOOST_JSON_UNLIKELY(! cs)) 2374   2080 if(BOOST_JSON_UNLIKELY(! cs))
2375   { 2375   {
HITCBC 2376   64 if(BOOST_JSON_UNLIKELY( 2376   64 if(BOOST_JSON_UNLIKELY(
2377   ! h_.on_number_part( 2377   ! h_.on_number_part(
2378   {begin, cs.used(begin)}, ec_))) 2378   {begin, cs.used(begin)}, ec_)))
HITCBC 2379   6 return fail(cs.begin()); 2379   6 return fail(cs.begin());
2380   2380  
2381   BOOST_IF_CONSTEXPR( precise_parsing ) 2381   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2382   4 num_buf_.append( begin, cs.used(begin) ); 2382   4 num_buf_.append( begin, cs.used(begin) );
HITCBC 2383   52 return maybe_suspend( 2383   52 return maybe_suspend(
HITCBC 2384   52 cs.begin(), state::num4, num); 2384   52 cs.begin(), state::num4, num);
2385   } 2385   }
HITCBC 2386   2016 char const c = *cs; 2386   2016 char const c = *cs;
HITCBC 2387   2016 if(BOOST_JSON_LIKELY( 2387   2016 if(BOOST_JSON_LIKELY(
2388   //static_cast<unsigned char>(c - '0') < 10)) 2388   //static_cast<unsigned char>(c - '0') < 10))
2389   c >= '0' && c <= '9')) 2389   c >= '0' && c <= '9'))
2390   { 2390   {
HITCBC 2391   1949 ++cs; 2391   1949 ++cs;
2392   } 2392   }
2393   else 2393   else
2394   { 2394   {
2395   // digit required 2395   // digit required
2396   BOOST_STATIC_CONSTEXPR source_location loc 2396   BOOST_STATIC_CONSTEXPR source_location loc
2397   = BOOST_CURRENT_LOCATION; 2397   = BOOST_CURRENT_LOCATION;
HITCBC 2398   67 return fail(cs.begin(), error::syntax, &loc); 2398   67 return fail(cs.begin(), error::syntax, &loc);
2399   } 2399   }
2400   } 2400   }
2401   2401  
2402   //---------------------------------- 2402   //----------------------------------
2403   // 2403   //
2404   // 1*DIGIT 2404   // 1*DIGIT
2405   // non-significant digits 2405   // non-significant digits
2406   // to the right of decimal 2406   // to the right of decimal
2407   // 2407   //
HITCBC 2408   2013470 do_num5: 2408   2013470 do_num5:
HITCBC 2409   37889832 for(;;) 2409   37889832 for(;;)
2410   { 2410   {
HITCBC 2411   39903302 if(BOOST_JSON_UNLIKELY(! cs)) 2411   39903302 if(BOOST_JSON_UNLIKELY(! cs))
2412   { 2412   {
HITCBC 2413   6112 if(BOOST_JSON_UNLIKELY(more_)) 2413   6112 if(BOOST_JSON_UNLIKELY(more_))
2414   { 2414   {
HITCBC 2415   4577 if(BOOST_JSON_UNLIKELY( 2415   4577 if(BOOST_JSON_UNLIKELY(
2416   ! h_.on_number_part( 2416   ! h_.on_number_part(
2417   {begin, cs.used(begin)}, ec_))) 2417   {begin, cs.used(begin)}, ec_)))
HITCBC 2418   20 return fail(cs.begin()); 2418   20 return fail(cs.begin());
2419   2419  
2420   BOOST_IF_CONSTEXPR( precise_parsing ) 2420   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2421   178 num_buf_.append( begin, cs.used(begin) ); 2421   178 num_buf_.append( begin, cs.used(begin) );
HITCBC 2422   4537 return suspend(cs.begin(), state::num5, num); 2422   4537 return suspend(cs.begin(), state::num5, num);
2423   } 2423   }
HITCBC 2424   1535 goto finish_dub; 2424   1535 goto finish_dub;
2425   } 2425   }
HITCBC 2426   39897190 char const c = *cs; 2426   39897190 char const c = *cs;
HITCBC 2427   39897190 if(BOOST_JSON_LIKELY( 2427   39897190 if(BOOST_JSON_LIKELY(
2428   c >= '0' && c <= '9')) 2428   c >= '0' && c <= '9'))
2429   { 2429   {
HITCBC 2430   37889832 ++cs; 2430   37889832 ++cs;
2431   } 2431   }
HITCBC 2432   2007358 else if((c | 32) == 'e') 2432   2007358 else if((c | 32) == 'e')
2433   { 2433   {
HITCBC 2434   2003236 ++cs; 2434   2003236 ++cs;
HITCBC 2435   2003236 goto do_exp1; 2435   2003236 goto do_exp1;
2436   } 2436   }
2437   else 2437   else
2438   { 2438   {
HITCBC 2439   4122 goto finish_dub; 2439   4122 goto finish_dub;
2440   } 2440   }
2441   } 2441   }
2442   2442  
2443   //---------------------------------- 2443   //----------------------------------
2444   // 2444   //
2445   // [.eE] 2445   // [.eE]
2446   // 2446   //
HITCBC 2447   2055310 do_num6: 2447   2055310 do_num6:
2448   { 2448   {
HITCBC 2449   2055310 if(BOOST_JSON_UNLIKELY(! cs)) 2449   2055310 if(BOOST_JSON_UNLIKELY(! cs))
2450   { 2450   {
HITCBC 2451   798 if(BOOST_JSON_UNLIKELY(more_)) 2451   798 if(BOOST_JSON_UNLIKELY(more_))
2452   { 2452   {
HITCBC 2453   751 if(BOOST_JSON_UNLIKELY( 2453   751 if(BOOST_JSON_UNLIKELY(
2454   ! h_.on_number_part( 2454   ! h_.on_number_part(
2455   {begin, cs.used(begin)}, ec_))) 2455   {begin, cs.used(begin)}, ec_)))
HITCBC 2456   42 return fail(cs.begin()); 2456   42 return fail(cs.begin());
2457   2457  
2458   BOOST_IF_CONSTEXPR( precise_parsing ) 2458   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2459   98 num_buf_.append( begin, cs.used(begin) ); 2459   98 num_buf_.append( begin, cs.used(begin) );
HITCBC 2460   667 return suspend(cs.begin(), state::num6, num); 2460   667 return suspend(cs.begin(), state::num6, num);
2461   } 2461   }
HITCBC 2462   47 goto finish_int; 2462   47 goto finish_int;
2463   } 2463   }
HITCBC 2464   2054512 char const c = *cs; 2464   2054512 char const c = *cs;
HITCBC 2465   2054512 if(BOOST_JSON_LIKELY( 2465   2054512 if(BOOST_JSON_LIKELY(
2466   c == '.')) 2466   c == '.'))
2467   { 2467   {
HITCBC 2468   2016097 ++cs; 2468   2016097 ++cs;
2469   } 2469   }
HITCBC 2470   38415 else if((c | 32) == 'e') 2470   38415 else if((c | 32) == 'e')
2471   { 2471   {
HITCBC 2472   9140 ++cs; 2472   9140 ++cs;
HITCBC 2473   9140 goto do_exp1; 2473   9140 goto do_exp1;
2474   } 2474   }
2475   else 2475   else
2476   { 2476   {
HITCBC 2477   29275 goto finish_int; 2477   29275 goto finish_int;
2478   } 2478   }
2479   } 2479   }
2480   2480  
2481   //---------------------------------- 2481   //----------------------------------
2482   // 2482   //
2483   // DIGIT 2483   // DIGIT
2484   // first significant digit 2484   // first significant digit
2485   // to the right of decimal 2485   // to the right of decimal
2486   // 2486   //
HITCBC 2487   2016835 do_num7: 2487   2016835 do_num7:
2488   { 2488   {
HITCBC 2489   2016835 if(BOOST_JSON_UNLIKELY(! cs)) 2489   2016835 if(BOOST_JSON_UNLIKELY(! cs))
2490   { 2490   {
HITCBC 2491   691 if(BOOST_JSON_UNLIKELY(more_)) 2491   691 if(BOOST_JSON_UNLIKELY(more_))
2492   { 2492   {
HITCBC 2493   687 if(BOOST_JSON_UNLIKELY( 2493   687 if(BOOST_JSON_UNLIKELY(
2494   ! h_.on_number_part( 2494   ! h_.on_number_part(
2495   {begin, cs.used(begin)}, ec_))) 2495   {begin, cs.used(begin)}, ec_)))
HITCBC 2496   35 return fail(cs.begin()); 2496   35 return fail(cs.begin());
2497   2497  
2498   BOOST_IF_CONSTEXPR( precise_parsing ) 2498   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2499   96 num_buf_.append( begin, cs.used(begin) ); 2499   96 num_buf_.append( begin, cs.used(begin) );
HITCBC 2500   617 return suspend(cs.begin(), state::num7, num); 2500   617 return suspend(cs.begin(), state::num7, num);
2501   } 2501   }
2502   // digit required 2502   // digit required
2503   BOOST_STATIC_CONSTEXPR source_location loc 2503   BOOST_STATIC_CONSTEXPR source_location loc
2504   = BOOST_CURRENT_LOCATION; 2504   = BOOST_CURRENT_LOCATION;
HITCBC 2505   4 return fail(cs.begin(), error::syntax, &loc); 2505   4 return fail(cs.begin(), error::syntax, &loc);
2506   } 2506   }
HITCBC 2507   2016144 char const c = *cs; 2507   2016144 char const c = *cs;
HITCBC 2508   2016144 if(BOOST_JSON_UNLIKELY( 2508   2016144 if(BOOST_JSON_UNLIKELY(
2509   c < '0' || c > '9')) 2509   c < '0' || c > '9'))
2510   { 2510   {
2511   // digit required 2511   // digit required
2512   BOOST_STATIC_CONSTEXPR source_location loc 2512   BOOST_STATIC_CONSTEXPR source_location loc
2513   = BOOST_CURRENT_LOCATION; 2513   = BOOST_CURRENT_LOCATION;
HITCBC 2514   169 return fail(cs.begin(), error::syntax, &loc); 2514   169 return fail(cs.begin(), error::syntax, &loc);
2515   } 2515   }
2516   } 2516   }
2517   2517  
2518   //---------------------------------- 2518   //----------------------------------
2519   // 2519   //
2520   // 1*DIGIT 2520   // 1*DIGIT
2521   // significant digits 2521   // significant digits
2522   // to the right of decimal 2522   // to the right of decimal
2523   // 2523   //
HITCBC 2524   2034436 do_num8: 2524   2034436 do_num8:
HITCBC 2525   3277926 for(;;) 2525   3277926 for(;;)
2526   { 2526   {
HITCBC 2527   5314862 if(BOOST_JSON_UNLIKELY(! cs)) 2527   5314862 if(BOOST_JSON_UNLIKELY(! cs))
2528   { 2528   {
HITCBC 2529   12816 if(BOOST_JSON_UNLIKELY(more_)) 2529   12816 if(BOOST_JSON_UNLIKELY(more_))
2530   { 2530   {
HITCBC 2531   11080 if(BOOST_JSON_UNLIKELY( 2531   11080 if(BOOST_JSON_UNLIKELY(
2532   ! h_.on_number_part( 2532   ! h_.on_number_part(
2533   {begin, cs.used(begin)}, ec_))) 2533   {begin, cs.used(begin)}, ec_)))
HITCBC 2534   67 return fail(cs.begin()); 2534   67 return fail(cs.begin());
2535   2535  
2536   BOOST_IF_CONSTEXPR( precise_parsing ) 2536   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2537   3442 num_buf_.append( begin, cs.used(begin) ); 2537   3442 num_buf_.append( begin, cs.used(begin) );
HITCBC 2538   10945 return suspend(cs.begin(), state::num8, num); 2538   10945 return suspend(cs.begin(), state::num8, num);
2539   } 2539   }
HITCBC 2540   1736 goto finish_dub; 2540   1736 goto finish_dub;
2541   } 2541   }
HITCBC 2542   5302046 char const c = *cs; 2542   5302046 char const c = *cs;
HITCBC 2543   5302046 if(BOOST_JSON_LIKELY( 2543   5302046 if(BOOST_JSON_LIKELY(
2544   c >= '0' && c <= '9')) 2544   c >= '0' && c <= '9'))
2545   { 2545   {
HITCBC 2546   5284910 ++cs; 2546   5284910 ++cs;
HITCBC 2547   5279817 if(!no_parsing && BOOST_JSON_LIKELY( 2547   5279817 if(!no_parsing && BOOST_JSON_LIKELY(
2548   num.mant <= 9007199254740991)) // 2^53-1 2548   num.mant <= 9007199254740991)) // 2^53-1
2549   { 2549   {
HITCBC 2550   3277926 if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN )) 2550   3277926 if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN ))
2551   { 2551   {
2552   BOOST_STATIC_CONSTEXPR source_location loc 2552   BOOST_STATIC_CONSTEXPR source_location loc
2553   = BOOST_CURRENT_LOCATION; 2553   = BOOST_CURRENT_LOCATION;
MISUBC 2554   return fail(cs.begin(), error::exponent_overflow, &loc); 2554   return fail(cs.begin(), error::exponent_overflow, &loc);
2555   } 2555   }
HITCBC 2556   3277926 --num.bias; 2556   3277926 --num.bias;
HITCBC 2557   3277926 num.mant = 10 * num.mant + ( c - '0' ); 2557   3277926 num.mant = 10 * num.mant + ( c - '0' );
2558   } 2558   }
2559   else 2559   else
2560   { 2560   {
HITCBC 2561   2006984 goto do_num5; 2561   2006984 goto do_num5;
2562   } 2562   }
2563   } 2563   }
HITCBC 2564   17136 else if((c | 32) == 'e') 2564   17136 else if((c | 32) == 'e')
2565   { 2565   {
HITCBC 2566   11133 ++cs; 2566   11133 ++cs;
HITCBC 2567   11133 goto do_exp1; 2567   11133 goto do_exp1;
2568   } 2568   }
2569   else 2569   else
2570   { 2570   {
HITCBC 2571   6003 goto finish_dub; 2571   6003 goto finish_dub;
2572   } 2572   }
2573   } 2573   }
2574   2574  
2575   //---------------------------------- 2575   //----------------------------------
2576   // 2576   //
2577   // *[+-] 2577   // *[+-]
2578   // 2578   //
HITCBC 2579   2031210 do_exp1: 2579   2031210 do_exp1:
HITCBC 2580   2031210 if(BOOST_JSON_UNLIKELY(! cs)) 2580   2031210 if(BOOST_JSON_UNLIKELY(! cs))
2581   { 2581   {
HITCBC 2582   565 if(BOOST_JSON_UNLIKELY( 2582   565 if(BOOST_JSON_UNLIKELY(
2583   ! h_.on_number_part( 2583   ! h_.on_number_part(
2584   {begin, cs.used(begin)}, ec_))) 2584   {begin, cs.used(begin)}, ec_)))
HITCBC 2585   48 return fail(cs.begin()); 2585   48 return fail(cs.begin());
2586   2586  
2587   BOOST_IF_CONSTEXPR( precise_parsing ) 2587   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2588   46 num_buf_.append( begin, cs.used(begin) ); 2588   46 num_buf_.append( begin, cs.used(begin) );
HITCBC 2589   469 return maybe_suspend( 2589   469 return maybe_suspend(
HITCBC 2590   469 cs.begin(), state::exp1, num); 2590   469 cs.begin(), state::exp1, num);
2591   } 2591   }
HITCBC 2592   2030645 if(*cs == '+') 2592   2030645 if(*cs == '+')
2593   { 2593   {
HITCBC 2594   2150 ++cs; 2594   2150 ++cs;
2595   } 2595   }
HITCBC 2596   2028495 else if(*cs == '-') 2596   2028495 else if(*cs == '-')
2597   { 2597   {
HITCBC 2598   1001935 ++cs; 2598   1001935 ++cs;
HITCBC 2599   1001935 num.frac = true; 2599   1001935 num.frac = true;
2600   } 2600   }
2601   2601  
2602   //---------------------------------- 2602   //----------------------------------
2603   // 2603   //
2604   // DIGIT 2604   // DIGIT
2605   // first digit of the exponent 2605   // first digit of the exponent
2606   // 2606   //
HITCBC 2607   1026560 do_exp2: 2607   1026560 do_exp2:
2608   { 2608   {
HITCBC 2609   2030778 if(BOOST_JSON_UNLIKELY(! cs)) 2609   2030778 if(BOOST_JSON_UNLIKELY(! cs))
2610   { 2610   {
HITCBC 2611   180 if(BOOST_JSON_UNLIKELY(more_)) 2611   180 if(BOOST_JSON_UNLIKELY(more_))
2612   { 2612   {
HITCBC 2613   171 if(BOOST_JSON_UNLIKELY( 2613   171 if(BOOST_JSON_UNLIKELY(
2614   ! h_.on_number_part( 2614   ! h_.on_number_part(
2615   {begin, cs.used(begin)}, ec_))) 2615   {begin, cs.used(begin)}, ec_)))
HITCBC 2616   19 return fail(cs.begin()); 2616   19 return fail(cs.begin());
2617   2617  
2618   BOOST_IF_CONSTEXPR( precise_parsing ) 2618   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2619   4 num_buf_.append( begin, cs.used(begin) ); 2619   4 num_buf_.append( begin, cs.used(begin) );
HITCBC 2620   133 return suspend(cs.begin(), state::exp2, num); 2620   133 return suspend(cs.begin(), state::exp2, num);
2621   } 2621   }
2622   // digit required 2622   // digit required
2623   BOOST_STATIC_CONSTEXPR source_location loc 2623   BOOST_STATIC_CONSTEXPR source_location loc
2624   = BOOST_CURRENT_LOCATION; 2624   = BOOST_CURRENT_LOCATION;
HITCBC 2625   9 return fail(cs.begin(), error::syntax, &loc); 2625   9 return fail(cs.begin(), error::syntax, &loc);
2626   } 2626   }
HITCBC 2627   2030598 char const c = *cs; 2627   2030598 char const c = *cs;
HITCBC 2628   2030598 if(BOOST_JSON_UNLIKELY( 2628   2030598 if(BOOST_JSON_UNLIKELY(
2629   c < '0' || c > '9')) 2629   c < '0' || c > '9'))
2630   { 2630   {
2631   // digit required 2631   // digit required
2632   BOOST_STATIC_CONSTEXPR source_location loc 2632   BOOST_STATIC_CONSTEXPR source_location loc
2633   = BOOST_CURRENT_LOCATION; 2633   = BOOST_CURRENT_LOCATION;
HITCBC 2634   508 return fail(cs.begin(), error::syntax, &loc); 2634   508 return fail(cs.begin(), error::syntax, &loc);
2635   } 2635   }
HITCBC 2636   2030090 ++cs; 2636   2030090 ++cs;
HITCBC 2637   2030090 num.exp = c - '0'; 2637   2030090 num.exp = c - '0';
2638   } 2638   }
2639   2639  
2640   //---------------------------------- 2640   //----------------------------------
2641   // 2641   //
2642   // 1*DIGIT 2642   // 1*DIGIT
2643   // subsequent digits in the exponent 2643   // subsequent digits in the exponent
2644   // 2644   //
HITCBC 2645   2042122 do_exp3: 2645   2042122 do_exp3:
HITCBC 2646   5466310 for(;;) 2646   5466310 for(;;)
2647   { 2647   {
HITCBC 2648   7508432 if(BOOST_JSON_UNLIKELY(! cs)) 2648   7508432 if(BOOST_JSON_UNLIKELY(! cs))
2649   { 2649   {
HITCBC 2650   2020539 if(BOOST_JSON_UNLIKELY(more_)) 2650   2020539 if(BOOST_JSON_UNLIKELY(more_))
2651   { 2651   {
HITCBC 2652   12186 if(BOOST_JSON_UNLIKELY( 2652   12186 if(BOOST_JSON_UNLIKELY(
2653   ! h_.on_number_part( 2653   ! h_.on_number_part(
2654   {begin, cs.used(begin)}, ec_))) 2654   {begin, cs.used(begin)}, ec_)))
HITCBC 2655   77 return fail(cs.begin()); 2655   77 return fail(cs.begin());
2656   2656  
2657   BOOST_IF_CONSTEXPR( precise_parsing ) 2657   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2658   2873 num_buf_.append( begin, cs.used(begin) ); 2658   2873 num_buf_.append( begin, cs.used(begin) );
HITCBC 2659   12032 return suspend(cs.begin(), state::exp3, num); 2659   12032 return suspend(cs.begin(), state::exp3, num);
2660   } 2660   }
2661   } 2661   }
2662   else 2662   else
2663   { 2663   {
HITCBC 2664   5487893 char const c = *cs; 2664   5487893 char const c = *cs;
HITCBC 2665   5487893 if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' )) 2665   5487893 if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' ))
2666   { 2666   {
HITCBC 2667   5466310 if(BOOST_JSON_UNLIKELY( 2667   5466310 if(BOOST_JSON_UNLIKELY(
2668   // 2147483647 INT_MAX 2668   // 2147483647 INT_MAX
2669   num.exp > 214748364 || 2669   num.exp > 214748364 ||
2670   (num.exp == 214748364 && c > '7') 2670   (num.exp == 214748364 && c > '7')
2671   )) 2671   ))
HITCBC 2672   3855 num.exp = INT_MAX; 2672   3855 num.exp = INT_MAX;
2673   else BOOST_IF_CONSTEXPR( !no_parsing ) 2673   else BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2674   4921603 num.exp = 10 * num.exp + ( c - '0' ); 2674   4921603 num.exp = 10 * num.exp + ( c - '0' );
2675   2675  
HITCBC 2676   5466310 ++cs; 2676   5466310 ++cs;
HITCBC 2677   5466310 continue; 2677   5466310 continue;
2678   } 2678   }
2679   } 2679   }
HITCBC 2680   2029936 BOOST_ASSERT(num.exp >= 0); 2680   2029936 BOOST_ASSERT(num.exp >= 0);
HITCBC 2681   2029936 if ( num.frac ) 2681   2029936 if ( num.frac )
2682   { 2682   {
HITCBC 2683   1001799 if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) )) 2683   1001799 if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) ))
2684   { 2684   {
2685   // if exponent overflowed, bias is a very large negative 2685   // if exponent overflowed, bias is a very large negative
2686   // number, and mantissa isn't zero, then we cannot parse the 2686   // number, and mantissa isn't zero, then we cannot parse the
2687   // number correctly 2687   // number correctly
HITCBC 2688   91 if(BOOST_JSON_UNLIKELY( 2688   91 if(BOOST_JSON_UNLIKELY(
2689   (num.exp == INT_MAX) && 2689   (num.exp == INT_MAX) &&
2690   (num.bias < 0) && 2690   (num.bias < 0) &&
2691   (num.exp + num.bias < 308) && 2691   (num.exp + num.bias < 308) &&
2692   num.mant )) 2692   num.mant ))
2693   { 2693   {
2694   BOOST_STATIC_CONSTEXPR source_location loc 2694   BOOST_STATIC_CONSTEXPR source_location loc
2695   = BOOST_CURRENT_LOCATION; 2695   = BOOST_CURRENT_LOCATION;
MISUBC 2696   return fail(cs.begin(), error::exponent_overflow, &loc); 2696   return fail(cs.begin(), error::exponent_overflow, &loc);
2697   } 2697   }
2698   2698  
HITCBC 2699   91 num.bias = 0; 2699   91 num.bias = 0;
HITCBC 2700   91 num.exp = INT_MAX; 2700   91 num.exp = INT_MAX;
2701   } 2701   }
2702   } 2702   }
HITCBC 2703   1028137 else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) )) 2703   1028137 else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) ))
2704   { 2704   {
2705   // if exponent overflowed, bias is a very large positive number, 2705   // if exponent overflowed, bias is a very large positive number,
2706   // and mantissa isn't zero, then we cannot parse the 2706   // and mantissa isn't zero, then we cannot parse the
2707   // number correctly 2707   // number correctly
MISUBC 2708   if(BOOST_JSON_UNLIKELY( 2708   if(BOOST_JSON_UNLIKELY(
2709   (num.exp == INT_MAX) && 2709   (num.exp == INT_MAX) &&
2710   (num.bias > 0) && 2710   (num.bias > 0) &&
2711   (num.exp - num.bias < 308) && 2711   (num.exp - num.bias < 308) &&
2712   num.mant )) 2712   num.mant ))
2713   { 2713   {
2714   BOOST_STATIC_CONSTEXPR source_location loc 2714   BOOST_STATIC_CONSTEXPR source_location loc
2715   = BOOST_CURRENT_LOCATION; 2715   = BOOST_CURRENT_LOCATION;
MISUBC 2716   return fail(cs.begin(), error::exponent_overflow, &loc); 2716   return fail(cs.begin(), error::exponent_overflow, &loc);
2717   } 2717   }
2718   2718  
MISUBC 2719   num.bias = 0; 2719   num.bias = 0;
MISUBC 2720   num.exp = INT_MAX; 2720   num.exp = INT_MAX;
2721   } 2721   }
HITCBC 2722   2029936 goto finish_dub; 2722   2029936 goto finish_dub;
2723   } 2723   }
2724   2724  
HITCBC 2725   30387 finish_int: 2725   30387 finish_int:
HITCBC 2726   28458 if(negative || (!stack_empty && num.neg)) 2726   28458 if(negative || (!stack_empty && num.neg))
2727   { 2727   {
HITCBC 2728   2531 if(BOOST_JSON_UNLIKELY( 2728   2531 if(BOOST_JSON_UNLIKELY(
2729   ! h_.on_int64(static_cast< 2729   ! h_.on_int64(static_cast<
2730   int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_))) 2730   int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_)))
HITCBC 2731   310 return fail(cs.begin()); 2731   310 return fail(cs.begin());
HITCBC 2732   1913 return cs.begin(); 2732   1913 return cs.begin();
2733   } 2733   }
HITCBC 2734   27856 if(num.mant <= INT64_MAX) 2734   27856 if(num.mant <= INT64_MAX)
2735   { 2735   {
HITCBC 2736   27555 finish_signed: 2736   27555 finish_signed:
HITCBC 2737   30830 if(BOOST_JSON_UNLIKELY( 2737   30830 if(BOOST_JSON_UNLIKELY(
2738   ! h_.on_int64(static_cast< 2738   ! h_.on_int64(static_cast<
2739   int64_t>(num.mant), {begin, cs.used(begin)}, ec_))) 2739   int64_t>(num.mant), {begin, cs.used(begin)}, ec_)))
HITCBC 2740   2267 return fail(cs.begin()); 2740   2267 return fail(cs.begin());
HITCBC 2741   26303 return cs.begin(); 2741   26303 return cs.begin();
2742   } 2742   }
HITCBC 2743   321 if(BOOST_JSON_UNLIKELY( 2743   321 if(BOOST_JSON_UNLIKELY(
2744   ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_))) 2744   ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_)))
HITCBC 2745   35 return fail(cs.begin()); 2745   35 return fail(cs.begin());
HITCBC 2746   254 return cs.begin(); 2746   254 return cs.begin();
HITCBC 2747   2052261 finish_dub: 2747   2052261 finish_dub:
2748   double d; 2748   double d;
HITCBC 2749   2052261 std::size_t const size = cs.used(begin); 2749   2052261 std::size_t const size = cs.used(begin);
HITCBC 2750   2052261 BOOST_ASSERT( !num_buf_.size() || precise_parsing ); 2750   2052261 BOOST_ASSERT( !num_buf_.size() || precise_parsing );
2751   BOOST_IF_CONSTEXPR( precise_parsing ) 2751   BOOST_IF_CONSTEXPR( precise_parsing )
2752   { 2752   {
HITCBC 2753   1009310 char const* data = begin; 2753   1009310 char const* data = begin;
HITCBC 2754   1009310 std::size_t full_size = size; 2754   1009310 std::size_t full_size = size;
2755   // if we previously suspended or if the current input ends with the 2755   // if we previously suspended or if the current input ends with the
2756   // number, we need to copy the current part of the number to the 2756   // number, we need to copy the current part of the number to the
2757   // temporary buffer 2757   // temporary buffer
HITCBC 2758   1009310 if(BOOST_JSON_UNLIKELY( num_buf_.size() )) 2758   1009310 if(BOOST_JSON_UNLIKELY( num_buf_.size() ))
2759   { 2759   {
HITCBC 2760   4771 data = num_buf_.append( begin, size ); 2760   4771 data = num_buf_.append( begin, size );
HITCBC 2761   4771 full_size = num_buf_.size(); 2761   4771 full_size = num_buf_.size();
2762   } 2762   }
HITCBC 2763   1009310 auto const err = detail::charconv::from_chars( 2763   1009310 auto const err = detail::charconv::from_chars(
2764   data, data + full_size, d ); 2764   data, data + full_size, d );
HITCBC 2765   1009310 BOOST_ASSERT( err.ec != std::errc::invalid_argument ); 2765   1009310 BOOST_ASSERT( err.ec != std::errc::invalid_argument );
HITCBC 2766   1009310 BOOST_ASSERT( err.ptr == data + full_size ); 2766   1009310 BOOST_ASSERT( err.ptr == data + full_size );
2767   (void)err; 2767   (void)err;
2768   } 2768   }
2769   else BOOST_IF_CONSTEXPR( no_parsing ) 2769   else BOOST_IF_CONSTEXPR( no_parsing )
HITCBC 2770   9258 d = 0; 2770   9258 d = 0;
2771   else 2771   else
HITCBC 2772   1033693 d = detail::dec_to_float( 2772   1033693 d = detail::dec_to_float(
2773   num.mant, 2773   num.mant,
HITCBC 2774   531741 num.bias + (num.frac ? 2774   531741 num.bias + (num.frac ?
HITCBC 2775   501952 -num.exp : num.exp), 2775   501952 -num.exp : num.exp),
HITCBC 2776   1033693 num.neg); 2776   1033693 num.neg);
HITCBC 2777   2052261 if(BOOST_JSON_UNLIKELY( 2777   2052261 if(BOOST_JSON_UNLIKELY(
2778   ! h_.on_double(d, {begin, size}, ec_))) 2778   ! h_.on_double(d, {begin, size}, ec_)))
HITCBC 2779   1903 return fail(cs.begin()); 2779   1903 return fail(cs.begin());
HITCBC 2780   2048455 return cs.begin(); 2780   2048455 return cs.begin();
2781   } 2781   }
2782   2782  
2783   //---------------------------------------------------------- 2783   //----------------------------------------------------------
2784   2784  
2785   template<class Handler> 2785   template<class Handler>
2786   template<class... Args> 2786   template<class... Args>
HITCBC 2787   2164608 basic_parser<Handler>:: 2787   2164608 basic_parser<Handler>::
2788   basic_parser( 2788   basic_parser(
2789   parse_options const& opt, 2789   parse_options const& opt,
2790   Args&&... args) 2790   Args&&... args)
HITCBC 2791   2164600 : h_(std::forward<Args>(args)...) 2791   2164600 : h_(std::forward<Args>(args)...)
HITCBC 2792   2164608 , opt_(opt) 2792   2164608 , opt_(opt)
2793   { 2793   {
HITCBC 2794   2164608 } 2794   2164608 }
2795   2795  
2796   //---------------------------------------------------------- 2796   //----------------------------------------------------------
2797   2797  
2798   template<class Handler> 2798   template<class Handler>
2799   void 2799   void
HITCBC 2800   4153132 basic_parser<Handler>:: 2800   4153132 basic_parser<Handler>::
2801   reset() noexcept 2801   reset() noexcept
2802   { 2802   {
HITCBC 2803   4153132 ec_ = {}; 2803   4153132 ec_ = {};
HITCBC 2804   4153132 st_.clear(); 2804   4153132 st_.clear();
HITCBC 2805   4153132 more_ = true; 2805   4153132 more_ = true;
HITCBC 2806   4153132 done_ = false; 2806   4153132 done_ = false;
HITCBC 2807   4153132 clean_ = true; 2807   4153132 clean_ = true;
HITCBC 2808   4153132 num_buf_.clear(); 2808   4153132 num_buf_.clear();
HITCBC 2809   4153132 } 2809   4153132 }
2810   2810  
2811   template<class Handler> 2811   template<class Handler>
2812   void 2812   void
HITCBC 2813   16 basic_parser<Handler>:: 2813   16 basic_parser<Handler>::
2814   fail(system::error_code ec) noexcept 2814   fail(system::error_code ec) noexcept
2815   { 2815   {
HITCBC 2816   16 if(! ec) 2816   16 if(! ec)
2817   { 2817   {
2818   // assign an arbitrary 2818   // assign an arbitrary
2819   // error code to prevent UB 2819   // error code to prevent UB
MISUBC 2820   BOOST_JSON_FAIL(ec_, error::incomplete); 2820   BOOST_JSON_FAIL(ec_, error::incomplete);
2821   } 2821   }
2822   else 2822   else
2823   { 2823   {
HITCBC 2824   16 ec_ = ec; 2824   16 ec_ = ec;
2825   } 2825   }
HITCBC 2826   16 done_ = false; 2826   16 done_ = false;
HITCBC 2827   16 } 2827   16 }
2828   2828  
2829   //---------------------------------------------------------- 2829   //----------------------------------------------------------
2830   2830  
2831   template<class Handler> 2831   template<class Handler>
2832   std::size_t 2832   std::size_t
HITCBC 2833   2334223 basic_parser<Handler>:: 2833   2334223 basic_parser<Handler>::
2834   write_some( 2834   write_some(
2835   bool more, 2835   bool more,
2836   char const* data, 2836   char const* data,
2837   std::size_t size, 2837   std::size_t size,
2838   system::error_code& ec) 2838   system::error_code& ec)
2839   { 2839   {
2840   // see if we exited via exception 2840   // see if we exited via exception
2841   // on the last call to write_some 2841   // on the last call to write_some
HITCBC 2842   2334223 if(! clean_) 2842   2334223 if(! clean_)
2843   { 2843   {
2844   // prevent UB 2844   // prevent UB
HITCBC 2845   1 if(! ec_) 2845   1 if(! ec_)
2846   { 2846   {
HITCBC 2847   1 BOOST_JSON_FAIL(ec_, error::exception); 2847   1 BOOST_JSON_FAIL(ec_, error::exception);
2848   } 2848   }
2849   } 2849   }
HITCBC 2850   2334223 if(ec_) 2850   2334223 if(ec_)
2851   { 2851   {
2852   // error is sticky 2852   // error is sticky
HITCBC 2853   5 ec = ec_; 2853   5 ec = ec_;
HITCBC 2854   5 return 0; 2854   5 return 0;
2855   } 2855   }
HITCBC 2856   2334218 clean_ = false; 2856   2334218 clean_ = false;
HITCBC 2857   2334218 more_ = more; 2857   2334218 more_ = more;
HITCBC 2858   2334218 end_ = data + size; 2858   2334218 end_ = data + size;
2859   const char* p; 2859   const char* p;
HITCBC 2860   2334218 if(BOOST_JSON_LIKELY(st_.empty())) 2860   2334218 if(BOOST_JSON_LIKELY(st_.empty()))
2861   { 2861   {
2862   // first time 2862   // first time
HITCBC 2863   2164594 depth_ = opt_.max_depth; 2863   2164594 depth_ = opt_.max_depth;
HITCBC 2864   2164594 if(BOOST_JSON_UNLIKELY( 2864   2164594 if(BOOST_JSON_UNLIKELY(
2865   ! h_.on_document_begin(ec_))) 2865   ! h_.on_document_begin(ec_)))
2866   { 2866   {
HITCBC 2867   7889 ec = ec_; 2867   7889 ec = ec_;
HITCBC 2868   7889 return 0; 2868   7889 return 0;
2869   } 2869   }
HITCBC 2870   2148815 p = parse_document(data, std::true_type()); 2870   2148815 p = parse_document(data, std::true_type());
2871   } 2871   }
2872   else 2872   else
2873   { 2873   {
HITCBC 2874   169624 p = parse_document(data, std::false_type()); 2874   169624 p = parse_document(data, std::false_type());
2875   } 2875   }
2876   2876  
HITCBC 2877   2299340 if(BOOST_JSON_LIKELY(p != sentinel())) 2877   2299340 if(BOOST_JSON_LIKELY(p != sentinel()))
2878   { 2878   {
HITCBC 2879   2099052 BOOST_ASSERT(! ec_); 2879   2099052 BOOST_ASSERT(! ec_);
HITCBC 2880   2099052 if(! done_) 2880   2099052 if(! done_)
2881   { 2881   {
HITCBC 2882   2031637 done_ = true; 2882   2031637 done_ = true;
HITCBC 2883   2031637 h_.on_document_end(ec_); 2883   2031637 h_.on_document_end(ec_);
2884   } 2884   }
2885   } 2885   }
2886   else 2886   else
2887   { 2887   {
HITCBC 2888   200288 if(! ec_) 2888   200288 if(! ec_)
2889   { 2889   {
HITCBC 2890   173509 if(! more_) 2890   173509 if(! more_)
2891   { 2891   {
HITCBC 2892   573 BOOST_JSON_FAIL(ec_, error::incomplete); 2892   573 BOOST_JSON_FAIL(ec_, error::incomplete);
2893   } 2893   }
HITCBC 2894   172936 else if(! st_.empty()) 2894   172936 else if(! st_.empty())
2895   { 2895   {
2896   // consume as much trailing whitespace in 2896   // consume as much trailing whitespace in
2897   // the JSON document as possible, but still 2897   // the JSON document as possible, but still
2898   // consider the parse complete 2898   // consider the parse complete
2899   state st; 2899   state st;
HITCBC 2900   172936 st_.peek(st); 2900   172936 st_.peek(st);
HITCBC 2901   172936 if( st == state::doc3 && 2901   172936 if( st == state::doc3 &&
HITCBC 2902   88551 ! done_) 2902   88551 ! done_)
2903   { 2903   {
HITCBC 2904   70724 done_ = true; 2904   70724 done_ = true;
HITCBC 2905   70724 h_.on_document_end(ec_); 2905   70724 h_.on_document_end(ec_);
2906   } 2906   }
2907   } 2907   }
2908   } 2908   }
HITCBC 2909   198644 p = end_; 2909   198644 p = end_;
2910   } 2910   }
HITCBC 2911   2293736 ec = ec_; 2911   2293736 ec = ec_;
HITCBC 2912   2293736 clean_ = true; 2912   2293736 clean_ = true;
HITCBC 2913   2293736 return p - data; 2913   2293736 return p - data;
2914   } 2914   }
2915   2915  
2916   template<class Handler> 2916   template<class Handler>
2917   std::size_t 2917   std::size_t
HITCBC 2918   1 basic_parser<Handler>:: 2918   1 basic_parser<Handler>::
2919   write_some( 2919   write_some(
2920   bool more, 2920   bool more,
2921   char const* data, 2921   char const* data,
2922   std::size_t size, 2922   std::size_t size,
2923   std::error_code& ec) 2923   std::error_code& ec)
2924   { 2924   {
HITCBC 2925   1 system::error_code jec; 2925   1 system::error_code jec;
HITCBC 2926   1 std::size_t const result = write_some(more, data, size, jec); 2926   1 std::size_t const result = write_some(more, data, size, jec);
HITCBC 2927   1 ec = jec; 2927   1 ec = jec;
HITCBC 2928   1 return result; 2928   1 return result;
2929   } 2929   }
2930   2930  
2931   #endif 2931   #endif
2932   2932  
2933   } // namespace json 2933   } // namespace json
2934   } // namespace boost 2934   } // namespace boost
2935   2935  
2936   #ifdef _MSC_VER 2936   #ifdef _MSC_VER
2937   #pragma warning(pop) 2937   #pragma warning(pop)
2938   #endif 2938   #endif
2939   2939  
2940   #endif 2940   #endif