1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_IMPL_PARSER_IPP
10  
#ifndef BOOST_JSON_IMPL_PARSER_IPP
11  
#define BOOST_JSON_IMPL_PARSER_IPP
11  
#define BOOST_JSON_IMPL_PARSER_IPP
12  

12  

13  
#include <boost/json/parser.hpp>
13  
#include <boost/json/parser.hpp>
14  
#include <boost/json/basic_parser_impl.hpp>
14  
#include <boost/json/basic_parser_impl.hpp>
15  
#include <boost/json/error.hpp>
15  
#include <boost/json/error.hpp>
16  
#include <cstring>
16  
#include <cstring>
17  
#include <stdexcept>
17  
#include <stdexcept>
18  
#include <utility>
18  
#include <utility>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace json {
21  
namespace json {
22  

22  

23  
parser::
23  
parser::
24  
parser(
24  
parser(
25  
    storage_ptr sp,
25  
    storage_ptr sp,
26  
    parse_options const& opt,
26  
    parse_options const& opt,
27  
    unsigned char* buffer,
27  
    unsigned char* buffer,
28  
    std::size_t size) noexcept
28  
    std::size_t size) noexcept
29  
    : p_(
29  
    : p_(
30  
        opt,
30  
        opt,
31  
        std::move(sp),
31  
        std::move(sp),
32  
        buffer,
32  
        buffer,
33  
        size)
33  
        size)
34  
{
34  
{
35  
    reset();
35  
    reset();
36  
}
36  
}
37  

37  

38  
parser::
38  
parser::
39  
parser(
39  
parser(
40  
    storage_ptr sp,
40  
    storage_ptr sp,
41  
    parse_options const& opt) noexcept
41  
    parse_options const& opt) noexcept
42  
    : p_(
42  
    : p_(
43  
        opt,
43  
        opt,
44  
        std::move(sp),
44  
        std::move(sp),
45  
        nullptr,
45  
        nullptr,
46  
        0)
46  
        0)
47  
{
47  
{
48  
    reset();
48  
    reset();
49  
}
49  
}
50  

50  

51  
void
51  
void
52  
parser::
52  
parser::
53  
reset(storage_ptr sp) noexcept
53  
reset(storage_ptr sp) noexcept
54  
{
54  
{
55  
    p_.reset();
55  
    p_.reset();
56  
    p_.handler().st.reset(sp);
56  
    p_.handler().st.reset(sp);
57  
}
57  
}
58  

58  

59  
std::size_t
59  
std::size_t
60  
parser::
60  
parser::
61  
write_some(
61  
write_some(
62  
    char const* data,
62  
    char const* data,
63  
    std::size_t size,
63  
    std::size_t size,
64  
    system::error_code& ec)
64  
    system::error_code& ec)
65  
{
65  
{
66  
    auto const n = p_.write_some(
66  
    auto const n = p_.write_some(
67  
        false, data, size, ec);
67  
        false, data, size, ec);
68  
    BOOST_ASSERT(ec || p_.done());
68  
    BOOST_ASSERT(ec || p_.done());
69  
    return n;
69  
    return n;
70  
}
70  
}
71  

71  

72  
std::size_t
72  
std::size_t
73  
parser::
73  
parser::
74  
write_some(
74  
write_some(
75  
    char const* data,
75  
    char const* data,
76  
    std::size_t size,
76  
    std::size_t size,
77  
    std::error_code& ec)
77  
    std::error_code& ec)
78  
{
78  
{
79  
    system::error_code jec;
79  
    system::error_code jec;
80  
    std::size_t const result = write_some(data, size, jec);
80  
    std::size_t const result = write_some(data, size, jec);
81  
    ec = jec;
81  
    ec = jec;
82  
    return result;
82  
    return result;
83  
}
83  
}
84  

84  

85  
std::size_t
85  
std::size_t
86  
parser::
86  
parser::
87  
write_some(
87  
write_some(
88  
    char const* data,
88  
    char const* data,
89  
    std::size_t size)
89  
    std::size_t size)
90  
{
90  
{
91  
    system::error_code ec;
91  
    system::error_code ec;
92  
    auto const n = write_some(
92  
    auto const n = write_some(
93  
        data, size, ec);
93  
        data, size, ec);
94  
    if(ec)
94  
    if(ec)
95  
        detail::throw_system_error( ec );
95  
        detail::throw_system_error( ec );
96  
    return n;
96  
    return n;
97  
}
97  
}
98  

98  

99  
std::size_t
99  
std::size_t
100  
parser::
100  
parser::
101  
write(
101  
write(
102  
    char const* data,
102  
    char const* data,
103  
    std::size_t size,
103  
    std::size_t size,
104  
    system::error_code& ec)
104  
    system::error_code& ec)
105  
{
105  
{
106  
    auto const n = write_some(
106  
    auto const n = write_some(
107  
        data, size, ec);
107  
        data, size, ec);
108  
    if(! ec && n < size)
108  
    if(! ec && n < size)
109  
    {
109  
    {
110  
        BOOST_JSON_FAIL(ec, error::extra_data);
110  
        BOOST_JSON_FAIL(ec, error::extra_data);
111  
        p_.fail(ec);
111  
        p_.fail(ec);
112  
    }
112  
    }
113  
    return n;
113  
    return n;
114  
}
114  
}
115  

115  

116  
std::size_t
116  
std::size_t
117  
parser::
117  
parser::
118  
write(
118  
write(
119  
    char const* data,
119  
    char const* data,
120  
    std::size_t size,
120  
    std::size_t size,
121  
    std::error_code& ec)
121  
    std::error_code& ec)
122  
{
122  
{
123  
    system::error_code jec;
123  
    system::error_code jec;
124  
    std::size_t const result = write(data, size, jec);
124  
    std::size_t const result = write(data, size, jec);
125  
    ec = jec;
125  
    ec = jec;
126  
    return result;
126  
    return result;
127  
}
127  
}
128  

128  

129  
std::size_t
129  
std::size_t
130  
parser::
130  
parser::
131  
write(
131  
write(
132  
    char const* data,
132  
    char const* data,
133  
    std::size_t size)
133  
    std::size_t size)
134  
{
134  
{
135  
    system::error_code ec;
135  
    system::error_code ec;
136  
    auto const n = write(
136  
    auto const n = write(
137  
        data, size, ec);
137  
        data, size, ec);
138  
    if(ec)
138  
    if(ec)
139  
        detail::throw_system_error( ec );
139  
        detail::throw_system_error( ec );
140  
    return n;
140  
    return n;
141  
}
141  
}
142  

142  

143  
value
143  
value
144  
parser::
144  
parser::
145  
release()
145  
release()
146  
{
146  
{
147  
    if( ! p_.done())
147  
    if( ! p_.done())
148  
    {
148  
    {
149  
        // prevent undefined behavior
149  
        // prevent undefined behavior
150  
        if(! p_.last_error())
150  
        if(! p_.last_error())
151  
        {
151  
        {
152  
            system::error_code ec;
152  
            system::error_code ec;
153  
            BOOST_JSON_FAIL(ec, error::incomplete);
153  
            BOOST_JSON_FAIL(ec, error::incomplete);
154  
            p_.fail(ec);
154  
            p_.fail(ec);
155  
        }
155  
        }
156  
        detail::throw_system_error(
156  
        detail::throw_system_error(
157  
            p_.last_error());
157  
            p_.last_error());
158  
    }
158  
    }
159  
    return p_.handler().st.release();
159  
    return p_.handler().st.release();
160  
}
160  
}
161  

161  

162  
} // namespace json
162  
} // namespace json
163  
} // namespace boost
163  
} // namespace boost
164  

164  

165  
#endif
165  
#endif