#include "string.h"
#include <util/string/ascii.h>
#include <util/system/sanitizers.h>
#include <util/system/sys_alloc.h>
#include <util/charset/wide.h>
#include <iostream>
alignas(32) const char NULL_STRING_REPR[128] = {0};
std::ostream& operator<<(std::ostream& os, const TString& s) {
return os.write(s.data(), s.size());
}
std::istream& operator>>(std::istream& is, TString& s) {
return is >> s.MutRef();
}
template <>
bool TBasicString<char, std::char_traits<char>>::to_lower(size_t pos, size_t n) {
return Transform([](size_t, char c) { return AsciiToLower(c); }, pos, n);
}
template <>
bool TBasicString<char, std::char_traits<char>>::to_upper(size_t pos, size_t n) {
return Transform([](size_t, char c) { return AsciiToUpper(c); }, pos, n);
}
template <>
bool TBasicString<char, std::char_traits<char>>::to_title(size_t pos, size_t n) {
if (n == 0) {
return false;
}
bool changed = to_upper(pos, 1);
return to_lower(pos + 1, n - 1) || changed;
}
template <>
TUtf16String&
TBasicString<wchar16, std::char_traits<wchar16>>::AppendAscii(const ::TStringBuf& s) {
ReserveAndResize(size() + s.size());
auto dst = begin() + size() - s.size();
for (const char* src = s.data(); dst != end(); ++dst, ++src) {
*dst = static_cast<wchar16>(*src);
}
return *this;
}
template <>
TUtf16String&
TBasicString<wchar16, std::char_traits<wchar16>>::AppendUtf8(const ::TStringBuf& s) {
size_t oldSize = size();
ReserveAndResize(size() + s.size() * 4);
size_t written = 0;
size_t pos = UTF8ToWideImpl(s.data(), s.size(), begin() + oldSize, written);
if (pos != s.size()) {
ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size());
}
resize(oldSize + written);
return *this;
}
template <>
bool TBasicString<wchar16, std::char_traits<wchar16>>::to_lower(size_t pos, size_t n) {
return ToLower(*this, pos, n);
}
template <>
bool TBasicString<wchar16, std::char_traits<wchar16>>::to_upper(size_t pos, size_t n) {
return ToUpper(*this, pos, n);
}
template <>
bool TBasicString<wchar16, std::char_traits<wchar16>>::to_title(size_t pos, size_t n) {
return ToTitle(*this, pos, n);
}
template <>
TUtf32String&
TBasicString<wchar32, std::char_traits<wchar32>>::AppendAscii(const ::TStringBuf& s) {
ReserveAndResize(size() + s.size());
auto dst = begin() + size() - s.size();
for (const char* src = s.data(); dst != end(); ++dst, ++src) {
*dst = static_cast<wchar32>(*src);
}
return *this;
}
template <>
TBasicString<char, std::char_traits<char>>&
TBasicString<char, std::char_traits<char>>::AppendUtf16(const ::TWtringBuf& s) {
const size_t oldSize = size();
ReserveAndResize(size() + WideToUTF8BufferSize(s.size()));
size_t written = 0;
WideToUTF8(s.data(), s.size(), begin() + oldSize, written);
resize(oldSize + written);
return *this;
}
template <>
TUtf32String&
TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf8(const ::TStringBuf& s) {
size_t oldSize = size();
ReserveAndResize(size() + s.size() * 4);
size_t written = 0;
size_t pos = UTF8ToWideImpl(s.data(), s.size(), begin() + oldSize, written);
if (pos != s.size()) {
ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size());
}
resize(oldSize + written);
return *this;
}
template <>
TUtf32String&
TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf16(const ::TWtringBuf& s) {
size_t oldSize = size();
ReserveAndResize(size() + s.size() * 2);
wchar32* oldEnd = begin() + oldSize;
wchar32* end = oldEnd;
NDetail::UTF16ToUTF32ImplScalar(s.data(), s.data() + s.size(), end);
size_t written = end - oldEnd;
resize(oldSize + written);
return *this;
}
template <>
bool TBasicString<wchar32, std::char_traits<wchar32>>::to_lower(size_t pos, size_t n) {
return ToLower(*this, pos, n);
}
template <>
bool TBasicString<wchar32, std::char_traits<wchar32>>::to_upper(size_t pos, size_t n) {
return ToUpper(*this, pos, n);
}
template <>
bool TBasicString<wchar32, std::char_traits<wchar32>>::to_title(size_t pos, size_t n) {
return ToTitle(*this, pos, n);
}