buffer.cpp 2.5 KB

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