buffered.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #pragma once
  2. #include <library/cpp/yson_pull/detail/macros.h>
  3. #include <library/cpp/yson_pull/output.h>
  4. #include <util/generic/strbuf.h>
  5. namespace NYsonPull {
  6. namespace NDetail {
  7. namespace NOutput {
  8. template <typename T>
  9. class TBuffered: public NYsonPull::NOutput::IStream {
  10. TArrayHolder<ui8> buffer_;
  11. size_t size_;
  12. public:
  13. TBuffered(size_t buffer_size)
  14. : buffer_{new ui8[buffer_size]}
  15. , size_{buffer_size} {
  16. reset_buffer();
  17. }
  18. protected:
  19. void do_flush_buffer(TStringBuf extra) override {
  20. auto& buf = buffer();
  21. if (!buf.is_empty()) {
  22. do_write({reinterpret_cast<const char*>(buf.begin()), buf.used()});
  23. reset_buffer();
  24. }
  25. if (extra.size() >= buf.available()) {
  26. do_write(extra);
  27. } else if (extra.size() > 0) {
  28. ::memcpy(buf.pos(), extra.data(), extra.size());
  29. buf.advance(extra.size());
  30. }
  31. }
  32. private:
  33. void do_write(TStringBuf data) {
  34. // CRTP dispatch
  35. static_cast<T*>(this)->write(data);
  36. }
  37. void reset_buffer() {
  38. buffer().reset(buffer_.Get(), buffer_.Get() + size_);
  39. }
  40. };
  41. }
  42. } // namespace NDetail
  43. }