str.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 Y_LIFETIME_BOUND) 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 Y_LIFETIME_BOUND) 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(TString&& string)
  107. : TEmbeddedString(std::move(string))
  108. , TStringInput(*TEmbeddedString::Ptr())
  109. , TStringOutput(*TEmbeddedString::Ptr())
  110. {
  111. }
  112. inline TStringStream(const TStringStream& other)
  113. : TEmbeddedString(other.Str())
  114. , TStringInput(*TEmbeddedString::Ptr())
  115. , TStringOutput(*TEmbeddedString::Ptr())
  116. {
  117. }
  118. inline TStringStream(TStringStream&& other)
  119. : TEmbeddedString(std::move(other).Str())
  120. , TStringInput(*TEmbeddedString::Ptr())
  121. , TStringOutput(*TEmbeddedString::Ptr())
  122. {
  123. other.Pos_ = 0;
  124. }
  125. inline TStringStream& operator=(const TStringStream& other) {
  126. // All references remain alive, we need to change position only
  127. Str() = other.Str();
  128. Pos_ = other.Pos_;
  129. return *this;
  130. }
  131. inline TStringStream& operator=(TStringStream&& other) {
  132. // All references remain alive, we need to change position only
  133. Str() = std::move(other).Str();
  134. Pos_ = other.Pos_;
  135. other.Pos_ = 0;
  136. return *this;
  137. }
  138. ~TStringStream() override;
  139. /**
  140. * @returns Whether @c this contains any data
  141. */
  142. explicit operator bool() const noexcept {
  143. return !Empty();
  144. }
  145. /**
  146. * @returns String that this stream is writing into.
  147. */
  148. inline TString& Str() & noexcept {
  149. return *Ptr();
  150. }
  151. /**
  152. * @returns String that this stream is writing into.
  153. */
  154. inline const TString& Str() const& noexcept {
  155. return *Ptr();
  156. }
  157. /**
  158. * @returns String that this stream is writing into.
  159. */
  160. inline TString&& Str() && noexcept {
  161. return std::move(*Ptr());
  162. }
  163. /**
  164. * @returns Pointer to the character data contained
  165. * in this stream. The data is guaranteed
  166. * to be null-terminated.
  167. */
  168. inline const char* Data() const noexcept {
  169. return Ptr()->data();
  170. }
  171. /**
  172. * @returns Total number of characters in this
  173. * stream. Note that this is not the same
  174. * as the total number of characters
  175. * available for reading.
  176. */
  177. inline size_t Size() const noexcept {
  178. return Ptr()->size();
  179. }
  180. /**
  181. * @returns Whether the string that this stream
  182. * operates on is empty.
  183. */
  184. Y_PURE_FUNCTION inline bool Empty() const noexcept {
  185. return Str().empty();
  186. }
  187. using TStringOutput::Reserve;
  188. /**
  189. * Clears the string that this stream operates on and resets the
  190. * read/write pointers.
  191. */
  192. inline void Clear() {
  193. Str().clear();
  194. Pos_ = 0;
  195. }
  196. // TODO: compatibility with existing code, remove
  197. Y_PURE_FUNCTION bool empty() const {
  198. return Empty();
  199. }
  200. void clear() {
  201. Clear();
  202. }
  203. };
  204. /** @} */