sbuffer.hpp 3.0 KB

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