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_STREAM_PARSER_IPP
10  
#ifndef BOOST_JSON_IMPL_STREAM_PARSER_IPP
11  
#define BOOST_JSON_IMPL_STREAM_PARSER_IPP
11  
#define BOOST_JSON_IMPL_STREAM_PARSER_IPP
12  

12  

13  
#include <boost/json/stream_parser.hpp>
13  
#include <boost/json/stream_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  
stream_parser::
23  
stream_parser::
24  
stream_parser(
24  
stream_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  
stream_parser::
38  
stream_parser::
39  
stream_parser(
39  
stream_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  
stream_parser::
52  
stream_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  
stream_parser::
60  
stream_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  
    return p_.write_some(
66  
    return p_.write_some(
67  
        true, data, size, ec);
67  
        true, data, size, ec);
68  
}
68  
}
69  

69  

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

82  

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

96  

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

113  

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

126  

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

140  

141  
void
141  
void
142  
stream_parser::
142  
stream_parser::
143  
finish(system::error_code& ec)
143  
finish(system::error_code& ec)
144  
{
144  
{
145  
    p_.write_some(false, nullptr, 0, ec);
145  
    p_.write_some(false, nullptr, 0, ec);
146  
}
146  
}
147  

147  

148  
void
148  
void
149  
stream_parser::
149  
stream_parser::
150  
finish()
150  
finish()
151  
{
151  
{
152  
    system::error_code ec;
152  
    system::error_code ec;
153  
    finish(ec);
153  
    finish(ec);
154  
    if(ec)
154  
    if(ec)
155  
        detail::throw_system_error( ec );
155  
        detail::throw_system_error( ec );
156  
}
156  
}
157  

157  

158  
void
158  
void
159  
stream_parser::
159  
stream_parser::
160  
finish(std::error_code& ec)
160  
finish(std::error_code& ec)
161  
{
161  
{
162  
    system::error_code jec;
162  
    system::error_code jec;
163  
    finish(jec);
163  
    finish(jec);
164  
    ec = jec;
164  
    ec = jec;
165  
}
165  
}
166  

166  

167  
value
167  
value
168  
stream_parser::
168  
stream_parser::
169  
release()
169  
release()
170  
{
170  
{
171  
    if(! p_.done())
171  
    if(! p_.done())
172  
    {
172  
    {
173  
        // prevent undefined behavior
173  
        // prevent undefined behavior
174  
        finish();
174  
        finish();
175  
    }
175  
    }
176  
    return p_.handler().st.release();
176  
    return p_.handler().st.release();
177  
}
177  
}
178  

178  

179  
} // namespace json
179  
} // namespace json
180  
} // namespace boost
180  
} // namespace boost
181  

181  

182  
#endif
182  
#endif