sbuffer.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #include "msgpack/v1/cpp_config_decl.hpp"
  13. #include "msgpack/v1/sbuffer_decl.hpp"
  14. #include "msgpack/assert.hpp"
  15. #include <stdexcept>
  16. #include <cstring>
  17. namespace msgpack {
  18. /// @cond
  19. MSGPACK_API_VERSION_NAMESPACE(v1) {
  20. /// @endcond
  21. class sbuffer {
  22. public:
  23. sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz)
  24. {
  25. if(initsz == 0) {
  26. m_data = MSGPACK_NULLPTR;
  27. } else {
  28. m_data = (char*)::malloc(initsz);
  29. if(!m_data) {
  30. throw std::bad_alloc();
  31. }
  32. }
  33. }
  34. ~sbuffer()
  35. {
  36. ::free(m_data);
  37. }
  38. #if !defined(MSGPACK_USE_CPP03)
  39. sbuffer(const sbuffer&) = delete;
  40. sbuffer& operator=(const sbuffer&) = delete;
  41. sbuffer(sbuffer&& other) :
  42. m_size(other.m_size), m_data(other.m_data), m_alloc(other.m_alloc)
  43. {
  44. other.m_size = other.m_alloc = 0;
  45. other.m_data = MSGPACK_NULLPTR;
  46. }
  47. sbuffer& operator=(sbuffer&& other)
  48. {
  49. ::free(m_data);
  50. m_size = other.m_size;
  51. m_alloc = other.m_alloc;
  52. m_data = other.m_data;
  53. other.m_size = other.m_alloc = 0;
  54. other.m_data = MSGPACK_NULLPTR;
  55. return *this;
  56. }
  57. #endif // !defined(MSGPACK_USE_CPP03)
  58. void write(const char* buf, size_t len)
  59. {
  60. MSGPACK_ASSERT(buf || len == 0);
  61. if (!buf) return;
  62. if(m_alloc - m_size < len) {
  63. expand_buffer(len);
  64. }
  65. std::memcpy(m_data + m_size, buf, len);
  66. m_size += len;
  67. }
  68. char* data()
  69. {
  70. return m_data;
  71. }
  72. const char* data() const
  73. {
  74. return m_data;
  75. }
  76. size_t size() const
  77. {
  78. return m_size;
  79. }
  80. char* release()
  81. {
  82. char* tmp = m_data;
  83. m_size = 0;
  84. m_data = MSGPACK_NULLPTR;
  85. m_alloc = 0;
  86. return tmp;
  87. }
  88. void clear()
  89. {
  90. m_size = 0;
  91. }
  92. private:
  93. void expand_buffer(size_t len)
  94. {
  95. size_t nsize = (m_alloc > 0) ?
  96. m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
  97. while(nsize < m_size + len) {
  98. size_t tmp_nsize = nsize * 2;
  99. if (tmp_nsize <= nsize) {
  100. nsize = m_size + len;
  101. break;
  102. }
  103. nsize = tmp_nsize;
  104. }
  105. void* tmp = ::realloc(m_data, nsize);
  106. if(!tmp) {
  107. throw std::bad_alloc();
  108. }
  109. m_data = static_cast<char*>(tmp);
  110. m_alloc = nsize;
  111. }
  112. #if defined(MSGPACK_USE_CPP03)
  113. private:
  114. sbuffer(const sbuffer&);
  115. sbuffer& operator=(const sbuffer&);
  116. #endif // defined(MSGPACK_USE_CPP03)
  117. private:
  118. size_t m_size;
  119. char* m_data;
  120. size_t m_alloc;
  121. };
  122. /// @cond
  123. } // MSGPACK_API_VERSION_NAMESPACE(v1)
  124. /// @endcond
  125. } // namespace msgpack
  126. #endif // MSGPACK_V1_SBUFFER_HPP