// // MessagePack for C++ simple buffer implementation // // Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi // // 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) // #ifndef MSGPACK_SBUFFER_HPP #define MSGPACK_SBUFFER_HPP #include "msgpack/versioning.hpp" #include #ifndef MSGPACK_SBUFFER_INIT_SIZE #define MSGPACK_SBUFFER_INIT_SIZE 8192 #endif namespace msgpack { /// @cond MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond class sbuffer { public: sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz) { if(initsz == 0) { m_data = nullptr; } else { m_data = (char*)::malloc(initsz); if(!m_data) { throw std::bad_alloc(); } } } ~sbuffer() { ::free(m_data); } #if !defined(MSGPACK_USE_CPP03) sbuffer(const sbuffer&) = delete; sbuffer& operator=(const sbuffer&) = delete; sbuffer(sbuffer&& other) : m_size(other.m_size), m_data(other.m_data), m_alloc(other.m_alloc) { other.m_size = other.m_alloc = 0; other.m_data = nullptr; } sbuffer& operator=(sbuffer&& other) { ::free(m_data); m_size = other.m_size; m_alloc = other.m_alloc; m_data = other.m_data; other.m_size = other.m_alloc = 0; other.m_data = nullptr; return *this; } #endif // !defined(MSGPACK_USE_CPP03) void write(const char* buf, size_t len) { if(m_alloc - m_size < len) { expand_buffer(len); } std::memcpy(m_data + m_size, buf, len); m_size += len; } char* data() { return m_data; } const char* data() const { return m_data; } size_t size() const { return m_size; } char* release() { char* tmp = m_data; m_size = 0; m_data = nullptr; m_alloc = 0; return tmp; } void clear() { m_size = 0; } private: void expand_buffer(size_t len) { size_t nsize = (m_alloc > 0) ? m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; while(nsize < m_size + len) { size_t tmp_nsize = nsize * 2; if (tmp_nsize <= nsize) { nsize = m_size + len; break; } nsize = tmp_nsize; } void* tmp = ::realloc(m_data, nsize); if(!tmp) { throw std::bad_alloc(); } m_data = static_cast(tmp); m_alloc = nsize; } #if defined(MSGPACK_USE_CPP03) private: sbuffer(const sbuffer&); sbuffer& operator=(const sbuffer&); #endif // defined(MSGPACK_USE_CPP03) private: size_t m_size; char* m_data; size_t m_alloc; }; /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond } // namespace msgpack #endif /* msgpack/sbuffer.hpp */