1 // 2 // MessagePack for C++ simple buffer implementation 3 // 4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // (See accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 // 10 #ifndef MSGPACK_V1_SBUFFER_HPP 11 #define MSGPACK_V1_SBUFFER_HPP 12 13 #include "rpc/msgpack/v1/sbuffer_decl.hpp" 14 15 #include <stdexcept> 16 #include <cstring> 17 18 namespace clmdep_msgpack { 19 20 /// @cond MSGPACK_API_VERSION_NAMESPACE(v1)21MSGPACK_API_VERSION_NAMESPACE(v1) { 22 /// @endcond 23 24 class sbuffer { 25 public: 26 sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz) 27 { 28 if(initsz == 0) { 29 m_data = MSGPACK_NULLPTR; 30 } else { 31 m_data = (char*)::malloc(initsz); 32 if(!m_data) { 33 throw std::bad_alloc(); 34 } 35 } 36 } 37 38 ~sbuffer() 39 { 40 ::free(m_data); 41 } 42 43 #if !defined(MSGPACK_USE_CPP03) 44 sbuffer(const sbuffer&) = delete; 45 sbuffer& operator=(const sbuffer&) = delete; 46 47 sbuffer(sbuffer&& other) : 48 m_size(other.m_size), m_data(other.m_data), m_alloc(other.m_alloc) 49 { 50 other.m_size = other.m_alloc = 0; 51 other.m_data = MSGPACK_NULLPTR; 52 } 53 54 sbuffer& operator=(sbuffer&& other) 55 { 56 ::free(m_data); 57 58 m_size = other.m_size; 59 m_alloc = other.m_alloc; 60 m_data = other.m_data; 61 62 other.m_size = other.m_alloc = 0; 63 other.m_data = MSGPACK_NULLPTR; 64 65 return *this; 66 } 67 #endif // !defined(MSGPACK_USE_CPP03) 68 69 void write(const char* buf, size_t len) 70 { 71 if(m_alloc - m_size < len) { 72 expand_buffer(len); 73 } 74 std::memcpy(m_data + m_size, buf, len); 75 m_size += len; 76 } 77 78 char* data() 79 { 80 return m_data; 81 } 82 83 const char* data() const 84 { 85 return m_data; 86 } 87 88 size_t size() const 89 { 90 return m_size; 91 } 92 93 char* release() 94 { 95 char* tmp = m_data; 96 m_size = 0; 97 m_data = MSGPACK_NULLPTR; 98 m_alloc = 0; 99 return tmp; 100 } 101 102 void clear() 103 { 104 m_size = 0; 105 } 106 107 private: 108 void expand_buffer(size_t len) 109 { 110 size_t nsize = (m_alloc > 0) ? 111 m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; 112 113 while(nsize < m_size + len) { 114 size_t tmp_nsize = nsize * 2; 115 if (tmp_nsize <= nsize) { 116 nsize = m_size + len; 117 break; 118 } 119 nsize = tmp_nsize; 120 } 121 122 void* tmp = ::realloc(m_data, nsize); 123 if(!tmp) { 124 throw std::bad_alloc(); 125 } 126 127 m_data = static_cast<char*>(tmp); 128 m_alloc = nsize; 129 } 130 131 #if defined(MSGPACK_USE_CPP03) 132 private: 133 sbuffer(const sbuffer&); 134 sbuffer& operator=(const sbuffer&); 135 #endif // defined(MSGPACK_USE_CPP03) 136 137 private: 138 size_t m_size; 139 char* m_data; 140 size_t m_alloc; 141 }; 142 143 /// @cond 144 } // MSGPACK_API_VERSION_NAMESPACE(v1) 145 /// @endcond 146 147 } // namespace clmdep_msgpack 148 149 #endif // MSGPACK_V1_SBUFFER_HPP 150