string.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "string.h"
  2. #include <util/string/ascii.h>
  3. #include <util/system/sanitizers.h>
  4. #include <util/system/sys_alloc.h>
  5. #include <util/charset/wide.h>
  6. #include <iostream>
  7. alignas(32) const char NULL_STRING_REPR[128] = {0};
  8. std::ostream& operator<<(std::ostream& os, const TString& s) {
  9. return os.write(s.data(), s.size());
  10. }
  11. std::istream& operator>>(std::istream& is, TString& s) {
  12. return is >> s.MutRef();
  13. }
  14. template <>
  15. bool TBasicString<char, std::char_traits<char>>::to_lower(size_t pos, size_t n) {
  16. return Transform([](size_t, char c) { return AsciiToLower(c); }, pos, n);
  17. }
  18. template <>
  19. bool TBasicString<char, std::char_traits<char>>::to_upper(size_t pos, size_t n) {
  20. return Transform([](size_t, char c) { return AsciiToUpper(c); }, pos, n);
  21. }
  22. template <>
  23. bool TBasicString<char, std::char_traits<char>>::to_title(size_t pos, size_t n) {
  24. if (n == 0) {
  25. return false;
  26. }
  27. bool changed = to_upper(pos, 1);
  28. return to_lower(pos + 1, n - 1) || changed;
  29. }
  30. template <>
  31. TUtf16String&
  32. TBasicString<wchar16, std::char_traits<wchar16>>::AppendAscii(const ::TStringBuf& s) {
  33. ReserveAndResize(size() + s.size());
  34. auto dst = begin() + size() - s.size();
  35. for (const char* src = s.data(); dst != end(); ++dst, ++src) {
  36. *dst = static_cast<wchar16>(*src);
  37. }
  38. return *this;
  39. }
  40. template <>
  41. TUtf16String&
  42. TBasicString<wchar16, std::char_traits<wchar16>>::AppendUtf8(const ::TStringBuf& s) {
  43. size_t oldSize = size();
  44. ReserveAndResize(size() + s.size() * 4);
  45. size_t written = 0;
  46. size_t pos = UTF8ToWideImpl(s.data(), s.size(), begin() + oldSize, written);
  47. if (pos != s.size()) {
  48. ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size());
  49. }
  50. resize(oldSize + written);
  51. return *this;
  52. }
  53. template <>
  54. bool TBasicString<wchar16, std::char_traits<wchar16>>::to_lower(size_t pos, size_t n) {
  55. return ToLower(*this, pos, n);
  56. }
  57. template <>
  58. bool TBasicString<wchar16, std::char_traits<wchar16>>::to_upper(size_t pos, size_t n) {
  59. return ToUpper(*this, pos, n);
  60. }
  61. template <>
  62. bool TBasicString<wchar16, std::char_traits<wchar16>>::to_title(size_t pos, size_t n) {
  63. return ToTitle(*this, pos, n);
  64. }
  65. template <>
  66. TUtf32String&
  67. TBasicString<wchar32, std::char_traits<wchar32>>::AppendAscii(const ::TStringBuf& s) {
  68. ReserveAndResize(size() + s.size());
  69. auto dst = begin() + size() - s.size();
  70. for (const char* src = s.data(); dst != end(); ++dst, ++src) {
  71. *dst = static_cast<wchar32>(*src);
  72. }
  73. return *this;
  74. }
  75. template <>
  76. TBasicString<char, std::char_traits<char>>&
  77. TBasicString<char, std::char_traits<char>>::AppendUtf16(const ::TWtringBuf& s) {
  78. const size_t oldSize = size();
  79. ReserveAndResize(size() + WideToUTF8BufferSize(s.size()));
  80. size_t written = 0;
  81. WideToUTF8(s.data(), s.size(), begin() + oldSize, written);
  82. resize(oldSize + written);
  83. return *this;
  84. }
  85. template <>
  86. TUtf32String&
  87. TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf8(const ::TStringBuf& s) {
  88. size_t oldSize = size();
  89. ReserveAndResize(size() + s.size() * 4);
  90. size_t written = 0;
  91. size_t pos = UTF8ToWideImpl(s.data(), s.size(), begin() + oldSize, written);
  92. if (pos != s.size()) {
  93. ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size());
  94. }
  95. resize(oldSize + written);
  96. return *this;
  97. }
  98. template <>
  99. TUtf32String&
  100. TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf16(const ::TWtringBuf& s) {
  101. size_t oldSize = size();
  102. ReserveAndResize(size() + s.size() * 2);
  103. wchar32* oldEnd = begin() + oldSize;
  104. wchar32* end = oldEnd;
  105. NDetail::UTF16ToUTF32ImplScalar(s.data(), s.data() + s.size(), end);
  106. size_t written = end - oldEnd;
  107. resize(oldSize + written);
  108. return *this;
  109. }
  110. template <>
  111. bool TBasicString<wchar32, std::char_traits<wchar32>>::to_lower(size_t pos, size_t n) {
  112. return ToLower(*this, pos, n);
  113. }
  114. template <>
  115. bool TBasicString<wchar32, std::char_traits<wchar32>>::to_upper(size_t pos, size_t n) {
  116. return ToUpper(*this, pos, n);
  117. }
  118. template <>
  119. bool TBasicString<wchar32, std::char_traits<wchar32>>::to_title(size_t pos, size_t n) {
  120. return ToTitle(*this, pos, n);
  121. }