Files
TCPlayerbotCore/src/common/Utilities/Util.cpp
T

613 lines
16 KiB
C++
Raw Normal View History

/*
2015-01-01 00:27:46 +01:00
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "Util.h"
2012-10-03 09:01:59 +02:00
#include "Common.h"
2014-08-05 17:16:53 +02:00
#include "CompilerDefs.h"
2010-06-07 13:20:46 -06:00
#include "utf8.h"
#include "SFMT.h"
#include "Errors.h" // for ASSERT
2014-07-20 02:54:12 +02:00
#include <stdarg.h>
#include <boost/thread/tss.hpp>
#include <boost/algorithm/string/case_conv.hpp>
2009-10-17 15:51:44 -07:00
2014-08-05 17:16:53 +02:00
#if COMPILER == COMPILER_GNU
2014-07-20 02:54:12 +02:00
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
static boost::thread_specific_ptr<SFMTRand> sfmtRand;
static SFMTRand* GetRng()
{
SFMTRand* rand = sfmtRand.get();
if (!rand)
{
rand = new SFMTRand();
sfmtRand.reset(rand);
}
return rand;
}
2009-10-17 15:51:44 -07:00
int32 irand(int32 min, int32 max)
2008-10-02 16:23:55 -05:00
{
ASSERT(max >= min);
return int32(GetRng()->IRandom(min, max));
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
uint32 urand(uint32 min, uint32 max)
2008-10-02 16:23:55 -05:00
{
ASSERT(max >= min);
return GetRng()->URandom(min, max);
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
uint32 urandms(uint32 min, uint32 max)
{
ASSERT(max >= min);
ASSERT(INT_MAX/IN_MILLISECONDS >= max);
return GetRng()->URandom(min * IN_MILLISECONDS, max * IN_MILLISECONDS);
}
float frand(float min, float max)
{
ASSERT(max >= min);
return float(GetRng()->Random() * (max - min) + min);
}
uint32 rand32()
2008-10-02 16:23:55 -05:00
{
return GetRng()->BRandom();
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
double rand_norm()
2008-10-02 16:23:55 -05:00
{
return GetRng()->Random();
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
double rand_chance()
2008-10-02 16:23:55 -05:00
{
return GetRng()->Random() * 100.0;
2008-10-02 16:23:55 -05:00
}
Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve)
2008-10-02 16:23:55 -05:00
{
2010-10-21 16:56:51 +02:00
m_str = new char[src.length() + 1];
memcpy(m_str, src.c_str(), src.length() + 1);
if (vectorReserve)
m_storage.reserve(vectorReserve);
2010-10-21 16:56:51 +02:00
char* posold = m_str;
char* posnew = m_str;
for (;;)
2008-10-02 16:23:55 -05:00
{
2010-10-21 16:56:51 +02:00
if (*posnew == sep)
2008-10-02 16:23:55 -05:00
{
m_storage.push_back(posold);
2010-10-21 16:56:51 +02:00
posold = posnew + 1;
*posnew = '\0';
2008-10-02 16:23:55 -05:00
}
else if (*posnew == '\0')
2008-10-02 16:23:55 -05:00
{
2010-10-21 16:56:51 +02:00
// Hack like, but the old code accepted these kind of broken strings,
// so changing it would break other things
if (posold != posnew)
m_storage.push_back(posold);
2010-10-21 16:56:51 +02:00
break;
2008-10-02 16:23:55 -05:00
}
2010-10-21 16:56:51 +02:00
++posnew;
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void stripLineInvisibleChars(std::string &str)
{
2012-09-04 14:40:41 +02:00
static std::string const invChars = " \t\7\n";
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
size_t wpos = 0;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
bool space = false;
2009-10-17 16:20:24 -07:00
for (size_t pos = 0; pos < str.size(); ++pos)
2008-10-02 16:23:55 -05:00
{
2011-09-29 12:43:05 +02:00
if (invChars.find(str[pos])!=std::string::npos)
2008-10-02 16:23:55 -05:00
{
2011-09-29 12:43:05 +02:00
if (!space)
2008-10-02 16:23:55 -05:00
{
str[wpos++] = ' ';
space = true;
}
}
else
{
2011-09-29 12:43:05 +02:00
if (wpos!=pos)
2008-10-02 16:23:55 -05:00
str[wpos++] = str[pos];
else
++wpos;
space = false;
}
}
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
if (wpos < str.size())
2011-04-29 20:47:02 +02:00
str.erase(wpos, str.size());
2011-09-29 12:43:05 +02:00
if (str.find("|TInterface")!=std::string::npos)
str.clear();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2014-06-22 16:29:49 +02:00
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
2014-06-22 15:42:46 +02:00
struct tm* localtime_r(const time_t* time, struct tm *result)
2014-06-08 20:08:43 +02:00
{
2014-06-22 15:42:46 +02:00
localtime_s(result, time);
return result;
2014-06-08 20:08:43 +02:00
}
2014-06-22 16:29:49 +02:00
#endif
2014-06-08 20:08:43 +02:00
std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
2008-10-02 16:23:55 -05:00
{
uint64 secs = timeInSecs % MINUTE;
uint64 minutes = timeInSecs % HOUR / MINUTE;
uint64 hours = timeInSecs % DAY / HOUR;
uint64 days = timeInSecs / DAY;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
std::ostringstream ss;
2011-09-29 12:43:05 +02:00
if (days)
2011-10-18 14:59:23 +02:00
ss << days << (shortText ? "d" : " Day(s) ");
2011-09-29 12:43:05 +02:00
if (hours || hoursOnly)
2011-10-18 14:59:23 +02:00
ss << hours << (shortText ? "h" : " Hour(s) ");
2011-09-29 12:43:05 +02:00
if (!hoursOnly)
2008-10-02 16:23:55 -05:00
{
2011-09-29 12:43:05 +02:00
if (minutes)
2011-10-18 14:59:23 +02:00
ss << minutes << (shortText ? "m" : " Minute(s) ");
2011-09-29 12:43:05 +02:00
if (secs || (!days && !hours && !minutes) )
2008-10-02 16:23:55 -05:00
ss << secs << (shortText ? "s" : " Second(s).");
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return ss.str();
}
2009-10-17 15:51:44 -07:00
int64 MoneyStringToMoney(const std::string& moneyString)
{
int64 money = 0;
if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
return 0; // Bad format
Tokenizer tokens(moneyString, ' ');
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
std::string tokenString(*itr);
2012-12-31 20:43:14 +01:00
size_t gCount = std::count(tokenString.begin(), tokenString.end(), 'g');
size_t sCount = std::count(tokenString.begin(), tokenString.end(), 's');
size_t cCount = std::count(tokenString.begin(), tokenString.end(), 'c');
if (gCount + sCount + cCount != 1)
return 0;
2014-12-29 01:00:16 +01:00
uint64 amount = atoull(*itr);
if (gCount == 1)
money += amount * 100 * 100;
else if (sCount == 1)
money += amount * 100;
else if (cCount == 1)
money += amount;
}
return money;
}
2008-12-12 11:21:28 -06:00
uint32 TimeStringToSecs(const std::string& timestring)
2008-10-02 16:23:55 -05:00
{
uint32 secs = 0;
uint32 buffer = 0;
uint32 multiplier = 0;
2009-10-17 15:51:44 -07:00
for (std::string::const_iterator itr = timestring.begin(); itr != timestring.end(); ++itr)
2008-10-02 16:23:55 -05:00
{
2011-09-29 12:43:05 +02:00
if (isdigit(*itr))
2008-10-02 16:23:55 -05:00
{
buffer*=10;
buffer+= (*itr)-'0';
2008-10-02 16:23:55 -05:00
}
else
{
2011-09-29 12:43:05 +02:00
switch (*itr)
2008-10-02 16:23:55 -05:00
{
case 'd': multiplier = DAY; break;
case 'h': multiplier = HOUR; break;
case 'm': multiplier = MINUTE; break;
case 's': multiplier = 1; break;
default : return 0; //bad format
}
buffer*=multiplier;
secs+=buffer;
buffer=0;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return secs;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
std::string TimeToTimestampStr(time_t t)
{
tm aTm;
2014-06-22 15:42:46 +02:00
localtime_r(&t, &aTm);
2008-10-02 16:23:55 -05:00
// YYYY year
// MM month (2 digits 01-12)
// DD day (2 digits 01-31)
// HH hour (2 digits 00-23)
// MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59)
char buf[20];
snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
2008-10-02 16:23:55 -05:00
return std::string(buf);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/// Check if the string is a valid ip address representation
bool IsIPAddress(char const* ipaddress)
{
2011-09-29 12:43:05 +02:00
if (!ipaddress)
2008-10-02 16:23:55 -05:00
return false;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// Let the big boys do it.
2011-04-29 20:47:02 +02:00
// Drawback: all valid ip address formats are recognized e.g.: 12.23, 121234, 0xABCD)
2008-10-02 16:23:55 -05:00
return inet_addr(ipaddress) != INADDR_NONE;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/// create PID file
2008-12-12 11:21:28 -06:00
uint32 CreatePIDFile(const std::string& filename)
2008-10-02 16:23:55 -05:00
{
FILE* pid_file = fopen (filename.c_str(), "w" );
2008-10-02 16:23:55 -05:00
if (pid_file == NULL)
return 0;
2009-10-17 15:51:44 -07:00
#ifdef _WIN32
2008-10-02 16:23:55 -05:00
DWORD pid = GetCurrentProcessId();
#else
pid_t pid = getpid();
#endif
2009-10-17 15:51:44 -07:00
fprintf(pid_file, "%u", pid );
2008-10-02 16:23:55 -05:00
fclose(pid_file);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return (uint32)pid;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
size_t utf8length(std::string& utf8str)
{
try
{
2011-04-29 20:47:02 +02:00
return utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
2008-10-02 16:23:55 -05:00
}
catch(std::exception)
{
utf8str.clear();
2008-10-02 16:23:55 -05:00
return 0;
}
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
void utf8truncate(std::string& utf8str, size_t len)
2008-10-02 16:23:55 -05:00
{
try
{
2011-04-29 20:47:02 +02:00
size_t wlen = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
2011-09-29 12:43:05 +02:00
if (wlen <= len)
2008-10-02 16:23:55 -05:00
return;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
std::wstring wstr;
wstr.resize(wlen);
2011-04-29 20:47:02 +02:00
utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]);
2008-10-02 16:23:55 -05:00
wstr.resize(len);
2011-04-29 20:47:02 +02:00
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str[0]);
2008-10-02 16:23:55 -05:00
utf8str.resize(oend-(&utf8str[0])); // remove unused tail
}
catch(std::exception)
{
utf8str.clear();
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
{
try
{
2011-04-29 20:47:02 +02:00
size_t len = utf8::distance(utf8str, utf8str+csize);
2011-09-29 12:43:05 +02:00
if (len > wsize)
2008-10-02 16:23:55 -05:00
{
2011-09-29 12:43:05 +02:00
if (wsize > 0)
wstr[0] = L'\0';
2008-10-02 16:23:55 -05:00
wsize = 0;
return false;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
wsize = len;
2011-04-29 20:47:02 +02:00
utf8::utf8to16(utf8str, utf8str+csize, wstr);
2008-10-02 16:23:55 -05:00
wstr[len] = L'\0';
}
catch(std::exception)
{
2011-09-29 12:43:05 +02:00
if (wsize > 0)
wstr[0] = L'\0';
2008-10-02 16:23:55 -05:00
wsize = 0;
return false;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
2008-10-02 16:23:55 -05:00
{
try
{
if (size_t len = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size()))
{
wstr.resize(len);
2011-04-29 20:47:02 +02:00
utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]);
}
2008-10-02 16:23:55 -05:00
}
catch(std::exception)
{
wstr.clear();
2008-10-02 16:23:55 -05:00
return false;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
{
try
{
std::string utf8str2;
utf8str2.resize(size*4); // allocate for most long case
2009-10-17 15:51:44 -07:00
if (size)
{
2011-04-29 20:47:02 +02:00
char* oend = utf8::utf16to8(wstr, wstr+size, &utf8str2[0]);
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
}
2008-10-02 16:23:55 -05:00
utf8str = utf8str2;
}
catch(std::exception)
{
utf8str.clear();
2008-10-02 16:23:55 -05:00
return false;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str)
2008-10-02 16:23:55 -05:00
{
try
{
std::string utf8str2;
utf8str2.resize(wstr.size()*4); // allocate for most long case
2009-10-17 15:51:44 -07:00
if (wstr.size())
{
2011-04-29 20:47:02 +02:00
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str2[0]);
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
}
2008-10-02 16:23:55 -05:00
utf8str = utf8str2;
}
catch(std::exception)
{
utf8str.clear();
2008-10-02 16:23:55 -05:00
return false;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
typedef wchar_t const* const* wstrlist;
2009-10-17 15:51:44 -07:00
std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension)
2008-10-02 16:23:55 -05:00
{
// supported only Cyrillic cases
2011-09-29 12:43:05 +02:00
if (wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5)
2008-10-02 16:23:55 -05:00
return wname;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
static wchar_t const a_End[] = { wchar_t(1), wchar_t(0x0430), wchar_t(0x0000)};
static wchar_t const o_End[] = { wchar_t(1), wchar_t(0x043E), wchar_t(0x0000)};
static wchar_t const ya_End[] = { wchar_t(1), wchar_t(0x044F), wchar_t(0x0000)};
static wchar_t const ie_End[] = { wchar_t(1), wchar_t(0x0435), wchar_t(0x0000)};
static wchar_t const i_End[] = { wchar_t(1), wchar_t(0x0438), wchar_t(0x0000)};
static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B), wchar_t(0x0000)};
static wchar_t const u_End[] = { wchar_t(1), wchar_t(0x0443), wchar_t(0x0000)};
static wchar_t const yu_End[] = { wchar_t(1), wchar_t(0x044E), wchar_t(0x0000)};
static wchar_t const oj_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const o_m_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C), wchar_t(0x0000)};
static wchar_t const j_End[] = { wchar_t(1), wchar_t(0x0439), wchar_t(0x0000)};
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
static wchar_t const* const dropEnds[6][8] = {
{ &a_End[1], &o_End[1], &ya_End[1], &ie_End[1], &soft_End[1], &j_End[1], NULL, NULL },
{ &a_End[1], &ya_End[1], &yeru_End[1], &i_End[1], NULL, NULL, NULL, NULL },
{ &ie_End[1], &u_End[1], &yu_End[1], &i_End[1], NULL, NULL, NULL, NULL },
{ &u_End[1], &yu_End[1], &o_End[1], &ie_End[1], &soft_End[1], &ya_End[1], &a_End[1], NULL },
{ &oj_End[1], &io_j_End[1], &ie_j_End[1], &o_m_End[1], &io_m_End[1], &ie_m_End[1], &yu_End[1], NULL },
{ &ie_End[1], &i_End[1], NULL, NULL, NULL, NULL, NULL, NULL }
};
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
for (wchar_t const* const* itr = &dropEnds[declension][0]; *itr; ++itr)
2008-10-02 16:23:55 -05:00
{
size_t len = size_t((*itr)[-1]); // get length from string size field
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
if (wname.substr(wname.size()-len, len)==*itr)
2011-04-29 20:47:02 +02:00
return wname.substr(0, wname.size()-len);
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return wname;
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
bool utf8ToConsole(const std::string& utf8str, std::string& conStr)
2008-10-02 16:23:55 -05:00
{
#if PLATFORM == PLATFORM_WINDOWS
std::wstring wstr;
2011-09-29 12:43:05 +02:00
if (!Utf8toWStr(utf8str, wstr))
2008-10-02 16:23:55 -05:00
return false;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
conStr.resize(wstr.size());
2011-04-29 20:47:02 +02:00
CharToOemBuffW(&wstr[0], &conStr[0], wstr.size());
2008-10-02 16:23:55 -05:00
#else
// not implemented yet
conStr = utf8str;
#endif
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
bool consoleToUtf8(const std::string& conStr, std::string& utf8str)
2008-10-02 16:23:55 -05:00
{
#if PLATFORM == PLATFORM_WINDOWS
std::wstring wstr;
wstr.resize(conStr.size());
2011-04-29 20:47:02 +02:00
OemToCharBuffW(&conStr[0], &wstr[0], conStr.size());
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
return WStrToUtf8(wstr, utf8str);
2008-10-02 16:23:55 -05:00
#else
// not implemented yet
utf8str = conStr;
return true;
#endif
}
2009-10-17 15:51:44 -07:00
bool Utf8FitTo(const std::string& str, std::wstring const& search)
2008-10-02 16:23:55 -05:00
{
std::wstring temp;
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
if (!Utf8toWStr(str, temp))
2008-10-02 16:23:55 -05:00
return false;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// converting to lower case
wstrToLower( temp );
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
if (temp.find(search) == std::wstring::npos)
2008-10-02 16:23:55 -05:00
return false;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
void utf8printf(FILE* out, const char *str, ...)
{
va_list ap;
va_start(ap, str);
2010-05-13 00:15:21 +02:00
vutf8printf(out, str, &ap);
va_end(ap);
}
2009-10-17 15:51:44 -07:00
void vutf8printf(FILE* out, const char *str, va_list* ap)
{
#if PLATFORM == PLATFORM_WINDOWS
char temp_buf[32*1024];
wchar_t wtemp_buf[32*1024];
2009-10-17 15:51:44 -07:00
size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
//vsnprintf returns -1 if the buffer is too small
if (temp_len == size_t(-1))
temp_len = 32*1024-1;
2009-10-17 15:51:44 -07:00
size_t wtemp_len = 32*1024-1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
2009-10-17 15:51:44 -07:00
CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);
fprintf(out, "%s", temp_buf);
#else
vfprintf(out, str, *ap);
#endif
}
2009-10-17 15:51:44 -07:00
2014-05-06 23:43:29 +02:00
bool Utf8ToUpperOnlyLatin(std::string& utf8String)
{
std::wstring wstr;
if (!Utf8toWStr(utf8String, wstr))
return false;
std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
return WStrToUtf8(wstr, utf8String);
}
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
{
int32 init = 0;
int32 end = arrayLen;
int8 op = 1;
if (reverse)
{
init = arrayLen - 1;
end = -1;
op = -1;
}
std::ostringstream ss;
for (int32 i = init; i != end; i += op)
{
char buffer[4];
sprintf(buffer, "%02X", bytes[i]);
ss << buffer;
}
return ss.str();
}
2014-05-02 02:55:10 +02:00
void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/)
{
// string must have even number of characters
if (str.length() & 1)
return;
int32 init = 0;
int32 end = str.length();
int8 op = 1;
if (reverse)
{
init = str.length() - 2;
2014-05-04 00:59:24 +02:00
end = -2;
2014-05-02 02:55:10 +02:00
op = -1;
}
uint32 j = 0;
for (int32 i = init; i != end; i += 2 * op)
{
char buffer[3] = { str[i], str[i + 1], '\0' };
out[j++] = strtoul(buffer, NULL, 16);
}
}
bool StringToBool(std::string const& str)
{
std::string lowerStr = boost::algorithm::to_lower_copy(str);
return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes";
}