block_io_buffer.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. void PopNumber(T& result) {
  20. result = PopNumber<T>();
  21. }
  22. template <typename T>
  23. T PopNumber() {
  24. Ensure(sizeof(T));
  25. T t = ReadUnaligned<T>(Buf_.data() + Pos_);
  26. Pos_ += sizeof(T);
  27. return t;
  28. }
  29. std::string_view PopString() {
  30. ui32 size = PopNumber<ui32>();
  31. Ensure(size);
  32. std::string_view result(Buf_.data() + Pos_, size);
  33. Pos_ += size;
  34. return result;
  35. }
  36. private:
  37. void Ensure(size_t delta) {
  38. Y_ENSURE(Pos_ + delta <= Buf_.size(), "Unexpected end of buffer");
  39. }
  40. private:
  41. size_t Pos_ = 0;
  42. TStringBuf Buf_;
  43. };
  44. class TOutputBuffer {
  45. public:
  46. void PushChar(char c) {
  47. Ensure(1);
  48. Vec_[Pos_] = c;
  49. ++Pos_;
  50. }
  51. template <typename T>
  52. void PushNumber(T t) {
  53. Ensure(sizeof(T));
  54. WriteUnaligned<T>(Vec_.data() + Pos_, t);
  55. Pos_ += sizeof(T);
  56. }
  57. void PushString(std::string_view data) {
  58. Ensure(sizeof(ui32) + data.size());
  59. *(ui32*)&Vec_[Pos_] = data.size();
  60. Pos_ += sizeof(ui32);
  61. std::memcpy(Vec_.data() + Pos_, data.data(), data.size());
  62. Pos_ += data.size();
  63. }
  64. // fill with zeros
  65. void Resize(size_t size) {
  66. Pos_ = 0;
  67. Vec_.clear();
  68. Vec_.resize(size);
  69. }
  70. void Rewind() {
  71. Pos_ = 0;
  72. }
  73. TStringBuf Finish() const {
  74. return TStringBuf(Vec_.data(), Vec_.data() + Pos_);
  75. }
  76. private:
  77. void Ensure(size_t delta) {
  78. if (Pos_ + delta > Vec_.size()) {
  79. if (Pos_ + delta > Vec_.capacity()) {
  80. Vec_.reserve(Max(2 * Vec_.capacity(), Pos_ + delta));
  81. }
  82. // TODO: replace TVector - resize() performs unneeded zeroing here
  83. Vec_.resize(Pos_ + delta);
  84. }
  85. }
  86. private:
  87. size_t Pos_ = 0;
  88. TVector<char> Vec_;
  89. };
  90. }
  91. }