You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

98 line
2.9 KiB

  1. #pragma once
  2. #include "vector_streambuf.h"
  3. namespace cppcore
  4. {
  5. template<typename T_data, typename T_char>
  6. basic_vector_streambuf<T_data, T_char>
  7. ::basic_vector_streambuf(size_t p_grow)
  8. : _buffer ()
  9. , _grow (p_grow)
  10. { }
  11. template<typename T_data, typename T_char>
  12. typename basic_vector_streambuf<T_data, T_char>::vector_type
  13. basic_vector_streambuf<T_data, T_char>
  14. ::get() const
  15. {
  16. auto vec = _buffer;
  17. vec.resize(static_cast<size_t>(this->pptr() - this->pbase()));
  18. return vec;
  19. }
  20. template<typename T_data, typename T_char>
  21. template<typename T_vector>
  22. void basic_vector_streambuf<T_data, T_char>
  23. ::set(T_vector&& v)
  24. {
  25. _buffer = std::forward<T_vector>(v);
  26. auto beg = reinterpret_cast<char_type*>(&_buffer.front());
  27. auto end = beg + _buffer.size();
  28. this->setp(beg, end);
  29. this->setg(beg, beg, end);
  30. }
  31. template<typename T_data, typename T_char>
  32. typename basic_vector_streambuf<T_data, T_char>::vector_type
  33. basic_vector_streambuf<T_data, T_char>
  34. ::extract()
  35. {
  36. _buffer.resize(static_cast<size_t>(this->pptr() - this->pbase()));
  37. auto ret = std::move(_buffer);
  38. this->setp(nullptr, nullptr);
  39. this->setg(nullptr, nullptr, nullptr);
  40. return ret;
  41. }
  42. template<typename T_data, typename T_char>
  43. typename basic_vector_streambuf<T_data, T_char>::int_type
  44. basic_vector_streambuf<T_data, T_char>
  45. ::underflow()
  46. {
  47. auto gpos = static_cast<size_t>(this->gptr() - this->eback());
  48. this->setg(this->pbase(), this->pbase() + gpos, this->pptr());
  49. if (this->gptr() == this->pptr())
  50. return traits_type::eof();
  51. auto ret = static_cast<int_type>(*this->gptr());
  52. return ret;
  53. }
  54. template<typename T_data, typename T_char>
  55. typename basic_vector_streambuf<T_data, T_char>::int_type
  56. basic_vector_streambuf<T_data, T_char>
  57. ::overflow(int_type ch)
  58. {
  59. if (ch != traits_type::eof())
  60. {
  61. size_t new_cap;
  62. if (_grow > 0)
  63. {
  64. new_cap = _buffer.size() + _grow;
  65. }
  66. else
  67. {
  68. new_cap = std::min(max_grow, std::max(2 * _buffer.size(), min_grow));
  69. }
  70. _buffer.resize(new_cap);
  71. auto beg = reinterpret_cast<char_type*>(&_buffer.front());
  72. auto end = beg + _buffer.size();
  73. auto ppos = static_cast<int>(this->pptr() - this->pbase());
  74. auto gpos = static_cast<size_t>(this->gptr() - this->eback());
  75. this->setp(beg, end);
  76. this->setg(beg, beg + gpos, beg + ppos);
  77. this->pbump(ppos);
  78. auto p = this->pptr();
  79. assert(this->pbase() <= p && p < this->epptr());
  80. *p = static_cast<char_type>(ch);
  81. this->pbump(1);
  82. }
  83. return ch;
  84. }
  85. }