2014-04-01 02:33:55 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "StrFmt.h"
|
2014-08-29 21:51:11 +02:00
|
|
|
#include <wx/string.h>
|
2014-04-01 02:33:55 +02:00
|
|
|
|
2014-04-08 19:29:17 +02:00
|
|
|
extern const std::string fmt::placeholder = "???";
|
2014-04-01 19:44:38 +02:00
|
|
|
|
|
|
|
|
2014-04-01 02:33:55 +02:00
|
|
|
//wrapper to deal with advance sprintf formating options with automatic length finding
|
|
|
|
//can't take strings by reference because of "va_start", so overload it with char *
|
|
|
|
std::string fmt::FormatV(const char *fmt, va_list args)
|
|
|
|
{
|
2014-04-08 19:29:17 +02:00
|
|
|
size_t length = 256;
|
2014-04-01 02:33:55 +02:00
|
|
|
std::string str;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
std::vector<char> buffptr(length);
|
2014-08-29 00:49:26 +02:00
|
|
|
#if !defined(_MSC_VER)
|
2014-05-18 14:28:11 +02:00
|
|
|
size_t printlen = vsnprintf(buffptr.data(), length, fmt, args);
|
2014-08-29 00:49:26 +02:00
|
|
|
#else
|
|
|
|
size_t printlen = vsnprintf_s(buffptr.data(), length, length - 1, fmt, args);
|
|
|
|
#endif
|
2014-05-18 14:28:11 +02:00
|
|
|
if (printlen < length)
|
2014-04-01 02:33:55 +02:00
|
|
|
{
|
|
|
|
str = std::string(buffptr.data(), printlen);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
length *= 2;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::FormatV(std::string fmt, va_list args)
|
|
|
|
{
|
|
|
|
std::string str = FormatV(fmt.c_str(), args);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2014-06-07 16:15:49 +02:00
|
|
|
std::string replace_first(const std::string& src, const std::string& from, const std::string& to)
|
|
|
|
{
|
|
|
|
auto pos = src.find(from);
|
|
|
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
{
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string replace_all(std::string src, const std::string& from, const std::string& to)
|
|
|
|
{
|
|
|
|
for (auto pos = src.find(from); pos != std::string::npos; src.find(from, pos + 1))
|
|
|
|
{
|
|
|
|
src = (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length());
|
|
|
|
pos += to.length();
|
|
|
|
}
|
|
|
|
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
2014-06-08 23:02:20 +02:00
|
|
|
//TODO: move this wx Stuff somewhere else
|
|
|
|
//convert a wxString to a std::string encoded in utf8
|
|
|
|
//CAUTION, only use this to interface with wxWidgets classes
|
|
|
|
std::string fmt::ToUTF8(const wxString& right)
|
|
|
|
{
|
|
|
|
auto ret = std::string(((const char *)right.utf8_str()));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//convert a std::string encoded in utf8 to a wxString
|
|
|
|
//CAUTION, only use this to interface with wxWidgets classes
|
|
|
|
wxString fmt::FromUTF8(const std::string& right)
|
|
|
|
{
|
|
|
|
auto ret = wxString::FromUTF8(right.c_str());
|
|
|
|
return ret;
|
|
|
|
}
|
2014-04-01 02:33:55 +02:00
|
|
|
|
|
|
|
//TODO: remove this after every snippet that uses it is gone
|
|
|
|
//WARNING: not fully compatible with CmpNoCase from wxString
|
|
|
|
int fmt::CmpNoCase(const std::string& a, const std::string& b)
|
|
|
|
{
|
|
|
|
if (a.length() != b.length())
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return std::equal(a.begin(),
|
|
|
|
a.end(),
|
|
|
|
b.begin(),
|
|
|
|
[](const char& a, const char& b){return tolower(a) == tolower(b); })
|
|
|
|
? 0 : -1;
|
|
|
|
}
|
2014-05-02 08:30:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: remove this after every snippet that uses it is gone
|
|
|
|
//WARNING: not fully compatible with CmpNoCase from wxString
|
|
|
|
void fmt::Replace(std::string &str, const std::string &searchterm, const std::string& replaceterm)
|
|
|
|
{
|
|
|
|
size_t cursor = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
cursor = str.find(searchterm, cursor);
|
|
|
|
if (cursor != std::string::npos)
|
|
|
|
{
|
|
|
|
str.replace(cursor, searchterm.size(), replaceterm);
|
|
|
|
cursor += replaceterm.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> fmt::rSplit(const std::string& source, const std::string& delim)
|
|
|
|
{
|
|
|
|
std::vector<std::string> ret;
|
|
|
|
size_t cursor = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
size_t prevcurs = cursor;
|
|
|
|
cursor = source.find(delim, cursor);
|
|
|
|
if (cursor != std::string::npos)
|
|
|
|
{
|
|
|
|
ret.push_back(source.substr(prevcurs,cursor-prevcurs));
|
|
|
|
cursor += delim.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret.push_back(source.substr(prevcurs));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
return ret;
|
2014-04-01 02:33:55 +02:00
|
|
|
}
|