aboutsummaryrefslogblamecommitdiffstats
path: root/util/generic/string.cpp
blob: a2b303f2605f9240029df538fff23cfe9629b484 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                   
 
                              
                                   
                                  
 
                   
                                                   
 
                                                              
                                        
 
                                                        
                            
 
           
                                                                                 
                                                                             
 
           
                                                                                 
                                                                             
 
           
                                                                                 
                     
     
                                               
 
           
             
                                                                                      
                                        
 
                                           
 
                                                                  
                                          
 
                 
 
           
             
                                                                                     
                            
                                            
                       
                                                                                
                          
                                                                                                                            
     
                              


                 
           
                                                                                       
                                  
 
           
                                                                                       
                                  
 
           
                                                                                       
                                  
 
 
           
             
                                                                                      
                                        
 
                                           
 
                                                                  




                                          
           
                                                                                









                                                               
           
             
                                                                                     
                            
                                            
                       
                                                                                
                          
                                                                                                                            
     
                              
                 
 
           
             
                                                                                      
                            
                                            

                                        
                                                                        
                                  
                              
 
                 
 
           
                                                                                       
                                  
 
           
                                                                                       
                                  
 
           
                                                                                       
                                  
 
#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);
}