Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

100 строки
3.0 KiB

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