std::vector<std::basic_string<T_Char>> split( const std::basic_string<T_Char>& src, const std::basic_string<T_Char>& delimit) { std::vector<std::basic_string<T_Char>> array; typedef typename std::basic_string<T_Char>::size_type size_type; typedef typename std::basic_string<T_Char>::const_iterator const_iterator; std::basic_string<T_Char> tmp; if (src.empty()) return array; if (delimit.empty()) { array.reserve(array.size() + src.size()); for (const_iterator it = src.begin(); it != src.end(); ++it) array.push_back(std::basic_string<T_Char>(1, *it)); return array; } size_type src_pos = 0; while (src.begin() + src_pos != src.end()) { size_type fnd_pos = src.find(delimit, src_pos); if (fnd_pos == std::basic_string<T_Char>::npos) { array.push_back(std::basic_string<T_Char>(src, src_pos)); break; } array.push_back( std::basic_string<T_Char>(src, src_pos, fnd_pos - src_pos)); src_pos = fnd_pos + delimit.length(); } return array; }
std::vector< std::basic_string< CharType > > str_split( std::basic_string< CharType > const & p_str, std::basic_string< CharType > const & p_delims, uint32_t p_maxSplits, bool p_bKeepVoid ) { typedef std::basic_string< CharType > string_t; std::vector< string_t > l_arrayReturn; if ( ! p_str.empty() && ! p_delims.empty() && p_maxSplits > 0 ) { l_arrayReturn.reserve( p_maxSplits + 1 ); std::size_t l_numSplits = 0; std::size_t l_pos = 0; std::size_t l_start = 0; do { l_pos = p_str.find_first_of( p_delims, l_start ); if ( l_pos == l_start ) { l_start = l_pos + 1; if ( p_bKeepVoid ) { l_arrayReturn.push_back( string_t() ); } } else if ( l_pos == string_t::npos || l_numSplits == p_maxSplits ) { string_t remnants = p_str.substr( l_start ); if ( !remnants.empty() || p_bKeepVoid ) { l_arrayReturn.push_back( remnants ); } return l_arrayReturn; } else { l_arrayReturn.push_back( p_str.substr( l_start, l_pos - l_start ) ); l_start = l_pos + 1; } //l_start = p_str.find_first_not_of( p_delims, l_start ); ++ l_numSplits; } while ( l_pos != string_t::npos ); } return l_arrayReturn; }
Error ShellExecute(const std::basic_string<charT, traits, Allocator>& fileName = std::basic_string<charT, traits, Allocator>(), const std::basic_string<charT, traits, Allocator>& operation = std::basic_string<charT, traits, Allocator>(), const std::basic_string<charT, traits, Allocator>& parameters = std::basic_string<charT, traits, Allocator>(), const std::basic_string<charT, traits, Allocator>& directory = std::basic_string<charT, traits, Allocator>(), HWND hwnd = HWND(NULL), show_command showCmd = show_command_normal) { const charT * const file = fileName.c_str(); const charT * const op = operation.empty() ? NULL : operation.c_str(); const charT * const params = parameters.empty() ? NULL : parameters.c_str(); const charT * const dir = directory.empty() ? NULL : directory.c_str(); return ShellExecute(hwnd, op, file, params, dir, showCmd); }
std::basic_string< char > str_convert< char, wchar_t >( std::basic_string< wchar_t > const & src ) { std::basic_string< char > dst; if ( !src.empty() ) { std::unique_lock< std::mutex > lock( g_conversionMutex ); char * szloc = setlocale( LC_CTYPE, "" ); size_t size = wcstombs( NULL, src.c_str(), 0 ) + 1; char * buffer = NULL; { auto guard = make_block_guard( [&buffer, &size]() { buffer = new char[size + 1]; }, [&buffer]() { delete [] buffer; } ); size = std::min( size, wcstombs( buffer, src.c_str(), size ) ); setlocale( LC_CTYPE, szloc ); dst.assign( buffer, buffer + size ); } } return dst; }
void IO::TrimRight(std::basic_string<charType> & str, const char* chars2remove) { if (!str.empty()) { //trim the characters in chars2remove from the right std::string::size_type pos = 0; if (chars2remove != NULL) { pos = str.find_last_not_of(chars2remove); if (pos != std::string::npos) str.erase(pos+1); else str.erase( str.begin() , str.end() ); // make empty } else { //trim space pos = std::string::npos; for (int i = str.size()-1; i >= 0; --i) { if (!isspace(str[i])) { pos = i; break; } } if (pos != std::string::npos) { if (pos+1 != str.size()) str.resize(pos+1); } else { str.clear(); } } } }
std::basic_string<Ch> encode_char_entities(const std::basic_string<Ch> &s) { // Don't do anything for empty strings. if(s.empty()) return s; typedef typename std::basic_string<Ch> Str; Str r; // To properly round-trip spaces and not uglify the XML beyond // recognition, we have to encode them IF the text contains only spaces. Str sp(1, Ch(' ')); if(s.find_first_not_of(sp) == Str::npos) { // The first will suffice. r = detail::widen<Ch>(" "); r += Str(s.size() - 1, Ch(' ')); } else { typename Str::const_iterator end = s.end(); for (typename Str::const_iterator it = s.begin(); it != end; ++it) { switch (*it) { case Ch('<'): r += detail::widen<Ch>("<"); break; case Ch('>'): r += detail::widen<Ch>(">"); break; case Ch('&'): r += detail::widen<Ch>("&"); break; case Ch('"'): r += detail::widen<Ch>("""); break; case Ch('\''): r += detail::widen<Ch>("'"); break; default: r += *it; break; } } } return r; }
std::basic_string<C> perl_s (std::basic_string<C> const& src, std::basic_string<C> const& e) { typedef std::basic_string<C> string; typedef typename string::size_type size; if (e.empty ()) return src; C delimiter (e[0]); size first = e.find (delimiter); size middle = e.find (delimiter, first + 1); size last = e.find (delimiter, middle + 1); string pattern (e, first + 1, middle - first - 1); string format (e, middle + 1, last - middle - 1); //std::cout << pattern << " " << format << std::endl; boost::basic_regex<C> expr (pattern); return regex_merge ( src, expr, format, boost::match_default | boost::format_all ); }
const std::basic_string<charT>& nan_text() { static std::basic_string<charT> r; if (r.empty()) { std::basic_ostringstream<charT> out; out << "#NaN#"; r = out.str(); } return r; }
cstr(const std::basic_string<char_type, CharTraits, Allocator>& s) { if (s.empty()) { clear(); } else { buf_ = s.c_str(); size_ = s.size(); } }
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p) { if(0 == *p) { if(s.empty() || ((s.size() == 1) && (s[0] == 0))) return 0; } return s.compare(p); }
bool EndsWith(const std::basic_string<CharT> &lhs, const std::basic_string<CharT> &rhs) { if (rhs.empty()) return true; if (lhs.length() < rhs.length()) return false; return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0; }
std::basic_string<CharType> escape_argument_if_needed(const std::basic_string<CharType>& arg) { if (!arg.empty() && !has_escapable_characters(arg)) { return arg; } else { return escape_argument(arg); } }
/** Return true iff `str` is a valid Symbol. */ static inline bool is_valid(const std::basic_string<char>& str) { if (str.empty() || (str[0] >= '0' && str[0] <= '9')) { return false; // Must start with a letter or underscore } for (size_t i = 0; i < str.length(); ++i) { if (!is_valid_char(str[i])) { return false; // All characters must be _, a-z, A-Z, 0-9 } } return true; }
ResultList split(const std::basic_string<CharT> &s, const std::basic_string<CharT> &delimiter, bool keepEmptyParts = true) { ResultList slist; // If delimiter.empty(): // pos = s.find(delimiter, start); // pos will be 0. if (delimiter.empty()) { slist.push_back(s); return slist; } typename std::basic_string<CharT>::size_type start = 0; typename std::basic_string<CharT>::size_type pos; std::basic_string<CharT> part; if (delimiter.length() == 1) { CharT ch = delimiter[0]; // Hope that: // find(std::basic_string<CharT>, CharT ch) // will be faster than: // find(std::basic_string<CharT>, std::basic_string<CharT>) while ((pos = s.find(ch, start)) != s.npos) { // Use strchr/wcschr instead? part = s.substr(start, pos - start); if (!part.empty() || keepEmptyParts) slist.push_back(part); start = pos + delimiter.length(); } } else { while ((pos = s.find(delimiter, start)) != s.npos) { // Use strstr/wcsstr instead? part = s.substr(start, pos - start); if (!part.empty() || keepEmptyParts) slist.push_back(part); start = pos + delimiter.length(); } } if (start != s.length() || keepEmptyParts) slist.push_back(s.substr(start)); return slist; }
std::basic_string<Char> PathJoin(const std::basic_string<Char>& dir, const std::basic_string<Char>& file) { if(dir.empty()) return file; Char c = *(dir.rbegin()); switch(c) { case '\\': case '/': return dir + file; } std::basic_string<Char> ret(dir); ret.push_back('\\'); ret.append(file); return ret; }
template<typename char_t> std::basic_string<char_t> trim(const std::basic_string<char_t>& what) { if ( what.empty() ) return what; const char_t whitespace[3] = { char_t(' '), char_t('\t'), 0 }; size_t left = what.find_first_not_of(whitespace); size_t right = what.find_last_not_of(whitespace); if ( left == std::basic_string<char_t>::npos ) { return std::basic_string<char_t>(); } else { return what.substr(left, right-left+1); } }
/** Convert a string to a valid symbol. * * This will make a best effort at turning `str` into a complete, valid * Symbol, and will always return one. */ static inline Symbol symbolify(const std::basic_string<char>& in) { if (in.empty()) { return Symbol("_"); } std::basic_string<char> out(in); for (size_t i = 0; i < in.length(); ++i) { if (!is_valid_char(out[i])) { out[i] = '_'; } } if (is_valid_start_char(out[0])) { return Symbol(out); } else { return Symbol(std::string("_") + out); } }
std::basic_string< wchar_t > str_convert< wchar_t, char >( std::basic_string< char > const & src ) { std::basic_string< wchar_t > dst; if ( !src.empty() ) { try { std::unique_lock< std::mutex > lock( g_conversionMutex ); char * szloc = setlocale( LC_CTYPE, "" ); mbtowc( NULL, NULL, 0 ); size_t max = src.size(); int length = 1; const char * in = src.c_str(); dst.reserve( src.size() ); while ( max > 0 && length >= 1 ) { wchar_t wc; length = mbtowc( &wc, in, max ); if ( length >= 1 ) { dst += wc; max -= length; in += length; } } setlocale( LC_CTYPE, szloc ); } catch ( std::exception & exc ) { CLogger::LogError( StringStream() << ERROR_DB_CONVERSION << exc.what() ); } catch ( ... ) { CLogger::LogError( StringStream() << ERROR_DB_CONVERSION << INFO_UNKNOWN ); } } return std::move( dst ); }
void IO::TrimLeft(std::basic_string<charType> & str, const char* chars2remove) { if (!str.empty()) //trim the characters in chars2remove from the left { std::string::size_type pos = 0; if (chars2remove != NULL) { pos = str.find_first_not_of(chars2remove); if (pos != std::string::npos) str.erase(0,pos); else str.erase( str.begin() , str.end() ); // make empty } else //trim space { pos = std::string::npos; //pos = -1 for (size_t i = 0; i < str.size(); ++i) { if (!isspace(str[i])) { pos = i; break; } } if (pos != std::string::npos) { if (pos > 0) { size_t length = str.size() - pos; for (size_t i = 0; i < length; ++i) str[i] = str[i+pos]; str.resize(length); } } else { str.clear(); } } } }
std::basic_string< char > str_convert< char, wchar_t >( std::basic_string< wchar_t > const & src ) { std::basic_string< char > dst; if ( !src.empty() ) { try { std::unique_lock< std::mutex > lock( g_conversionMutex ); std::string szloc = setlocale( LC_CTYPE, "" ); size_t max = src.size(); int length = 1; const wchar_t * in = src.c_str(); char buffer[32] = { 0 }; dst.reserve( 1 + src.size() * 2 ); while ( *in && length >= 1 ) { length = wctomb( buffer, *in ); if ( length >= 1 ) { dst += buffer; in++; } } setlocale( LC_CTYPE, szloc.c_str() ); } catch ( std::exception & exc ) { CLogger::LogError( StringStream() << ERROR_DB_CONVERSION << exc.what() ); } catch ( ... ) { CLogger::LogError( StringStream() << ERROR_DB_CONVERSION << INFO_UNKNOWN ); } } return std::move( dst ); }
void test_ok(std::string file,std::locale const &l,std::basic_string<Char> cmp=std::basic_string<Char>()) { if(cmp.empty()) cmp=to<Char>(file); std::ofstream test("testi.txt"); test << file; test.close(); typedef std::basic_fstream<Char> stream_type; stream_type f1("testi.txt",stream_type::in); f1.imbue(l); TEST(read_file<Char>(f1) == cmp); f1.close(); stream_type f2("testo.txt",stream_type::out); f2.imbue(l); f2 << cmp; f2.close(); std::ifstream testo("testo.txt"); TEST(read_file<char>(testo) == file); }
bool utfConvert( const std::basic_string<From>& from, std::basic_string<To>& to, ConversionResult(*cvtfunc)(const typename FromTrait::ArgType**, const typename FromTrait::ArgType*, typename ToTrait::ArgType**, typename ToTrait::ArgType*, ConversionFlags) ) { static_assert(sizeof(From) == sizeof(typename FromTrait::ArgType), "Error size mismatched"); static_assert(sizeof(To) == sizeof(typename ToTrait::ArgType), "Error size mismatched"); if (from.empty()) { to.clear(); return true; } // See: http://unicode.org/faq/utf_bom.html#gen6 static const int most_bytes_per_character = 4; const size_t maxNumberOfChars = from.length(); // all UTFs at most one element represents one character. const size_t numberOfOut = maxNumberOfChars * most_bytes_per_character / sizeof(To); std::basic_string<To> working(numberOfOut, 0); auto inbeg = reinterpret_cast<const typename FromTrait::ArgType*>(&from[0]); auto inend = inbeg + from.length(); auto outbeg = reinterpret_cast<typename ToTrait::ArgType*>(&working[0]); auto outend = outbeg + working.length(); auto r = cvtfunc(&inbeg, inend, &outbeg, outend, strictConversion); if (r != conversionOK) return false; working.resize(reinterpret_cast<To*>(outbeg) - &working[0]); to = std::move(working); return true; };
void StringTrimT(std::basic_string<CharType> &output) { if (output.empty()) return; size_t bound1 = 0; size_t bound2 = output.length(); const CharType *src = output.data(); for (; bound2 > 0; bound2--) if (NOT_SPACE(src[bound2-1])) break; for (; bound1 < bound2; bound1++) if (NOT_SPACE(src[bound1])) break; if (bound1 < bound2) { memmove((void *)src, src + bound1, sizeof(CharType) * (bound2 - bound1)); } output.resize(bound2 - bound1); }
bool is_simple_key(const std::basic_string<Ch> &key) { const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\""); return !key.empty() && key.find_first_of(chars) == key.npos; }
std::basic_string<Out> codecvt( std::basic_string<In> const &_string, std::locale const &_locale, Function const &_function ) { typedef std::basic_string< Out > return_type; typedef fcppt::container::raw_vector< Out > buffer_type; if( _string.empty() ) return return_type(); fcppt::codecvt_type const &conv( std::use_facet< fcppt::codecvt_type >( _locale ) ); buffer_type buf( _string.size() ); typedef fcppt::codecvt_type::state_type state_type; state_type state; std::memset( &state, 0, sizeof(state_type) ); Out *to = buf.data(); for( In const *from = _string.data(), *from_next = nullptr; ; // loop forever from = from_next ) { Out *to_next; std::codecvt_base::result const result( ( conv.*_function )( state, from, fcppt::container::data_end( _string ), from_next, to, buf.data_end(), to_next ) ); switch( result ) { case std::codecvt_base::noconv: return return_type( _string.begin(), _string.end() ); case std::codecvt_base::error: throw fcppt::exception( FCPPT_TEXT("codecvt: error!") ); case std::codecvt_base::partial: { typename buffer_type::difference_type const diff( std::distance( buf.data(), to_next ) ); buf.resize( buf.size() * 2 ); to = buf.data() + diff; } continue; case std::codecvt_base::ok: return return_type( buf.data(), to_next ); } FCPPT_ASSERT_UNREACHABLE; } }
template<typename char_t> bool ends_with(const std::basic_string<char_t>& what, const std::basic_string<char_t>& with) { return !what.empty() && (what.find(with) == what.length()-with.length()); }
inline std::basic_string<CharT> unescape_impl(std::basic_string<CharT> src, EscapeFlags flags) { if (src.empty()) return {}; typedef CharT char_type; typedef std::basic_string<char_type> string_type; typedef typename string_type::iterator iterator_type; typedef detail::named_character_references_traits<char_type> named_character_references_traits_type; typedef detail::unescape_traits<char_type> unescape_traits_type; boost::match_results<iterator_type> what; boost::match_flag_type rgx_flags = boost::match_default; iterator_type start = src.begin(), end = src.end(); // this function must not fail. auto const perform_replace = [&](string_type const& replace_to) -> void { std::size_t const last_pos_i = std::distance(src.begin(), what[0].first); // std::cout << "replacing " << what.str(0) << " to " << replace_to << std::endl; src.replace(what[0].first, what[0].second, replace_to); start = src.begin() + last_pos_i + replace_to.size(); end = src.end(); }; auto const process = [&]() -> bool { string_type const found_str(what.str(0)); string_type found_code; bool is_numeric = false; bool is_hexadecimal = false; BOOST_ASSERT(what.size() == 5); // determine whether it's named, decimal or hexadecimal if (what.str(1).empty() && what.str(3).empty()) { // named is_numeric = false; } else { is_numeric = true; if (!what.str(1).empty()) { // hexadecimal BOOST_ASSERT(!what.str(2).empty()); is_hexadecimal = true; found_code = what.str(2); } else { // decimal BOOST_ASSERT(!what.str(3).empty()); BOOST_ASSERT(!what.str(4).empty()); is_hexadecimal = false; found_code = what.str(4); } } try { // check for each types auto const& table = named_character_references_traits_type::table(); if (is_numeric) { if ((flags & UNESCAPE_DECIMAL) && is_hexadecimal) { UChar32 const cp = std::stoull(unescape_traits_type::hexadecimal_prefix() + found_code, nullptr, 16); perform_replace(saya::to<string_type>(saya::ustring(cp))); return true; } else if ((flags & UNESCAPE_DECIMAL) && !is_hexadecimal) { UChar32 const cp = boost::lexical_cast<UChar32>(found_code); perform_replace(saya::to<string_type>(saya::ustring(cp))); return true; } } else { if ((flags & UNESCAPE_NAMED) && table.count(found_str)) { perform_replace(table.at(found_str)); return true; } } } catch (std::out_of_range const&) { return false; } catch (std::invalid_argument const&) { return false; } catch (boost::bad_lexical_cast const&) { return false; } return false; }; while (boost::regex_search(start, end, what, detail::unescape_traits<char_type>::character_reference_rgx(), rgx_flags)) { if (!process()) { // skip and continue start = what[0].second; } rgx_flags |= boost::match_prev_avail; } return src; }
bool enum_file_lines::GetTString(std::vector<T>& From, std::basic_string<T>& To, eol::type& Eol, bool bBigEndian) const { To.clear(); // Обработка ситуации, когда у нас пришёл двойной \r\r, а потом не было \n. // В этом случаем считаем \r\r двумя MAC окончаниями строк. if (m_CrCr) { m_CrCr = false; Eol = eol::type::mac; return true; } auto CurrentEol = eol::type::none; for (const auto* ReadBufPtr = ReadPos < ReadSize? From.data() + ReadPos / sizeof(T) : nullptr; ; ++ReadBufPtr, ReadPos += sizeof(T)) { if (ReadPos >= ReadSize) { if (!(SrcFile.Read(From.data(), ReadBufCount * sizeof(T), ReadSize) && ReadSize)) { Eol = CurrentEol; return !To.empty() || CurrentEol != eol::type::none; } if (bBigEndian && sizeof(T) != 1) { swap_bytes(From.data(), From.data(), ReadSize); } ReadPos = 0; ReadBufPtr = From.data(); } if (CurrentEol == eol::type::none) { // UNIX if (*ReadBufPtr == m_Eol.lf<T>()) { CurrentEol = eol::type::unix; continue; } // MAC / Windows? / Notepad? else if (*ReadBufPtr == m_Eol.cr<T>()) { CurrentEol = eol::type::mac; continue; } } else if (CurrentEol == eol::type::mac) { if (m_CrSeen) { m_CrSeen = false; // Notepad if (*ReadBufPtr == m_Eol.lf<T>()) { CurrentEol = eol::type::bad_win; continue; } else { // Пришёл \r\r, а \n не пришёл, поэтому считаем \r\r двумя MAC окончаниями строк m_CrCr = true; break; } } else { // Windows if (*ReadBufPtr == m_Eol.lf<T>()) { CurrentEol = eol::type::win; continue; } // Notepad or two MACs? else if (*ReadBufPtr == m_Eol.cr<T>()) { m_CrSeen = true; continue; } else { break; } } } else { break; } To.push_back(*ReadBufPtr); CurrentEol = eol::type::none; } Eol = CurrentEol; return true; }
bool is_simple_data(const std::basic_string<Ch> &data) { const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\""); return !data.empty() && data.find_first_of(chars) == data.npos; }
size_t StringReplaceAllT(const std::basic_string<CharType> &find, const std::basic_string<CharType> &replace, std::basic_string<CharType> &output) { size_t find_length = find.size(); size_t replace_length = replace.size(); size_t offset = 0, endpos; size_t target = 0, found_pos; size_t replaced = 0; CharType *data_ptr; if (find.empty() || output.empty()) return 0; /* * to avoid extra memory reallocating, * we use two passes to finish the task in the case that replace.size() is greater find.size() */ if (find_length < replace_length) { /* the first pass, count all available 'find' to be replaced */ for (;;) { offset = output.find(find, offset); if (offset == std::basic_string<CharType>::npos) break; replaced++; offset += find_length; } if (replaced == 0) return 0; size_t newsize = output.size() + replaced * (replace_length - find_length); /* we apply for more memory to hold the content to be replaced */ endpos = newsize; offset = newsize - output.size(); output.resize(newsize); data_ptr = &output[0]; memmove((void*)(data_ptr + offset), (void*)data_ptr, (output.size() - offset) * sizeof(CharType)); } else { endpos = output.size(); offset = 0; data_ptr = const_cast<CharType *>(&output[0]); } /* the second pass, the replacement */ while (offset < endpos) { found_pos = output.find(find, offset); if (found_pos != std::basic_string<CharType>::npos) { /* move the content between two targets */ if (target != found_pos) memmove((void*)(data_ptr + target), (void*)(data_ptr + offset), (found_pos - offset) * sizeof(CharType)); target += found_pos - offset; /* replace */ memcpy(data_ptr + target, replace.data(), replace_length * sizeof(CharType)); target += replace_length; offset = find_length + found_pos; replaced++; } else { /* ending work */ if (target != offset) memcpy((void*)(data_ptr + target), (void*)(data_ptr + offset), (endpos - offset) * sizeof(CharType)); break; } } if (replace_length < find_length) output.resize(output.size() - replaced * (find_length - replace_length)); return replaced; }