2
0
mirror of https://github.com/boostorg/json.git synced 2026-01-31 08:12:25 +00:00
Files
json/test/doc_storage_ptr.cpp
2020-09-13 15:07:57 -07:00

233 lines
6.7 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/json
//
#include <boost/json/monotonic_resource.hpp>
#include <boost/json/parse.hpp>
#include <boost/json/static_resource.hpp>
#include <boost/json/storage_ptr.hpp>
#include <boost/json/value.hpp>
#include <iostream>
#include "test_suite.hpp"
BOOST_JSON_NS_BEGIN
//----------------------------------------------------------
static void set1() {
//----------------------------------------------------------
{
//[doc_storage_ptr_1
storage_ptr sp1;
storage_ptr sp2;
assert( sp1.get() != nullptr ); // always points to a valid resource
assert( sp1.get() == sp2.get() ); // both point to the default resource
assert( *sp1.get() == *sp2.get() ); // the default resource compares equal
//]
}
//----------------------------------------------------------
{
//[doc_storage_ptr_2
value jv;
array arr;
object obj;
assert( jv.storage().get() == storage_ptr().get() ); // uses the default memory resource
assert( jv.storage().get() == arr.storage().get() ); // both point to the default resource
assert( *arr.storage() == *obj.storage() ); // containers use equivalent resources
//]
}
//----------------------------------------------------------
{
//[doc_storage_ptr_3
monotonic_resource mr;
value const jv = parse( "[1,2,3]", &mr );
//]
}
//----------------------------------------------------------
} // set1
//----------------------------------------------------------
//[doc_storage_ptr_4
value parse_value( string_view s)
{
return parse( s, make_counted_resource< monotonic_resource >() );
}
//]
//----------------------------------------------------------
//[doc_storage_ptr_5
template< class Handler >
void do_rpc( string_view s, Handler&& h )
{
unsigned char buffer[ 8192 ]; // Small stack buffer to avoid most allocations during parse
monotonic_resource mr( buffer ); // This resource will use our local buffer first
value const jv = parse( s, &mr ); // Parse the input string into a value that uses our resource
h( jv ); // Call the handler to perform the RPC command
}
//]
//----------------------------------------------------------
void set2() {
//----------------------------------------------------------
{
//[doc_storage_ptr_6
unsigned char buffer[ 8192 ];
static_resource mr( buffer ); // The resource will use our local buffer
//]
}
//----------------------------------------------------------
{
//[doc_storage_ptr_7
monotonic_resource mr;
array arr( &mr ); // construct an array using our resource
arr.emplace_back( "boost" ); // insert a string
assert( *arr[0].as_string().storage() == mr ); // the resource is propagated to the string
//]
}
//----------------------------------------------------------
{
//[doc_storage_ptr_8
{
monotonic_resource mr;
array arr( &mr ); // construct an array using our resource
assert( ! arr.storage().is_counted() ); // no shared ownership
}
//]
}
//----------------------------------------------------------
{
//[doc_storage_ptr_9
storage_ptr sp = make_counted_resource< monotonic_resource >();
string str( sp );
assert( sp.is_counted() ); // shared ownership
assert( str.storage().is_counted() ); // shared ownership
//]
}
//----------------------------------------------------------
} // set2
//----------------------------------------------------------
//[doc_storage_ptr_10
class logging_resource : public memory_resource
{
private:
void* do_allocate( std::size_t bytes, std::size_t align ) override
{
std::cout << "Allocating " << bytes << " bytes with alignment " << align << '\n';
return ::operator new( bytes );
}
void do_deallocate( void* ptr, std::size_t bytes, std::size_t align ) override
{
std::cout << "Deallocating " << bytes << " bytes with alignment " << align << " @ address " << ptr << '\n';
return ::operator delete( ptr );
}
bool do_is_equal( memory_resource const& other ) const noexcept override
{
// since the global allocation and deallocation functions are used,
// any instance of a logging_resource can deallocate memory allocated
// by another instance of a logging_resource
return dynamic_cast< logging_resource const* >( &other ) != nullptr;
}
};
//]
//----------------------------------------------------------
#if 0
void do_rpc( string_view s )
{
// The parser will use this storage for its temporary needs
unsigned char temp[ 4000 ];
// The null resource guarantees we will never dynamically allocate
null_resource mr1;
// Construct a strict parser using the temp buffer and no dynamic memory
parser p( &mr1, parse_options(), temp );
// Now we need a buffer to hold the actual JSON values
unsigned char buf[ 6000 ];
// The static resource is monotonic, using only a caller-provided buffer
static_resource mr2( buf );
// We need to catch any exceptions thrown by the two memory resources
try
{
// This error code indicates errors not related to memory exhaustion
error_code ec;
// Parse the entire string we received from the network client
p.write( s, ec );
// Inform the parser that the complete input has been provided
if(! ec )
p.finish( ec );
if(! ec )
{
// Retrieve the value. It will use `buf` for storage.
value jv = p.release();
// At this point we can inspect jv and perform the requested RPC.
}
else
{
// An error occurred. A real program would report the error
// message back to the network client, indicating that the
// received JSON was invalid.
}
}
catch(std::bad_alloc const&)
{
// The memory needed to parse this JSON exceeded our statically
// define upper limits. A real program would send an error message
// back to the network client informing that their JSON is too large.
}
}
#endif
//----------------------------------------------------------
class doc_storage_ptr_test
{
public:
void
run()
{
(void)&set1;
BOOST_TEST_PASS();
}
};
TEST_SUITE(doc_storage_ptr_test, "boost.json.doc_storage_ptr");
BOOST_JSON_NS_END