block_io_buffer.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #pragma once
  2. #include <util/generic/strbuf.h>
  3. #include <util/generic/vector.h>
  4. #include <util/system/unaligned_mem.h>
  5. namespace NYql {
  6. namespace NUdf {
  7. class TInputBuffer {
  8. public:
  9. TInputBuffer(TStringBuf buf)
  10. : Buf_(buf)
  11. {}
  12. char PopChar() {
  13. Ensure(1);
  14. char c = Buf_.data()[Pos_];
  15. ++Pos_;
  16. return c;
  17. }
  18. template <typename T>
  19. T PopNumber() {
  20. Ensure(sizeof(T));
  21. T t = ReadUnaligned<T>(Buf_.data() + Pos_);
  22. Pos_ += sizeof(T);
  23. return t;
  24. }
  25. std::string_view PopString() {
  26. ui32 size = PopNumber<ui32>();
  27. Ensure(size);
  28. std::string_view result(Buf_.data() + Pos_, size);
  29. Pos_ += size;
  30. return result;
  31. }
  32. private:
  33. void Ensure(size_t delta) {
  34. Y_ENSURE(Pos_ + delta <= Buf_.size(), "Unexpected end of buffer");
  35. }
  36. private:
  37. size_t Pos_ = 0;
  38. TStringBuf Buf_;
  39. };
  40. class TOutputBuffer {
  41. public:
  42. void PushChar(char c) {
  43. Ensure(1);
  44. Vec_[Pos_] = c;
  45. ++Pos_;
  46. }
  47. template <typename T>
  48. void PushNumber(T t) {
  49. Ensure(sizeof(T));
  50. WriteUnaligned<T>(Vec_.data() + Pos_, t);
  51. Pos_ += sizeof(T);
  52. }
  53. void PushString(std::string_view data) {
  54. Ensure(sizeof(ui32) + data.size());
  55. *(ui32*)&Vec_[Pos_] = data.size();
  56. Pos_ += sizeof(ui32);
  57. std::memcpy(Vec_.data() + Pos_, data.data(), data.size());
  58. Pos_ += data.size();
  59. }
  60. // fill with zeros
  61. void Resize(size_t size) {
  62. Pos_ = 0;
  63. Vec_.clear();
  64. Vec_.resize(size);
  65. }
  66. void Rewind() {
  67. Pos_ = 0;
  68. }
  69. TStringBuf Finish() const {
  70. return TStringBuf(Vec_.data(), Vec_.data() + Pos_);
  71. }
  72. private:
  73. void Ensure(size_t delta) {
  74. if (Pos_ + delta > Vec_.size()) {
  75. if (Pos_ + delta > Vec_.capacity()) {
  76. Vec_.reserve(Max(2 * Vec_.capacity(), Pos_ + delta));
  77. }
  78. // TODO: replace TVector - resize() performs unneeded zeroing here
  79. Vec_.resize(Pos_ + delta);
  80. }
  81. }
  82. private:
  83. size_t Pos_ = 0;
  84. TVector<char> Vec_;
  85. };
  86. }
  87. }