Skip to content

Commit

Permalink
caller provided serializer storage
Browse files Browse the repository at this point in the history
  • Loading branch information
vinniefalco authored and grisumbras committed Jan 27, 2023
1 parent d7b7bef commit c06b17a
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 25 deletions.
29 changes: 21 additions & 8 deletions include/boost/json/detail/impl/stack.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@ namespace detail {
stack::
~stack()
{
if(buf_)
if(base_ != buf_)
sp_->deallocate(
buf_, cap_);
base_, cap_);
}

stack::
stack(
storage_ptr sp,
unsigned char* buf,
std::size_t buf_size) noexcept
: sp_(std::move(sp))
, cap_(buf_size)
, base_(buf)
, buf_(buf)
{
}

void
Expand All @@ -30,15 +42,16 @@ reserve(std::size_t n)
{
if(cap_ >= n)
return;
auto const buf = static_cast<
char*>(sp_->allocate(n));
if(buf_)
auto const base = static_cast<
unsigned char*>(sp_->allocate(n));
if(base_)
{
if(size_ > 0)
std::memcpy(buf, buf_, size_);
sp_->deallocate(buf_, cap_);
std::memcpy(base, base_, size_);
if(base_ != buf_)
sp_->deallocate(base_, cap_);
}
buf_ = buf;
base_ = base;
cap_ = n;
}

Expand Down
18 changes: 13 additions & 5 deletions include/boost/json/detail/stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,20 @@ class stack
storage_ptr sp_;
std::size_t cap_ = 0;
std::size_t size_ = 0;
char* buf_ = nullptr;
unsigned char* base_ = nullptr;
unsigned char* buf_ = nullptr;

public:
BOOST_JSON_DECL
~stack();

stack() = default;

stack(
storage_ptr sp,
unsigned char* buf,
std::size_t buf_size) noexcept;

bool
empty() const noexcept
{
Expand Down Expand Up @@ -57,7 +65,7 @@ class stack
//BOOST_ASSERT(cap_ >= size_ + n);
reserve(size_ + n);
std::memcpy(
buf_ + size_, &t, n);
base_ + size_, &t, n);
size_ += n;
}

Expand All @@ -68,7 +76,7 @@ class stack
auto const n = sizeof(T);
BOOST_ASSERT(size_ + n <= cap_);
std::memcpy(
buf_ + size_, &t, n);
base_ + size_, &t, n);
size_ += n;
}

Expand All @@ -79,7 +87,7 @@ class stack
auto const n = sizeof(T);
BOOST_ASSERT(size_ >= n);
std::memcpy(&t,
buf_ + size_ - n, n);
base_ + size_ - n, n);
}

template<class T>
Expand All @@ -90,7 +98,7 @@ class stack
BOOST_ASSERT(size_ >= n);
size_ -= n;
std::memcpy(
&t, buf_ + size_, n);
&t, base_ + size_, n);
}
};

Expand Down
32 changes: 22 additions & 10 deletions include/boost/json/impl/serialize.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ std::string
serialize(
value const& jv)
{
std::string s;
serializer sr;
unsigned char buf[256];
serializer sr(
storage_ptr(),
buf,
sizeof(buf));
sr.reset(&jv);
std::string s;
serialize_impl(s, sr);
return s;
}
Expand All @@ -76,8 +80,12 @@ std::string
serialize(
array const& arr)
{
unsigned char buf[256];
serializer sr(
storage_ptr(),
buf,
sizeof(buf));
std::string s;
serializer sr;
sr.reset(&arr);
serialize_impl(s, sr);
return s;
Expand All @@ -87,8 +95,12 @@ std::string
serialize(
object const& obj)
{
unsigned char buf[256];
serializer sr(
storage_ptr(),
buf,
sizeof(buf));
std::string s;
serializer sr;
sr.reset(&obj);
serialize_impl(s, sr);
return s;
Expand All @@ -98,20 +110,20 @@ std::string
serialize(
string const& str)
{
std::string s;
serializer sr;
sr.reset(&str);
serialize_impl(s, sr);
return s;
return serialize( str.subview() );
}

// this is here for key_value_pair::key()
std::string
serialize(
string_view sv)
{
unsigned char buf[256];
serializer sr(
storage_ptr(),
buf,
sizeof(buf));
std::string s;
serializer sr;
sr.reset(sv);
serialize_impl(s, sr);
return s;
Expand Down
12 changes: 12 additions & 0 deletions include/boost/json/impl/serializer.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ enum class serializer::state : char
serializer::
~serializer() noexcept = default;

serializer::
serializer(
storage_ptr sp,
unsigned char* buf,
std::size_t buf_size) noexcept
: st_(
std::move(sp),
buf,
buf_size)
{
}

bool
serializer::
suspend(state st)
Expand Down
34 changes: 33 additions & 1 deletion include/boost/json/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class serializer
BOOST_JSON_DECL
~serializer() noexcept;

/** Default constructor
/** Constructor
This constructs a serializer with no value.
The value may be set later by calling @ref reset.
Expand All @@ -130,6 +130,38 @@ class serializer
BOOST_JSON_DECL
serializer() noexcept;

/** Constructor
This constructs a serializer with no value.
The value may be set later by calling @ref reset.
If serialization is attempted with no value,
the output is as if a null value is serialized.
@par Complexity
Constant.
@par Exception Safety
No-throw guarantee.
@param sp A pointer to the @ref memory_resource
to use when producing partial output.
Shared ownership of the memory resource
is retained until the serializer is
destroyed.
@param buf An optional static buffer to
use for temporary storage when producing
partial output.
@param buf_size The number of bytes of
valid memory pointed to by `buf`.
*/
BOOST_JSON_DECL
serializer(
storage_ptr sp,
unsigned char* buf = nullptr,
std::size_t buf_size = 0) noexcept;

/** Returns `true` if the serialization is complete
This function returns `true` when all of the
Expand Down
50 changes: 49 additions & 1 deletion test/serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
// Test that header file is self-contained.
#include <boost/json/serializer.hpp>

#include <boost/json/parse.hpp>
#include <boost/json/serialize.hpp>
#include <boost/json/null_resource.hpp>
#include <boost/json/parse.hpp>
#include <boost/json/parse.hpp>
#include <iostream>

#include "parse-vectors.hpp"
Expand Down Expand Up @@ -368,6 +370,52 @@ class serializer_test
BOOST_TEST(sr.read(buf) == "null");
}

// serializer(storage_ptr)
{
{
serializer sr((storage_ptr()));
char buf[32];
BOOST_TEST(sr.read(buf) == "null");
}
{
serializer sr(get_null_resource());
char buf[1];
BOOST_TEST_THROWS(
sr.read(buf),
std::exception);
}
}

// serializer(storage_ptr, unsigned char*, size_t)
{
{
unsigned char temp[256];
serializer sr(
get_null_resource(),
temp,
sizeof(temp));
char buf[32];
BOOST_TEST(sr.read(&buf[0], 1) == "n");
BOOST_TEST(sr.read(&buf[1], 2) == "ul");
BOOST_TEST(sr.read(&buf[3], 1) == "l");
BOOST_TEST(
std::memcmp(buf, "null", 4) == 0);
}
{
unsigned char temp[1];
serializer sr(
get_null_resource(),
temp,
sizeof(temp));
array ar({1, 2, 3});
sr.reset(&ar);
char buf[32];
BOOST_TEST_THROWS(
sr.read(&buf[0], 1),
std::exception);
}
}

// done()
{
value jv = 1;
Expand Down

0 comments on commit c06b17a

Please sign in to comment.