string.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "string.h"
  2. #include <library/cpp/yt/assert/assert.h>
  3. #include <library/cpp/yt/misc/variant.h>
  4. #include <library/cpp/yt/memory/new.h>
  5. namespace NYT::NYson {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. TYsonStringBuf::TYsonStringBuf()
  8. {
  9. Type_ = EYsonType::Node; // fake
  10. Null_ = true;
  11. }
  12. TYsonStringBuf::TYsonStringBuf(const TYsonString& ysonString)
  13. {
  14. if (ysonString) {
  15. Data_ = ysonString.AsStringBuf();
  16. Type_ = ysonString.GetType();
  17. Null_ = false;
  18. } else {
  19. Type_ = EYsonType::Node; // fake
  20. Null_ = true;
  21. }
  22. }
  23. TYsonStringBuf::TYsonStringBuf(const TString& data, EYsonType type)
  24. : TYsonStringBuf(TStringBuf(data), type)
  25. { }
  26. TYsonStringBuf::TYsonStringBuf(TStringBuf data, EYsonType type)
  27. : Data_(data)
  28. , Type_(type)
  29. , Null_(false)
  30. { }
  31. TYsonStringBuf::TYsonStringBuf(const char* data, EYsonType type)
  32. : TYsonStringBuf(TStringBuf(data), type)
  33. { }
  34. TYsonStringBuf::operator bool() const
  35. {
  36. return !Null_;
  37. }
  38. TStringBuf TYsonStringBuf::AsStringBuf() const
  39. {
  40. YT_VERIFY(*this);
  41. return Data_;
  42. }
  43. EYsonType TYsonStringBuf::GetType() const
  44. {
  45. YT_VERIFY(*this);
  46. return Type_;
  47. }
  48. ////////////////////////////////////////////////////////////////////////////////
  49. TYsonString::TYsonString()
  50. {
  51. Begin_ = nullptr;
  52. Size_ = 0;
  53. Type_ = EYsonType::Node; // fake
  54. }
  55. TYsonString::TYsonString(const TYsonStringBuf& ysonStringBuf)
  56. {
  57. if (ysonStringBuf) {
  58. auto data = ysonStringBuf.AsStringBuf();
  59. auto holder = NDetail::TYsonStringHolder::Allocate(data.length());
  60. ::memcpy(holder->GetData(), data.data(), data.length());
  61. Begin_ = holder->GetData();
  62. Size_ = data.Size();
  63. Type_ = ysonStringBuf.GetType();
  64. Payload_ = std::move(holder);
  65. } else {
  66. Begin_ = nullptr;
  67. Size_ = 0;
  68. Type_ = EYsonType::Node; // fake
  69. }
  70. }
  71. TYsonString::TYsonString(
  72. TStringBuf data,
  73. EYsonType type)
  74. : TYsonString(TYsonStringBuf(data, type))
  75. { }
  76. #ifdef TSTRING_IS_STD_STRING
  77. TYsonString::TYsonString(
  78. const TString& data,
  79. EYsonType type)
  80. : TYsonString(TYsonStringBuf(data, type))
  81. { }
  82. #else
  83. TYsonString::TYsonString(
  84. const TString& data,
  85. EYsonType type)
  86. {
  87. // NOTE: CoW TString implementation is assumed
  88. // Moving the payload MUST NOT invalidate its internal pointers
  89. Payload_ = data;
  90. Begin_ = data.data();
  91. Size_ = data.length();
  92. Type_ = type;
  93. }
  94. #endif
  95. TYsonString::TYsonString(
  96. const TSharedRef& data,
  97. EYsonType type)
  98. {
  99. Payload_ = data.GetHolder();
  100. Begin_ = data.Begin();
  101. Size_ = data.Size();
  102. Type_ = type;
  103. }
  104. TYsonString::operator bool() const
  105. {
  106. return !std::holds_alternative<TNullPayload>(Payload_);
  107. }
  108. EYsonType TYsonString::GetType() const
  109. {
  110. YT_VERIFY(*this);
  111. return Type_;
  112. }
  113. TStringBuf TYsonString::AsStringBuf() const
  114. {
  115. YT_VERIFY(*this);
  116. return TStringBuf(Begin_, Begin_ + Size_);
  117. }
  118. TString TYsonString::ToString() const
  119. {
  120. return Visit(
  121. Payload_,
  122. [] (const TNullPayload&) -> TString {
  123. YT_ABORT();
  124. },
  125. [&] (const TSharedRangeHolderPtr&) {
  126. return TString(AsStringBuf());
  127. },
  128. [] (const TString& payload) {
  129. return payload;
  130. });
  131. }
  132. TSharedRef TYsonString::ToSharedRef() const
  133. {
  134. return Visit(
  135. Payload_,
  136. [] (const TNullPayload&) -> TSharedRef {
  137. YT_ABORT();
  138. },
  139. [&] (const TSharedRangeHolderPtr& holder) {
  140. return TSharedRef(Begin_, Size_, holder);
  141. },
  142. [] (const TString& payload) {
  143. return TSharedRef::FromString(payload);
  144. });
  145. }
  146. size_t TYsonString::ComputeHash() const
  147. {
  148. return THash<TStringBuf>()(TStringBuf(Begin_, Begin_ + Size_));
  149. }
  150. void TYsonString::Save(IOutputStream* s) const
  151. {
  152. EYsonType type = Type_;
  153. if (*this) {
  154. ::SaveMany(s, type, ToSharedRef());
  155. } else {
  156. ::SaveMany(s, type, TString());
  157. }
  158. }
  159. void TYsonString::Load(IInputStream* s)
  160. {
  161. EYsonType type;
  162. TString data;
  163. ::LoadMany(s, type, data);
  164. if (data) {
  165. *this = TYsonString(data, type);
  166. } else {
  167. *this = TYsonString();
  168. }
  169. }
  170. ////////////////////////////////////////////////////////////////////////////////
  171. void FormatValue(TStringBuilderBase* builder, const TYsonString& yson, TStringBuf spec)
  172. {
  173. FormatValue(builder, yson.ToString(), spec);
  174. }
  175. void FormatValue(TStringBuilderBase* builder, const TYsonStringBuf& yson, TStringBuf spec)
  176. {
  177. FormatValue(builder, yson.AsStringBuf(), spec);
  178. }
  179. ////////////////////////////////////////////////////////////////////////////////
  180. } // namespace NYT::NYson