buffer.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "buffer.h"
  2. #include <util/generic/buffer.h>
  3. #include <util/generic/yexception.h>
  4. class TBufferOutput::TImpl {
  5. public:
  6. inline TImpl(TBuffer& buf)
  7. : Data_(buf)
  8. {
  9. }
  10. virtual ~TImpl() = default;
  11. inline size_t DoNext(void** ptr) {
  12. if (Data_.Avail() == 0) {
  13. Data_.Reserve(FastClp2(Data_.Capacity() + MinBufferGrowSize));
  14. }
  15. size_t previousSize = Data_.size();
  16. Data_.Resize(Data_.Capacity());
  17. *ptr = Data_.Begin() + previousSize;
  18. return Data_.Size() - previousSize;
  19. }
  20. inline void DoUndo(size_t len) {
  21. Y_VERIFY(len <= Data_.Size(), "trying to undo more bytes than actually written");
  22. Data_.Resize(Data_.size() - len);
  23. }
  24. inline void DoWrite(const void* buf, size_t len) {
  25. Data_.Append((const char*)buf, len);
  26. }
  27. inline void DoWriteC(char c) {
  28. Data_.Append(c);
  29. }
  30. inline TBuffer& Buffer() const noexcept {
  31. return Data_;
  32. }
  33. private:
  34. TBuffer& Data_;
  35. static constexpr size_t MinBufferGrowSize = 16;
  36. };
  37. namespace {
  38. using TImpl = TBufferOutput::TImpl;
  39. class TOwnedImpl: private TBuffer, public TImpl {
  40. public:
  41. inline TOwnedImpl(size_t buflen)
  42. : TBuffer(buflen)
  43. , TImpl(static_cast<TBuffer&>(*this))
  44. {
  45. }
  46. };
  47. }
  48. TBufferOutput::TBufferOutput(size_t buflen)
  49. : Impl_(new TOwnedImpl(buflen))
  50. {
  51. }
  52. TBufferOutput::TBufferOutput(TBuffer& buffer)
  53. : Impl_(new TImpl(buffer))
  54. {
  55. }
  56. TBufferOutput::TBufferOutput(TBufferOutput&&) noexcept = default;
  57. TBufferOutput& TBufferOutput::operator=(TBufferOutput&&) noexcept = default;
  58. TBufferOutput::~TBufferOutput() = default;
  59. TBuffer& TBufferOutput::Buffer() const noexcept {
  60. return Impl_->Buffer();
  61. }
  62. size_t TBufferOutput::DoNext(void** ptr) {
  63. return Impl_->DoNext(ptr);
  64. }
  65. void TBufferOutput::DoUndo(size_t len) {
  66. Impl_->DoUndo(len);
  67. }
  68. void TBufferOutput::DoWrite(const void* buf, size_t len) {
  69. Impl_->DoWrite(buf, len);
  70. }
  71. void TBufferOutput::DoWriteC(char c) {
  72. Impl_->DoWriteC(c);
  73. }
  74. TBufferInput::TBufferInput(const TBuffer& buffer)
  75. : Buf_(buffer)
  76. , Readed_(0)
  77. {
  78. }
  79. TBufferInput::~TBufferInput() = default;
  80. const TBuffer& TBufferInput::Buffer() const noexcept {
  81. return Buf_;
  82. }
  83. void TBufferInput::Rewind() noexcept {
  84. Readed_ = 0;
  85. }
  86. size_t TBufferInput::DoNext(const void** ptr, size_t len) {
  87. len = Min(Buf_.Size() - Readed_, len);
  88. *ptr = Buf_.data() + Readed_;
  89. Readed_ += len;
  90. return len;
  91. }
  92. void TBufferInput::DoUndo(size_t len) {
  93. Y_VERIFY(len <= Readed_);
  94. Readed_ -= len;
  95. }