str.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #pragma once
  2. #include "zerocopy.h"
  3. #include "zerocopy_output.h"
  4. #include <util/generic/string.h>
  5. #include <util/generic/noncopyable.h>
  6. #include <util/generic/store_policy.h>
  7. /**
  8. * @addtogroup Streams_Strings
  9. * @{
  10. */
  11. /**
  12. * Input stream for reading data from a string.
  13. */
  14. class TStringInput: public IZeroCopyInputFastReadTo {
  15. public:
  16. /**
  17. * Constructs a string input stream that reads character data from the
  18. * provided string.
  19. *
  20. * Note that this stream keeps a reference to the provided string, so it's
  21. * up to the user to make sure that the string doesn't get destroyed while
  22. * this stream is in use.
  23. *
  24. * For reading data from `TStringBuf`s, see `TMemoryInput` (`util/stream/mem.h`).
  25. *
  26. * @param s String to read from.
  27. */
  28. inline TStringInput(const TString& s) noexcept
  29. : S_(&s)
  30. , Pos_(0)
  31. {
  32. }
  33. TStringInput(const TString&&) = delete;
  34. ~TStringInput() override;
  35. TStringInput(TStringInput&&) noexcept = default;
  36. TStringInput& operator=(TStringInput&&) noexcept = default;
  37. inline void Swap(TStringInput& s) noexcept {
  38. DoSwap(S_, s.S_);
  39. DoSwap(Pos_, s.Pos_);
  40. }
  41. protected:
  42. size_t DoNext(const void** ptr, size_t len) override;
  43. void DoUndo(size_t len) override;
  44. private:
  45. const TString* S_;
  46. size_t Pos_;
  47. friend class TStringStream;
  48. };
  49. /**
  50. * Stream for writing data into a string.
  51. */
  52. class TStringOutput: public IZeroCopyOutput {
  53. public:
  54. /**
  55. * Constructs a string output stream that appends character data to the
  56. * provided string.
  57. *
  58. * Note that this stream keeps a reference to the provided string, so it's
  59. * up to the user to make sure that the string doesn't get destroyed while
  60. * this stream is in use.
  61. *
  62. * @param s String to append to.
  63. */
  64. inline TStringOutput(TString& s) noexcept
  65. : S_(&s)
  66. {
  67. }
  68. TStringOutput(TStringOutput&& s) noexcept = default;
  69. ~TStringOutput() override;
  70. /**
  71. * @param size Number of additional characters to
  72. * reserve in output string.
  73. */
  74. inline void Reserve(size_t size) {
  75. S_->reserve(S_->size() + size);
  76. }
  77. inline void Swap(TStringOutput& s) noexcept {
  78. DoSwap(S_, s.S_);
  79. }
  80. protected:
  81. size_t DoNext(void** ptr) override;
  82. void DoUndo(size_t len) override;
  83. void DoWrite(const void* buf, size_t len) override;
  84. void DoWriteC(char c) override;
  85. private:
  86. TString* S_;
  87. };
  88. /**
  89. * String input/output stream, similar to `std::stringstream`.
  90. */
  91. class TStringStream: private TEmbedPolicy<TString>, public TStringInput, public TStringOutput {
  92. using TEmbeddedString = TEmbedPolicy<TString>;
  93. public:
  94. inline TStringStream()
  95. : TEmbeddedString()
  96. , TStringInput(*TEmbeddedString::Ptr())
  97. , TStringOutput(*TEmbeddedString::Ptr())
  98. {
  99. }
  100. inline TStringStream(const TString& string)
  101. : TEmbeddedString(string)
  102. , TStringInput(*TEmbeddedString::Ptr())
  103. , TStringOutput(*TEmbeddedString::Ptr())
  104. {
  105. }
  106. inline TStringStream(const TStringStream& other)
  107. : TEmbeddedString(other.Str())
  108. , TStringInput(*TEmbeddedString::Ptr())
  109. , TStringOutput(*TEmbeddedString::Ptr())
  110. {
  111. }
  112. inline TStringStream& operator=(const TStringStream& other) {
  113. // All references remain alive, we need to change position only
  114. Str() = other.Str();
  115. Pos_ = other.Pos_;
  116. return *this;
  117. }
  118. ~TStringStream() override;
  119. /**
  120. * @returns Whether @c this contains any data
  121. */
  122. explicit operator bool() const noexcept {
  123. return !Empty();
  124. }
  125. /**
  126. * @returns String that this stream is writing into.
  127. */
  128. inline TString& Str() noexcept {
  129. return *Ptr();
  130. }
  131. /**
  132. * @returns String that this stream is writing into.
  133. */
  134. inline const TString& Str() const noexcept {
  135. return *Ptr();
  136. }
  137. /**
  138. * @returns Pointer to the character data contained
  139. * in this stream. The data is guaranteed
  140. * to be null-terminated.
  141. */
  142. inline const char* Data() const noexcept {
  143. return Ptr()->data();
  144. }
  145. /**
  146. * @returns Total number of characters in this
  147. * stream. Note that this is not the same
  148. * as the total number of characters
  149. * available for reading.
  150. */
  151. inline size_t Size() const noexcept {
  152. return Ptr()->size();
  153. }
  154. /**
  155. * @returns Whether the string that this stream
  156. * operates on is empty.
  157. */
  158. Y_PURE_FUNCTION inline bool Empty() const noexcept {
  159. return Str().empty();
  160. }
  161. using TStringOutput::Reserve;
  162. /**
  163. * Clears the string that this stream operates on and resets the
  164. * read/write pointers.
  165. */
  166. inline void Clear() {
  167. Str().clear();
  168. Pos_ = 0;
  169. }
  170. // TODO: compatibility with existing code, remove
  171. Y_PURE_FUNCTION bool empty() const {
  172. return Empty();
  173. }
  174. void clear() {
  175. Clear();
  176. }
  177. };
  178. /** @} */