aligned.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #include "input.h"
  3. #include "output.h"
  4. #include <util/system/yassert.h>
  5. #include <util/generic/bitops.h>
  6. /**
  7. * @addtogroup Streams
  8. * @{
  9. */
  10. /**
  11. * Proxy input stream that provides additional functions that make reading
  12. * aligned data easier.
  13. */
  14. class TAlignedInput: public IInputStream {
  15. public:
  16. TAlignedInput(IInputStream* s)
  17. : Stream_(s)
  18. , Position_(0)
  19. {
  20. }
  21. /**
  22. * Ensures alignment of the position in the input stream by skipping
  23. * some input.
  24. *
  25. * @param alignment Alignment. Must be a power of 2.
  26. */
  27. void Align(size_t alignment = sizeof(void*)) {
  28. Y_ASSERT(IsPowerOf2(alignment));
  29. if (Position_ & (alignment - 1)) {
  30. size_t len = alignment - (Position_ & (alignment - 1));
  31. do {
  32. len -= DoSkip(len);
  33. } while (len);
  34. }
  35. }
  36. private:
  37. size_t DoRead(void* ptr, size_t len) override;
  38. size_t DoSkip(size_t len) override;
  39. size_t DoReadTo(TString& st, char ch) override;
  40. ui64 DoReadAll(IOutputStream& out) override;
  41. private:
  42. IInputStream* Stream_;
  43. ui64 Position_;
  44. };
  45. /**
  46. * Proxy output stream that provides additional functions that make writing
  47. * aligned data easier.
  48. */
  49. class TAlignedOutput: public IOutputStream {
  50. public:
  51. TAlignedOutput(IOutputStream* s)
  52. : Stream_(s)
  53. , Position_(0)
  54. {
  55. }
  56. TAlignedOutput(TAlignedOutput&&) noexcept = default;
  57. TAlignedOutput& operator=(TAlignedOutput&&) noexcept = default;
  58. size_t GetCurrentOffset() const {
  59. return Position_;
  60. }
  61. /**
  62. * Ensures alignment of the position in the output stream by writing
  63. * some data.
  64. *
  65. * @param alignment Alignment. Must be a power of 2.
  66. */
  67. void Align(size_t alignment = sizeof(void*)) {
  68. Y_ASSERT(IsPowerOf2(alignment));
  69. static char unused[sizeof(void*) * 2];
  70. Y_ASSERT(alignment <= sizeof(unused));
  71. if (Position_ & (alignment - 1)) {
  72. DoWrite(unused, alignment - (Position_ & (alignment - 1)));
  73. }
  74. }
  75. private:
  76. void DoWrite(const void* ptr, size_t len) override;
  77. private:
  78. IOutputStream* Stream_;
  79. ui64 Position_;
  80. };
  81. /** @} */