diff --git a/include/boost/json/detail/sbo_buffer.hpp b/include/boost/json/detail/sbo_buffer.hpp index 78c95be7d..7b059859c 100644 --- a/include/boost/json/detail/sbo_buffer.hpp +++ b/include/boost/json/detail/sbo_buffer.hpp @@ -151,6 +151,9 @@ class sbo_buffer } std::size_t const old_capacity = this->capacity(); + if( size <= old_capacity - size_ ) + return; + std::size_t new_capacity = size_ + size; // growth factor 2 diff --git a/test/Jamfile b/test/Jamfile index b15678386..a90246439 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -37,6 +37,7 @@ local SOURCES = pilfer.cpp pointer.cpp result_for.cpp + sbo_buffer.cpp serialize.cpp serializer.cpp snippets.cpp diff --git a/test/sbo_buffer.cpp b/test/sbo_buffer.cpp new file mode 100644 index 000000000..7e164a3a7 --- /dev/null +++ b/test/sbo_buffer.cpp @@ -0,0 +1,91 @@ +// +// Copyright (c) 2026 Ramya Eliger (ramya@digiscrypt.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include +#include + +#include + +#include "test_suite.hpp" + +namespace boost { +namespace json { + +class sbo_buffer_test +{ +public: + void + testInlineStorage() + { + detail::sbo_buffer<32> buf; + std::size_t const cap = buf.capacity(); + BOOST_TEST(cap >= 32); + + char const* p = buf.append("1.2", 3); + BOOST_TEST(buf.size() == 3); + BOOST_TEST(string_view(p, buf.size()) == "1.2"); + BOOST_TEST(buf.capacity() == cap); + + p = buf.append("5e10", 4); + BOOST_TEST(buf.size() == 7); + BOOST_TEST(string_view(p, buf.size()) == "1.25e10"); + BOOST_TEST(buf.capacity() == cap); + } + + void + testReuse() + { + detail::sbo_buffer<32> buf; + std::size_t const cap = buf.capacity(); + for(int i = 0; i < 40; ++i) + { + buf.clear(); + char const* p = buf.append("1.25", 4); + BOOST_TEST(buf.size() == 4); + BOOST_TEST(string_view(p, buf.size()) == "1.25"); + } + BOOST_TEST(buf.capacity() == cap); + } + + void + testGrowth() + { + detail::sbo_buffer<32> buf; + std::string const s(1000, 'x'); + + char const* p = buf.append(s.data(), s.size()); + BOOST_TEST(buf.size() == s.size()); + BOOST_TEST(buf.capacity() >= s.size()); + BOOST_TEST(string_view(p, buf.size()) == s); + + std::size_t const cap = buf.capacity(); + buf.clear(); + p = buf.append("1.25", 4); + BOOST_TEST(buf.size() == 4); + BOOST_TEST(string_view(p, buf.size()) == "1.25"); + BOOST_TEST(buf.capacity() == cap); + + buf.reset(); + BOOST_TEST(buf.size() == 0); + BOOST_TEST(buf.capacity() == 32); + } + + void + run() + { + testInlineStorage(); + testReuse(); + testGrowth(); + } +}; + +TEST_SUITE(sbo_buffer_test, "boost.json.sbo_buffer"); + +} // namespace json +} // namespace boost