Skip to content

Commit 2b2ffda

Browse files
vinniefalcogrisumbras
authored andcommitted
caller provided serializer storage
1 parent ada7711 commit 2b2ffda

File tree

13 files changed

+1002
-744
lines changed

13 files changed

+1002
-744
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// Copyright (c) 2019 Vinnie Falco ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/boostorg/json
8+
//
9+
10+
#ifndef BOOST_JSON_DETAIL_IMPL_SERIALIZE_IPP
11+
#define BOOST_JSON_DETAIL_IMPL_SERIALIZE_IPP
12+
13+
#include <boost/json/detail/serialize.hpp>
14+
15+
namespace boost {
16+
namespace json {
17+
namespace detail {
18+
19+
void
20+
serialize_impl(
21+
std::string& s,
22+
serializer& sr)
23+
{
24+
// serialize to a small buffer to avoid
25+
// the first few allocations in std::string
26+
char buf[BOOST_JSON_STACK_BUFFER_SIZE];
27+
string_view sv;
28+
sv = sr.read(buf);
29+
if(sr.done())
30+
{
31+
// fast path
32+
s.append(
33+
sv.data(), sv.size());
34+
return;
35+
}
36+
std::size_t len = sv.size();
37+
s.reserve(len * 2);
38+
s.resize(s.capacity());
39+
BOOST_ASSERT(
40+
s.size() >= len * 2);
41+
std::memcpy(&s[0],
42+
sv.data(), sv.size());
43+
auto const lim =
44+
s.max_size() / 2;
45+
for(;;)
46+
{
47+
sv = sr.read(
48+
&s[0] + len,
49+
s.size() - len);
50+
len += sv.size();
51+
if(sr.done())
52+
break;
53+
// growth factor 2x
54+
if(s.size() < lim)
55+
s.resize(s.size() * 2);
56+
else
57+
s.resize(2 * lim);
58+
}
59+
s.resize(len);
60+
}
61+
62+
} // detail
63+
} // json
64+
} // boost
65+
66+
#endif
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Copyright (c) 2019 Vinnie Falco ([email protected])
3+
// Copyright (c) 2020 Krystian Stasiowski ([email protected])
4+
//
5+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
// file LICENSE_1_0.txt or copy at http://wwboost.org/LICENSE_1_0.txt)
7+
//
8+
// Official repository: https://github.com/boostorg/json
9+
//
10+
11+
#ifndef BOOST_JSON_DETAIL_IMPL_WRITER_IPP
12+
#define BOOST_JSON_DETAIL_IMPL_WRITER_IPP
13+
14+
#include <boost/json/detail/writer.hpp>
15+
#include <boost/json/detail/sse2.hpp>
16+
#include <boost/json/detail/format.hpp> // for max_number_chars
17+
#include <boost/static_assert.hpp>
18+
19+
namespace boost {
20+
namespace json {
21+
namespace detail {
22+
23+
} // detail
24+
} // json
25+
} // boost
26+
27+
#endif
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// Copyright (c) 2019 Vinnie Falco ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/boostorg/json
8+
//
9+
10+
#ifndef BOOST_JSON_DETAIL_SERIALIZE_HPP
11+
#define BOOST_JSON_DETAIL_SERIALIZE_HPP
12+
13+
#include <boost/json/serializer.hpp>
14+
#include <string>
15+
16+
namespace boost {
17+
namespace json {
18+
namespace detail {
19+
20+
BOOST_JSON_DECL
21+
void
22+
serialize_impl(
23+
std::string& s,
24+
serializer& sr);
25+
26+
} // detail
27+
} // json
28+
} // boost
29+
30+
#endif

include/boost/json/detail/stream.hpp

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -234,112 +234,6 @@ class clipped_const_stream
234234
}
235235
};
236236

237-
//--------------------------------------
238-
239-
class stream
240-
{
241-
friend class local_stream;
242-
243-
char* p_;
244-
char* end_;
245-
246-
public:
247-
stream(
248-
char* data,
249-
std::size_t size) noexcept
250-
: p_(data)
251-
, end_(data + size)
252-
{
253-
}
254-
255-
size_t
256-
used(char* begin) const noexcept
257-
{
258-
return static_cast<
259-
size_t>(p_ - begin);
260-
}
261-
262-
size_t
263-
remain() const noexcept
264-
{
265-
return end_ - p_;
266-
}
267-
268-
char*
269-
data() noexcept
270-
{
271-
return p_;
272-
}
273-
274-
operator bool() const noexcept
275-
{
276-
return p_ < end_;
277-
}
278-
279-
// unchecked
280-
char&
281-
operator*() noexcept
282-
{
283-
BOOST_ASSERT(p_ < end_);
284-
return *p_;
285-
}
286-
287-
// unchecked
288-
stream&
289-
operator++() noexcept
290-
{
291-
BOOST_ASSERT(p_ < end_);
292-
++p_;
293-
return *this;
294-
}
295-
296-
// unchecked
297-
void
298-
append(
299-
char const* src,
300-
std::size_t n) noexcept
301-
{
302-
BOOST_ASSERT(remain() >= n);
303-
std::memcpy(p_, src, n);
304-
p_ += n;
305-
}
306-
307-
// unchecked
308-
void
309-
append(char c) noexcept
310-
{
311-
BOOST_ASSERT(p_ < end_);
312-
*p_++ = c;
313-
}
314-
315-
void
316-
advance(std::size_t n) noexcept
317-
{
318-
BOOST_ASSERT(remain() >= n);
319-
p_ += n;
320-
}
321-
};
322-
323-
class local_stream
324-
: public stream
325-
{
326-
stream& src_;
327-
328-
public:
329-
explicit
330-
local_stream(
331-
stream& src)
332-
: stream(src)
333-
, src_(src)
334-
{
335-
}
336-
337-
~local_stream()
338-
{
339-
src_.p_ = p_;
340-
}
341-
};
342-
343237
} // detail
344238
} // namespace json
345239
} // namespace boost
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//
2+
// Copyright (c) 2019 Vinnie Falco ([email protected])
3+
// Copyright (c) 2020 Krystian Stasiowski ([email protected])
4+
//
5+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7+
//
8+
// Official repository: https://github.com/boostorg/json
9+
//
10+
11+
#ifndef BOOST_JSON_DETAIL_WRITER_HPP
12+
#define BOOST_JSON_DETAIL_WRITER_HPP
13+
14+
#include <boost/json/detail/stack.hpp>
15+
#include <boost/json/serialize_options.hpp>
16+
#include <boost/json/string_view.hpp>
17+
18+
namespace boost {
19+
namespace json {
20+
namespace detail {
21+
22+
struct writer
23+
{
24+
char* dest_;
25+
char const* end_;
26+
27+
public:
28+
using resume_fn = bool(*)(writer&, serialize_options const&);
29+
30+
detail::stack stack;
31+
char temp_[29];
32+
33+
writer() = default;
34+
35+
writer(
36+
storage_ptr sp,
37+
unsigned char* buf,
38+
std::size_t buf_size) noexcept
39+
: stack(
40+
std::move(sp),
41+
buf,
42+
buf_size)
43+
{
44+
}
45+
46+
char*
47+
data() noexcept
48+
{
49+
return dest_;
50+
}
51+
52+
// provide an output buffer
53+
void
54+
prepare(
55+
char* dest,
56+
std::size_t size)
57+
{
58+
dest_ = dest;
59+
end_ = dest + size;
60+
}
61+
62+
// return true if there is no space
63+
bool
64+
empty() const noexcept
65+
{
66+
return dest_ == end_;
67+
}
68+
69+
// return the amount of space available
70+
std::size_t
71+
available() const noexcept
72+
{
73+
return static_cast<
74+
std::size_t>(end_ - dest_);
75+
}
76+
77+
// return true if there is space
78+
bool
79+
append(char c) noexcept
80+
{
81+
if(! empty())
82+
{
83+
*dest_++ = c;
84+
return true;
85+
}
86+
return false;
87+
}
88+
89+
// append one char
90+
void
91+
append_unsafe(
92+
char c) noexcept
93+
{
94+
BOOST_ASSERT(! empty());
95+
*dest_++ = c;
96+
}
97+
98+
// append chars in s, unchecked
99+
void
100+
append_unsafe(
101+
char const* s,
102+
std::size_t n) noexcept
103+
{
104+
BOOST_ASSERT(available() >= n);
105+
std::memcpy(dest_, s, n);
106+
dest_ += n;
107+
}
108+
109+
// push a resume function
110+
void
111+
push_resume(resume_fn fn)
112+
{
113+
stack.push(fn);
114+
}
115+
116+
// pop and invoke a resume function
117+
// or return true if stack is empty
118+
bool
119+
do_resume(serialize_options const& opts)
120+
{
121+
if(! stack.empty())
122+
{
123+
resume_fn fn;
124+
stack.pop(fn);
125+
return fn(*this, opts);
126+
}
127+
return true;
128+
}
129+
};
130+
131+
} // detail
132+
} // json
133+
} // boost
134+
135+
#endif

0 commit comments

Comments
 (0)