Files
Tools_CPP/lib/stdTools.cpp
2024-11-18 21:19:07 +05:00

2263 lines
70 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//---------------------------------------------------------------------------
//#pragma hdrstop
//---------------------------------------------------------------------------
#define _CRT_SECURE_NO_WARNINGS
//---------------------------------------------------------------------------
#ifdef _WIN32
#define NOMINMAX
#endif // _WIN32
//---------------------------------------------------------------------------
#include "stdTools.h"
//#include "mathTools.h"
#include <cstdint>
//#include <Math.h>
#include <list>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <locale>
#include <codecvt>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <ctime>
#include <limits> //min max
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
#include <windows.h>
//#include <minwinbase.h>
#include <winnt.h>
//#include <fileapi.h>
#include <shlobj.h>
#else
//#include <chrono>
#include <sys/time.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#endif
#include <sys/stat.h> //mkdir
#include <iostream>
#include <clocale>
#include <cstring>
#include <cstdlib>
namespace Utility
{
//---------------------------------------------------------------------------
std::string sp3()
{
#if defined _WIN32 || defined __CYGWIN__
return "\\";
#else
return "/";
#endif
}
//------------------------------------------------------------------------------
//Разделитель для директорий
char separator()
{
#ifdef _WIN32
return '\\';
#else
return '/';
#endif
}
//---------------------------------------------------------------------------
std::string base64_encode(const std::string &in) {
std::string out;
#if defined(__BORLANDC__)
#else
int val = 0, valb = -6;
for (unsigned char c : in) {
val = (val << 8) + c;
valb += 8;
while (valb >= 0) {
out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]);
while (out.size() % 4) out.push_back('=');
#endif
return out;
}
//---------------------------------------------------------------------------
std::string base64_decode(const std::string &in) {
std::string out;
#if defined(__BORLANDC__)
#else
std::vector<int> T(256, -1);
for (int i = 0; i<64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
int val = 0, valb = -8;
for (unsigned char c : in) {
if (T[c] == -1) break;
val = (val << 6) + T[c];
valb += 6;
if (valb >= 0) {
out.push_back(char((val >> valb) & 0xFF));
valb -= 8;
}
}
#endif
return out;
}
//------------------------------------------------------------------------------
//Преобразовать HEX символ в число (вынужденный повтор чтобы не инклюдить большой файл)
int hexCharToIntTMP(char input)
{
if(input >= '0' && input <= '9')
return input - '0';
if(input >= 'A' && input <= 'F')
return input - 'A' + 10;
if(input >= 'a' && input <= 'f')
return input - 'a' + 10;
throw std::invalid_argument("Invalid input string");
}
//------------------------------------------------------------------------------
uint16_t hexString2ToUint(std::string &str, int pos,bool cut)
{
uint16_t result;
((uint8_t*)&result)[0] = hexCharToIntTMP(str[pos]) * 16 + hexCharToIntTMP(str[pos + 1]);
((uint8_t*)&result)[1] = hexCharToIntTMP(str[pos + 2]) * 16 + hexCharToIntTMP(str[pos + 3]);
if (cut)
{
str = str.substr(0, pos) + str.substr(pos+4);
}
return result;
}
//---------------------------------------------------------------------------
uint32_t hexString4ToUint(std::string &str, int pos, bool cut)
{
uint32_t result=0;
((uint8_t*)&result)[0] = hexCharToIntTMP(str[pos]) * 16 + hexCharToIntTMP(str[pos + 1]);
((uint8_t*)&result)[1] = hexCharToIntTMP(str[pos + 2]) * 16 + hexCharToIntTMP(str[pos + 3]);
((uint8_t*)&result)[2] = hexCharToIntTMP(str[pos + 4]) * 16 + hexCharToIntTMP(str[pos + 5]);
((uint8_t*)&result)[3] = hexCharToIntTMP(str[pos + 6]) * 16 + hexCharToIntTMP(str[pos + 7]);
if (cut)
{
str = str.substr(0, pos) + str.substr(pos + 8);
}
return result;
}
//---------------------------------------------------------------------------
uint64_t hexString6ToUint(std::string &str, int pos, bool cut)
{
uint64_t result=0;
((uint8_t*)&result)[0] = hexCharToIntTMP(str[pos]) * 16 + hexCharToIntTMP(str[pos+1]);
((uint8_t*)&result)[1] = hexCharToIntTMP(str[pos + 2]) * 16 + hexCharToIntTMP(str[pos + 3]);
((uint8_t*)&result)[2] = hexCharToIntTMP(str[pos + 4]) * 16 + hexCharToIntTMP(str[pos + 5]);
((uint8_t*)&result)[3] = hexCharToIntTMP(str[pos + 6]) * 16 + hexCharToIntTMP(str[pos + 7]);
((uint8_t*)&result)[4] = hexCharToIntTMP(str[pos + 8]) * 16 + hexCharToIntTMP(str[pos + 9]);
((uint8_t*)&result)[5] = hexCharToIntTMP(str[pos + 10]) * 16 + hexCharToIntTMP(str[pos + 11]);
if (cut)
{
str = str.substr(0, pos) + str.substr(pos + 12);
}
return result;
}
//---------------------------------------------------------------------------
//Прочитать файл в строку
std::string readFileToString(std::string fName){
std::ifstream t(fName);
std::stringstream buffer;
buffer << t.rdbuf();
return buffer.str();
}
//------------------------------------------------------------------------------
bool deleteFile(std::string fileName)
{
bool result=false;
#ifdef __linux__
if(unlink(fileName.c_str())==0)
{
result=true;
}
#elif _WIN32
if(remove(fileName.c_str())==0)
{
result=true;
}
#endif
return result;
}
//---------------------------------------------------------------------------
//Получить дату последнего изменения файла
long getFileDateModiff(std::string file)
{
#ifdef __linux__
struct stat fStat;
int rc = stat(file.c_str(), &fStat);
if(rc==0)
{
return fStat.st_mtim.tv_sec;
}
return 0;
#elif _WIN32
return 0;
#else
#endif
}
//------------------------------------------------------------------------------
//удалить старые файлы которые были созданы больше заданного количества дней
bool deleteOldFiles(std::string path,int days)
{
bool result=true;
std::list<std::string> fileList;
Utility::getFiles(fileList,path);
std::list<std::string>::const_iterator iterator;
for (iterator = fileList.begin(); iterator != fileList.end(); ++iterator) {
std::string fName = *iterator;
long timeS = getFileDateModiff(fName);
int tNow=std::time(NULL);
int tDiff = tNow-timeS;
if(tDiff > days*24*60*60) {
if(!deleteFile(fName)) {
result=result & false;
}
}
}
return result;
}
//---------------------------------------------------------------------------
//Найти файлы в директории и под директории и добавить их в список
void getFiles(std::list<std::string>& fileList, std::string directory)
{
if(directory.length()>0 && directory[directory.length()-1]!=separator()) directory+=separator();
#ifdef __linux__
DIR *dir = opendir(directory.c_str());
if(dir)
{
struct dirent *ent;
while((ent = readdir(dir)) != NULL)
{
if(ent->d_type==0x04)
{
if ((strncmp(".", ent->d_name, 1) != 0) && (strncmp("..", ent->d_name, 2) != 0))
{
std::string newDir = directory + ent->d_name+"/";
Utility::getFiles(fileList, newDir);
}
}
else
if(ent->d_type==0x08)
{
std::string fWName = ent->d_name;
fWName = directory + fWName;
fileList.push_back(fWName);
}
}
closedir(dir);
}
#elif _WIN32
HANDLE hFind;
WIN32_FIND_DATAA FindFileData;
if ((hFind = FindFirstFileA((std::string(directory+"*.*")).c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) {
do {
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes)
{
if ((strncmp(".", FindFileData.cFileName, 1) != 0) && (strncmp("..", FindFileData.cFileName, 2) != 0))
{
std::string newDir = directory + FindFileData.cFileName+"\\";
Utility::getFiles(fileList, newDir);
}
}
else
{
std::string fWName = FindFileData.cFileName;
fWName = directory + fWName;
fileList.push_back(fWName);
}
} while (FindNextFileA(hFind, &FindFileData));
FindClose(hFind);
}
#else
#endif
}
//---------------------------------------------------------------------------
//Читаем до символа перехода на новую строку
std::wstring readUTF16LEString(FILE* fp)
{
std::wstring result=L"";
wchar_t ch;
while( !feof( fp) )
{
size_t count = fread( &((char*)&ch)[0], 1, 1, fp);
if(count==1)
{
count = fread( &((char*)&ch)[1], 1, 1, fp);
if(count==1)
{
if(ch==10) break; //L'\n'
if(ch!=13) //L'\r'
result+=ch;
}
}
}
return result;
}
//---------------------------------------------------------------------------
//Прочитать первый попавшийся UTF-16 (LE) FF FE во всём файле
bool seekToLEBOM(FILE* fp)
{
bool result = false;
unsigned char ch;
while( !feof( fp) )
{
size_t count = fread( &ch, 1, 1, fp);
if(count==1 && ch==0xFF)
{
count = fread( &ch, 1, 1, fp);
if(count==1 && ch==0xFE)
{
result=true;
break;
}
}
}
return result;
}
//---------------------------------------------------------------------------
//Читать в строку до первого попавшегося символа (в результате этого символа не будет)
std::string readString(FILE* fp,char ch)
{
std::string result="";
char tmp;
while( !feof( fp) )
{
size_t count = fread( &tmp, 1, 1, fp);
if(count==1)
{
if(tmp==ch)
break;
result+=tmp;
}
}
return result;
}
//---------------------------------------------------------------------------
int readFile(FILE* fp,char* data,int len)
{
int result=0;
while( !feof( fp) )
{
size_t count = fread( &data[result], 1, 1, fp);
if(count==1)
{
result++;
if(result>=len)
break;
}
}
return result;
}
//---------------------------------------------------------------------------
std::string lowerCaseENG(std::string str)
{
std::string result;
for(int i=0;i<(int)str.length();i++)
{
if(str[i]<='Z' && str[i]>='A')
result += str[i]-('Z'-'z');
else
result += str[i];
}
return result;
}
//---------------------------------------------------------------------------
/*char easytolower(char in){
if(in<='Z' && in>='A')
return in-('Z'-'z');
return in;
}*/
//---------------------------------------------------------------------------
//#include <atlbase.h> //Зло :-)
//#include "stdafx.h"
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
#if defined( _VC )
#include < ctime >
#endif
#if defined( _BORLAND )
#include <vcl.h>
#endif
#include <Windows.h> //Для Windows
#include <sys\types.h>
#include <sys\stat.h>
#else
#include <iconv.h>
#endif
//#include <time.h> //Функция времени
#include "tcDebug.h"
//---------------------------------------------------------------------------
//260 was taken from windef.h
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
//---------------------------------------------------------------------------
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
//---------------------------------------------------------------------------
/*template <typename T>
std::string toStdStr(T val)
{
std::ostringstream oss;
oss << val;
return oss.str();
}*/
//---------------------------------------------------------------------------
//Большее из 2х
/*int MaxI4(int v1,int v2)
{ if(v1>v2) return v1; else return v2;
}*/
//---------------------------------------------------------------------------
/*std::wstring s2ws(const std::string& str)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
int len;
int slength = (int)str.length();// + 1;
if(slength==0) return L"";
len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, 0, 0);
std::wstring rez(len, L'\0');
MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, &rez[0], len);
//Каз. символы из ASCII в UTF16 в ручную переводим
for(size_t i=0;i<str.length();i++)
{
switch ((char)str[i])
{
case (char)0xA3: rez[i]=L'Ә'; break;// Ә
case (char)0xBC: rez[i]=L'ә'; break;// ә
case (char)0xAA: rez[i]=L'Ғ'; break;// Ғ
case (char)0xBA: rez[i]=L'ғ'; break;// ғ
case (char)0x8D: rez[i]=L'Қ'; break;// Қ
case (char)0x9D: rez[i]=L'қ'; break;// қ
case (char)0xBD: rez[i]=L'Ң'; break;// Ң
case (char)0xBE: rez[i]=L'ң'; break;// ң
case (char)0xA5: rez[i]=L'Ө'; break;// Ө
case (char)0xB4: rez[i]=L'ө'; break;// ө
case (char)0xA1: rez[i]=L'Ұ'; break;// Ұ
case (char)0xA2: rez[i]=L'ұ'; break;// ұ
case (char)0xAF: rez[i]=L'Ү'; break;// Ү
case (char)0xBF: rez[i]=L'ү'; break;// ү
case (char)0x8E: rez[i]=L'Һ'; break;// Һ
case (char)0x9E: rez[i]=L'һ'; break;// һ
//case (char)0xB2: rez[i]=L'І'; break;// І
//case (char)0xB3: rez[i]=L'i'; break;// i
case (char)0xB9: rez[i]=L'№'; break;
}
}
return rez;
#else
std::wstring result;
const char* pt = s.c_str();
size_t max = s.length();
int length;
wchar_t dest;
mbtowc (NULL, NULL, 0);
while (max>0)
{
length = mbtowc(&dest,pt,max);
if (length<1) break;
result+=dest;
pt+=length; max-=length;
}
return result;
#endif
return L"";
}*/
//---------------------------------------------------------------------------
//Размер файла в байтах
long getFileSize(std::string filename)
{
//#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
// unsigned long FileSize = 0;
// HANDLE hF = CreateFile(
// filename.c_str(), // file name
// GENERIC_READ, // access mode
// 0, // share mode
// NULL, // SD
// OPEN_EXISTING, // how to create
// 0, // file attributes
// NULL // handle to template file
// );
// FileSize = GetFileSize(hF, NULL);
// CloseHandle(hF);
// return FileSize;
//#else
std::ifstream in(filename.c_str(), std::ifstream::ate | std::ifstream::binary);
return (long)in.tellg();
//struct stat stat_buf;
//int rc = stat(filename.c_str(), &stat_buf);
//return rc == 0 ? stat_buf.st_size : -1;
//#endif
}
//---------------------------------------------------------------------------
//Размер файла в байтах
long GetWFileSize(std::wstring filename)
{
std::string str = WStringToString(filename,std::locale(""));
std::wifstream in(str.c_str(), std::wifstream::ate | std::wifstream::binary);
return (long)in.tellg();
}
//---------------------------------------------------------------------------
//Сохранение лог файла по 10 мегабайт (в 2 файлика)
bool logrotateW(std::wstring fileName, std::wstring data)
{
long fileSize = GetWFileSize(fileName);
//Переименовываем файл если он привысил размер
if(fileSize>1024*1024*10)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
//_wrename(fileName.c_str(),std::wstring(fileName+L".1").c_str());
std::string str = WStringToString(fileName,std::locale(""),'?');
std::rename(str.c_str(),std::string(str+".1").c_str());
#else
std::string str = WStringToString(fileName,std::locale(""));
rename(str.c_str(),std::string(str+".1").c_str());
#endif
}
//Записываем лог
std::string str = WStringToString(fileName,std::locale(""));
std::ofstream myfile(str.c_str(),std::fstream::app | std::fstream::out);
if (myfile.is_open())
{
myfile << data.c_str();
myfile.flush();
myfile.close();
return true;
}
return false;
}
//---------------------------------------------------------------------------
bool logrotateUTF8(std::wstring fileName, std::wstring data)
{
long fileSize = GetWFileSize(fileName);
//Переименовываем файл если он привысил размер
if (fileSize>1024 * 1024 * 10)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
//_wrename(fileName.c_str(),std::wstring(fileName+L".1").c_str());
std::string str = WStringToString(fileName, std::locale(""));
rename(str.c_str(), std::string(str + ".1").c_str());
#else
std::string str = WStringToString(fileName,std::locale(""));
rename(str.c_str(),std::string(str+".1").c_str());
#endif
}
else if (fileSize == 0 || fileSize == -1) //Записываю сигнатуру то что это UTF8
{
std::string str = WStringToString(fileName,std::locale(""));
std::ofstream myfile(str.c_str(), std::fstream::app | std::fstream::out);
if (myfile.is_open())
{
myfile << (char)0xEF << (char)0xBB << (char)0xBF;
myfile.flush();
myfile.close();
}
}
//Записываем лог
std::string str = WStringToString(fileName,std::locale(""));
std::ofstream myfile(str.c_str(), std::fstream::app | std::fstream::out);
if (myfile.is_open())
{
std::time_t result = std::time(0);
std::string time = std::asctime(std::localtime(&result));
time = time.substr(0, time.length() - 1);
myfile << "[" << time << "] " << convUTF16ToUTF8(data).c_str() << std::endl;
myfile.flush();
myfile.close();
return true;
}
return false;
}
//---------------------------------------------------------------------------
std::string escape_json(const std::string& input) {
std::ostringstream oss;
for (char c : input) {
switch (c) {
case '"': oss << "\\\""; break;
case '\\': oss << "\\\\"; break;
case '\b': oss << "\\b"; break;
case '\f': oss << "\\f"; break;
case '\n': oss << "\\n"; break;
case '\r': oss << "\\r"; break;
case '\t': oss << "\\t"; break;
default:
if (static_cast<unsigned char>(c) < 0x20 || c == 0x7F) {
oss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c);
} else {
oss << c;
}
break;
}
}
return oss.str();
}
//---------------------------------------------------------------------------
//Сохранение лог файла по 10 мегабайт (в 2 файлика) Функция отрабатывает за 4 миллисекунды
/*bool logrotate(std::string fileName, std::string data, bool cout, int size)
{
long fileSize = GetFileSize(fileName);
//Переименовываем файл если он привысил размер
if(fileSize>1024*1024* size)
{
remove(std::string(fileName + ".1").c_str()); //Пытаюсь удалить старый файл
rename(fileName.c_str(),std::string(fileName+".1").c_str());
}
//Записываем лог
std::ofstream myfile(fileName.c_str(), std::ofstream::binary | std::fstream::app);
if (myfile.is_open())
{
std::stringstream str(std::stringstream::out | std::stringstream::binary);
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
SYSTEMTIME st;
GetLocalTime(&st);
//LONG time_ms = (st.wSecond * 1000) + st.wMilliseconds;
//для конвертиции в строку: https://www.technical-recipes.com/2014/converting-a-systemtime-to-a-stdstring-in-c/
char buffer[256];
memset(buffer, 0, sizeof(buffer));
sprintf(buffer,
"%d.%02d.%02d %02d:%02d:%02d.%03d",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
st.wMilliseconds);
str << "[" << buffer << "] " << data << std::endl;
#else
timeval curTime;
gettimeofday(&curTime, NULL);
int milli = curTime.tv_usec / 1000;
std::time_t utime = curTime.tv_sec;
char buffer[80]; memset(buffer, 0, sizeof(buffer));
std::strftime(buffer, sizeof(buffer), "%Y.%m.%d %H:%M:%S", std::localtime(&utime));
str << "[" << buffer << ":" << milli << "] " << data << std::endl;
#endif
if (cout)
std::cout << "[" << buffer << "] " << data << std::endl; //Повтор лога в консоль
myfile.write(str.str().c_str(), str.str().length());
myfile.flush();
myfile.close();
return true;
}else
{
std::cerr << "Error: " << strerror(errno) << " " << fileName << std::endl;
}
return true;
}*/
bool logrotate(std::string fileName, std::string thread, std::string level, std::string data, bool cout, int size)
{
long fileSize = getFileSize(fileName);
//Переименовываем файл если он привысил размер
if(fileSize>1024*1024* size)
{
remove(std::string(fileName + ".1").c_str()); //Пытаюсь удалить старый файл
rename(fileName.c_str(),std::string(fileName+".1").c_str());
}
if(fileSize==-1){
createFolder(BeforeFirst(fileName,separator()));
}
//Записываем лог
std::ofstream myfile(fileName.c_str(), std::ofstream::binary | std::fstream::app);
if (myfile.is_open())
{
std::stringstream str(std::stringstream::out | std::stringstream::binary);
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
SYSTEMTIME st;
GetLocalTime(&st);
char buffer[256];
memset(buffer, 0, sizeof(buffer));
sprintf(buffer,
"%d-%02d-%02d %02d:%02d:%02d.%03d",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
st.wMilliseconds);
str << "[" << buffer << "] " << data << std::endl;
#else
timeval curTime;
gettimeofday(&curTime, NULL);
int milli = curTime.tv_usec / 1000;
std::time_t utime = curTime.tv_sec;
char buffer[80]; memset(buffer, 0, sizeof(buffer));
std::strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", std::localtime(&utime));
str << "{\"timestamp\":\"" << buffer << "." << std::setw(3) << std::setfill('0') << milli << "Z\", \"thread\":\"" <<thread<<"\", \"level\":\""<<level<<"\", \"message\":\"" << escape_json(data)<<"\"}" << std::endl;
#endif
if (cout)
std::cout << "[" << buffer << "] " << data << std::endl; //Повтор лога в консоль
myfile.write(str.str().c_str(), str.str().length());
myfile.flush();
myfile.close();
return true;
}else
{
std::cerr << "Error: " << strerror(errno) << " " << fileName << std::endl;
}
return true;
}
//---------------------------------------------------------------------------
bool fileExists(std::string name)
{
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
//---------------------------------------------------------------------------
std::string ws2s(const std::wstring& str)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
int len;
int slength = (int)str.length();// + 1;
if(slength==0) return "";
len = WideCharToMultiByte(CP_ACP, 0, str.c_str(), slength, 0, 0, 0, 0);
std::string rez(len, '\0');
WideCharToMultiByte(CP_ACP, 0, str.c_str(), slength, &rez[0], len, 0, 0);
//Каз символы из UTF16 в ASCII в ручную переводим
for(size_t i=0;i<str.length();i++)
{
switch (str[i])
{
case L'Ә': rez[i]=(char)0xA3; break;// Ә
case L'ә': rez[i]=(char)0xBC; break;// ә
case L'Ғ': rez[i]=(char)0xAA; break;// Ғ
case L'ғ': rez[i]=(char)0xBA; break;// ғ
case L'Қ': rez[i]=(char)0x8D; break;// Қ
case L'қ': rez[i]=(char)0x9D; break;// қ
case L'Ң': rez[i]=(char)0xBD; break;// Ң
case L'ң': rez[i]=(char)0xBE; break;// ң
case L'Ө': rez[i]=(char)0xA5; break;// Ө
case L'ө': rez[i]=(char)0xB4; break;// ө
case L'Ұ': rez[i]=(char)0xA1; break;// Ұ
case L'ұ': rez[i]=(char)0xA2; break;// ұ
case L'Ү': rez[i]=(char)0xAF; break;// Ү
case L'ү': rez[i]=(char)0xBF; break;// ү
case L'Һ': rez[i]=(char)0x8E; break;// Һ
case L'һ': rez[i]=(char)0x9E; break;// һ
//case L'І': rez[i]=(char)0xB2; break;// І
//case L'i': rez[i]=(char)0xB3; break;// i
case 10402: rez[i]=(char)0xB9; break;//L'№'
}
}
return rez;
#else
std::string result( str.begin(), str.end() );
return result;
#endif
return "";
}
//---------------------------------------------------------------------------
//Конвертнуть Win1251 в utf8 //TRANSLIT//IGNORE
std::string iConvert(const std::string& instr,const char* fromCode,const char* toCode)
{
std::string outstr;
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
#else
iconv_t cd = iconv_open(toCode, fromCode);
if( cd == (iconv_t)(-1) )
throw std::runtime_error("Не удалось открыть дескриптор iconv");
size_t in_size = instr.size();
char* inPrt = (char*)instr.c_str();
int BUF_SIZE=in_size*4;
char* out_buf = new char[BUF_SIZE];
char* outPtr;
size_t out_size;
size_t rSize;
while(in_size > 0)
{
outPtr = out_buf;
out_size = BUF_SIZE;
rSize = iconv(cd, &inPrt, &in_size, &outPtr, &out_size );
if(rSize == (size_t)-1 && errno)
{
switch (errno)
{
case EILSEQ:
throw std::runtime_error("invalid multibyte chars");
case EINVAL:
throw std::runtime_error("invalid multibyte chars");
default:
throw std::runtime_error("unknown error");
}
}
outstr.append(out_buf,BUF_SIZE-out_size);
}
if(iconv_close(cd)!=0 )
std::runtime_error("Не удается закрыть дескриптор iconv");
delete[] out_buf;
#endif
return outstr;
}
//---------------------------------------------------------------------------
//Конвертим из Unicode в DOS 866 кодировку
std::string UnicodeToDOS886(std::wstring str)
{
std::string rez;
rez.reserve(str.length()); //Количество символов не должно измениться
for(unsigned int i=0;i<str.length();i++)
{
switch(str[i])
{
case L'А': rez+=(char)0x80; break;
case L'Б': rez+=(char)0x81; break;
case L'В': rez+=(char)0x82; break;
case L'Г': rez+=(char)0x83; break;
case L'Д': rez+=(char)0x84; break;
case L'Е': rez+=(char)0x85; break;
case L'Ё': rez+=(char)0x85; break; //case L'Ё': rez+=(char)0xF0; break;
case L'Ж': rez+=(char)0x86; break;
case L'З': rez+=(char)0x87; break;
case L'И': rez+=(char)0x88; break;
case L'Й': rez+=(char)0x89; break;
case L'К': rez+=(char)0x8A; break;
case L'Л': rez+=(char)0x8B; break;
case L'М': rez+=(char)0x8C; break;
case L'Н': rez+=(char)0x8D; break;
case L'О': rez+=(char)0x8E; break;
case L'П': rez+=(char)0x8F; break;
case L'Р': rez+=(char)0x90; break;
case L'С': rez+=(char)0x91; break;
case L'Т': rez+=(char)0x92; break;
case L'У': rez+=(char)0x93; break;
case L'Ф': rez+=(char)0x94; break;
case L'Х': rez+=(char)0x95; break;
case L'Ц': rez+=(char)0x96; break;
case L'Ч': rez+=(char)0x97; break;
case L'Ш': rez+=(char)0x98; break;
case L'Щ': rez+=(char)0x99; break;
case L'Ъ': rez+=(char)0x9A; break;
case L'Ы': rez+=(char)0x9B; break;
case L'Ь': rez+=(char)0x9C; break;
case L'Э': rez+=(char)0x9D; break;
case L'Ю': rez+=(char)0x9E; break;
case L'Я': rez+=(char)0x9F; break;
case L'а': rez+=(char)0xA0; break;
case L'б': rez+=(char)0xA1; break;
case L'в': rez+=(char)0xA2; break;
case L'г': rez+=(char)0xA3; break;
case L'д': rez+=(char)0xA4; break;
case L'е': rez+=(char)0xA5; break;
case L'ё': rez+=(char)0xA5; break; //case L'ё': rez+=(char)0xF1; break;
case L'ж': rez+=(char)0xA6; break;
case L'з': rez+=(char)0xA7; break;
case L'и': rez+=(char)0xA8; break;
case L'й': rez+=(char)0xA9; break;
case L'к': rez+=(char)0xAA; break;
case L'л': rez+=(char)0xAB; break;
case L'м': rez+=(char)0xAC; break;
case L'н': rez+=(char)0xAD; break;
case L'о': rez+=(char)0xAE; break;
case L'п': rez+=(char)0xAF; break;
case L'р': rez+=(char)0xE0; break;
case L'с': rez+=(char)0xE1; break;
case L'т': rez+=(char)0xE2; break;
case L'у': rez+=(char)0xE3; break;
case L'ф': rez+=(char)0xE4; break;
case L'х': rez+=(char)0xE5; break;
case L'ц': rez+=(char)0xE6; break;
case L'ч': rez+=(char)0xE7; break;
case L'ш': rez+=(char)0xE8; break;
case L'щ': rez+=(char)0xE9; break;
case L'ъ': rez+=(char)0xEA; break;
case L'ы': rez+=(char)0xEB; break;
case L'ь': rez+=(char)0xEC; break;
case L'э': rez+=(char)0xED; break;
case L'ю': rez+=(char)0xEE; break;
case L'я': rez+=(char)0xEF; break;
//Каз-яз
/* case L'?': rez+=(char)0xDB; break;
case L'?': rez+=(char)0xDC; break;
case L'?': rez+=(char)0xDE; break;
case L'?': rez+=(char)0xDF; break;
case L'?': rez+=(char)0xF0; break;
case L'?': rez+=(char)0xF1; break;
case L'?': rez+=(char)0xF3; break;
case L'?': rez+=(char)0xF4; break;
case L'?': rez+=(char)0xF5; break;
case L'?': rez+=(char)0xF6; break;
case L'?': rez+=(char)0xF7; break;
case L'?': rez+=(char)0xF8; break;
case L'?': rez+=(char)0xFD; break;
case L'?': rez+=(char)0xFE; break;
*/
default: rez+=(char)str[i]; break;
}
}
return rez;
}
//---------------------------------------------------------------------------
//Обратная конвертация из DOS886 в Unicode
std::wstring DOS886ToUnicode(std::string str)
{
std::wstring rez;
rez.reserve(str.length()); //Количество символов не должно измениться
for(unsigned int i=0;i<str.length();i++)
{
switch(str[i])
{
case (char)0x80: rez+=L'А'; break;
case (char)0x81: rez+=L'Б'; break;
case (char)0x82: rez+=L'В'; break;
case (char)0x83: rez+=L'Г'; break;
case (char)0x84: rez+=L'Д'; break;
case (char)0x85: rez+=L'Е'; break;
//case (char)0xF0: rez+=L'Ё'; break; //В место "Ё" в принтере "?"
case (char)0x86: rez+=L'Ж'; break;
case (char)0x87: rez+=L'З'; break;
case (char)0x88: rez+=L'И'; break;
case (char)0x89: rez+=L'Й'; break;
case (char)0x8A: rez+=L'К'; break;
case (char)0x8B: rez+=L'Л'; break;
case (char)0x8C: rez+=L'М'; break;
case (char)0x8D: rez+=L'Н'; break;
case (char)0x8E: rez+=L'О'; break;
case (char)0x8F: rez+=L'П'; break;
case (char)0x90: rez+=L'Р'; break;
case (char)0x91: rez+=L'С'; break;
case (char)0x92: rez+=L'Т'; break;
case (char)0x93: rez+=L'У'; break;
case (char)0x94: rez+=L'Ф'; break;
case (char)0x95: rez+=L'Х'; break;
case (char)0x96: rez+=L'Ц'; break;
case (char)0x97: rez+=L'Ч'; break;
case (char)0x98: rez+=L'Ш'; break;
case (char)0x99: rez+=L'Щ'; break;
case (char)0x9A: rez+=L'Ъ'; break;
case (char)0x9B: rez+=L'Ы'; break;
case (char)0x9C: rez+=L'Ь'; break;
case (char)0x9D: rez+=L'Э'; break;
case (char)0x9E: rez+=L'Ю'; break;
case (char)0x9F: rez+=L'Я'; break;
case (char)0xA0: rez+=L'а'; break;
case (char)0xA1: rez+=L'б'; break;
case (char)0xA2: rez+=L'в'; break;
case (char)0xA3: rez+=L'г'; break;
case (char)0xA4: rez+=L'д'; break;
case (char)0xA5: rez+=L'е'; break;
//case (char)0xF1: rez+=L'ё'; break; //В место "ё" в принтере "?"
case (char)0xA6: rez+=L'ж'; break;
case (char)0xA7: rez+=L'з'; break;
case (char)0xA8: rez+=L'и'; break;
case (char)0xA9: rez+=L'й'; break;
case (char)0xAA: rez+=L'к'; break;
case (char)0xAB: rez+=L'л'; break;
case (char)0xAC: rez+=L'м'; break;
case (char)0xAD: rez+=L'н'; break;
case (char)0xAE: rez+=L'о'; break;
case (char)0xAF: rez+=L'п'; break;
case (char)0xE0: rez+=L'р'; break;
case (char)0xE1: rez+=L'с'; break;
case (char)0xE2: rez+=L'т'; break;
case (char)0xE3: rez+=L'у'; break;
case (char)0xE4: rez+=L'ф'; break;
case (char)0xE5: rez+=L'х'; break;
case (char)0xE6: rez+=L'ц'; break;
case (char)0xE7: rez+=L'ч'; break;
case (char)0xE8: rez+=L'ш'; break;
case (char)0xE9: rez+=L'щ'; break;
case (char)0xEA: rez+=L'ъ'; break;
case (char)0xEB: rez+=L'ы'; break;
case (char)0xEC: rez+=L'ь'; break;
case (char)0xED: rez+=L'э'; break;
case (char)0xEE: rez+=L'ю'; break;
case (char)0xEF: rez+=L'я'; break;
//Каз-яз
case (char)0xDB: rez+=L'?'; break;
case (char)0xDC: rez+=L'?'; break;
case (char)0xDE: rez+=L'?'; break;
case (char)0xDF: rez+=L'?'; break;
case (char)0xF0: rez+=L'?'; break;
case (char)0xF1: rez+=L'?'; break;
case (char)0xF3: rez+=L'?'; break;
case (char)0xF4: rez+=L'?'; break;
case (char)0xF5: rez+=L'?'; break;
case (char)0xF6: rez+=L'?'; break;
case (char)0xF7: rez+=L'?'; break;
case (char)0xF8: rez+=L'?'; break;
case (char)0xFD: rez+=L'?'; break;
case (char)0xFE: rez+=L'?'; break;
default: rez+=(char)str[i]; break;
}
}
return rez;
}
//---------------------------------------------------------------------------
std::string UIntToStdStr(unsigned int val)
{
std::stringstream ss;
ss << val;
return ss.str();
}
//---------------------------------------------------------------------------
std::string IntToStdStr(int val)
{
std::ostringstream oss;
oss << val;
return oss.str();
}
//---------------------------------------------------------------------------
template <typename T>
std::string toStringHex(T val)
{
std::ostringstream oss;
oss << std::hex << val;
return oss.str();
}
//---------------------------------------------------------------------------
std::string toStringHex2(int val)
{
std::ostringstream oss;
oss << std::hex << val;
std::string result = oss.str();
if (result.length() % 2 != 0)
result = "0" + result;
return result;
}
//---------------------------------------------------------------------------
std::string toHexString(unsigned char* mas,int len)
{
std::string result="";
for(int i=0;i<len;i++)
{
std::string str=toStringHex2(mas[i]);
if(str.length()==1)
result+="0"+str;
else
result+=str;
}
return result;
}
//---------------------------------------------------------------------------
bool hexStringToArray(std::string data, char* mas)
{
int len = data.length() / 2;
for (int i = 0; i < len; i++) {
std::string val;
val += data[i * 2];
val += data[i * 2 + 1];
mas[i] = strtol(val.c_str(), NULL, 16);
}
return true;
}
//---------------------------------------------------------------------------
//Преобразовать HEX строку в число
template <typename T>
T fromStringHex(std::string val)
{
T value;
std::istringstream iss(val);
iss >> std::hex >> value;
return value;
}
//----------------------------------------------------------------------------
//ord - менять порядок байт
unsigned int hexStringToInt(std::string val, bool ord)
{
if (ord)
{
return (unsigned int)strtol(val.c_str(), NULL, 16);
}
else
{
std::string tmp;
for (unsigned int i = 0; i < val.size() / 2; i++)
{
tmp = val[i * 2 + 1] + tmp;
tmp = val[i * 2] + tmp;
}
return (unsigned int)strtol(tmp.c_str(), NULL, 16);
}
}
//---------------------------------------------------------------------------
unsigned int hexStdStrToUInt(std::string& str)
{
unsigned int x;
std::stringstream ss;
ss << std::hex << str;
ss >> x;
return x;
}
//----------------------------------------------------------------------------
//Закодировать двоично десятичное число
//Преобразовать строку цифр в строку байт пример "1234" в 2 байта [12h,34h] если нечётное то 0 в начале
std::string CodeBSD(std::string str)
{
if(str.length()%2!=0) str="0"+str;
//Преобразуем 2 символа в 1 байт
std::string rez;
size_t len=str.length()/2;
for(size_t i=0;i<len;i++)
{
std::string ch;
ch+=str[i*2];
ch+=str[i*2+1];
unsigned char hch = fromStringHex<int>(ch);
rez+=hch;
}
return rez;
}
//---------------------------------------------------------------------------
//Закодировать двоично десятичное число
//Преобразовать строку цифр в строку байт пример "1234" в 2 байта [12h,34h] если нечётное то 0 в начале
//len - количество (байт)символов добавит нули в начале если получилось меньше
std::string CodeBSD(int val,int len)
{
std::string str=CodeBSD(IntToStdStr(val));
for(int i=str.length();i<len;i++) //Медленно
str=(char)0x00+str;
return str;
}
//---------------------------------------------------------------------------
//Двоично десятичный символ в int
int BSDToInt(char chr)
{
std::string data = DecodeBSD(chr);
return StdStrToInt(data);
}
//---------------------------------------------------------------------------
//Двоично десятичную строку в int
int BSDToInt(std::string str, size_t start, size_t len)
{
std::string data = DecodeBSD(str,start,len);
return StdStrToInt(data);
}
//---------------------------------------------------------------------------
//Раскодировать двоично десятичное число 2 байта [12h,34h] преобразуются в строку "1234"
std::string DecodeBSD(char chr)
{
std::string rez;
unsigned char ch;
ch=(chr >> 4) & 0x0F;
if(ch<10) rez+=(char)(48+ch);
else rez+='0'; //такого не должно быть
ch=chr & 0x0F;
if(ch<10) rez+=(char)(48+ch);
else rez+='0'; //такого не должно быть
return rez;
}
//---------------------------------------------------------------------------
//Раскодировать двоично десятичное число 2 байта [12h,34h] преобразуются в строку "1234"
std::string DecodeBSD(std::string str, size_t start, size_t len)
{
if(len==0) len=str.length();
len=start+len;
if(len>str.length()) len=str.length();
std::string rez;
for(size_t i=start;i<len;i++)
{
rez+=DecodeBSD(str[i]);
}
return rez;
}
//---------------------------------------------------------------------------
//std::wstring StringToWString( const std::string& in, std::locale loc )
std::wstring StringToWString(const std::string& in, const std::locale &loc)
{
std::wstring out;
std::string::const_iterator i( in.begin() ), ie( in.end() );
for( ; i!=ie; ++i )
out += std::use_facet<std::ctype<wchar_t> > ( loc ).widen( *i );
return out;
}
//---------------------------------------------------------------------------
//Запись в строку line, align: 1 = лево, 2 = центр, 3 = право
void printToPos(std::wstring& line, std::wstring data, char align) {
switch (align) {
case 1: {
for (uint32_t i = 0; i < std::min(line.length(), data.length()); i++) //На min ругалось сделал std::min
{
line[i] = data[i];
}
break;
}
case 2: {
int p1 = line.length() / 2.0f;
int p2 = data.length() / 2.0f;
int st = p1 - p2;
for (uint32_t i = st; i < st + data.length(); i++)
{
if (i > 0 && i < line.length()) {
line[i] = data[i - st];
}
}
break;
}
case 3: {
for (uint32_t i = 0; i < std::min(line.length(), data.length()); i++)
{
line[line.length()-i-1] = data[data.length()-i-1];
}
break;
}
}
}
//---------------------------------------------------------------------------
void replaseChars(std::string& str, char oldCh, char newCh)
{
int indexCh = str.find(oldCh);
while (indexCh != -1)
{
str.replace(indexCh,1,1,newCh);
indexCh = str.find(oldCh,indexCh);
}
}
//---------------------------------------------------------------------------
/*inline std::string replace(std::string text, std::string s, std::string d)
{
for(unsigned index=0; index=text.find(s, index), index!=std::string::npos;)
{
text.replace(index, s.length(), d);
index+=d.length();
}
return text;
}*/
//---------------------------------------------------------------------------
//Заменить подстроку на другую
void replaceAll(std::wstring& str, const std::wstring from, const std::wstring to)
{
if (from.empty())
return;
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
//------------------------------------------------------------------------------
//Заменить подстроку на другую
void replaceAll(std::string& str, const std::string from, const std::string to)
{
if (from.empty())
return;
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
//------------------------------------------------------------------------------
//Заменить все вхождения строки find в sors на repl (wxString::Replace)
std::string replaceStrings(std::string sors,std::string find,std::string repl)
{
if(find==repl) return sors;
std::string rez="";
size_t p0=0;
size_t p1 = sors.find(find,p0);
while(p1!=std::string::npos)
{
rez.append(sors,p0,p1-p0);
rez+=repl;
p0=p1+find.length();
p1=sors.find(find,p0);
}
rez.append(sors,p0,sors.length()-p0);
return rez;
}
//---------------------------------------------------------------------------
std::wstring replaceStrings(std::wstring sors,std::wstring find,std::wstring repl)
{
if(find==repl) return sors;
std::wstring rez=L"";
size_t p0=0;
size_t p1 = sors.find(find,p0);
while(p1!=std::wstring::npos)
{
rez.append(sors,p0,p1-p0);
rez+=repl;
p0=p1+find.length();
p1=sors.find(find,p0);
}
rez.append(sors,p0,sors.length()-p0);
return rez;
}
//---------------------------------------------------------------------------
//Получить дату в виде ANSI строки в формате ddmmyyyy
std::string getStrDate()
{
time_t t=time(NULL);
tm* st=localtime(&t);
std::string str1=IntToStdStr(st->tm_mday);
if(str1.length()==1) str1="0"+str1;
std::string str2=IntToStdStr(st->tm_mon+1);
if(str2.length()==1) str2="0"+str2;
std::string str3=IntToStdStr(st->tm_year+1900);
if(str3.length()==1) str3="0"+str3;
//delete st; Ошибка памяти будет если удалю
return str1+str2+str3;
}
//---------------------------------------------------------------------------
//Преобразую строку вида 02-10-18 20:51:40 в unix time
unsigned int getTime1(std::string date)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
std::string tmp;
//struct tm {
//int tm_sec; // seconds
//int tm_min; // minutes
//int tm_hour; // hours
//int tm_mday; // day of the month
//int tm_mon; // month
//int tm_year; // year
//int tm_wday; // day of the week
//int tm_yday; // day in the year
//int tm_isdst; // daylight saving time
//};
struct tm tmd;
memset(&tmd, 0, sizeof(struct tm));
tmp=CutBeforeFirst(date, "-");
tmd.tm_mday = StdStrToInt(tmp);
tmp=CutBeforeFirst(date, "-");
tmd.tm_mon = StdStrToInt(tmp);
tmp=CutBeforeFirst(date, " ");
tmd.tm_year = (2000 + StdStrToInt(tmp)) - 1900;
tmp=CutBeforeFirst(date, ":");
tmd.tm_hour = StdStrToInt(tmp);
tmp=CutBeforeFirst(date, ":");
tmd.tm_min = StdStrToInt(tmp);
tmd.tm_sec = StdStrToInt(date);
time_t time = mktime(&tmd);
return (unsigned int)time;
#else
return 0;
#endif
}
//---------------------------------------------------------------------------
//Получить дату в виде Unicode строки в формате ddmmyyyy
std::wstring getWStrDate()
{
return StringToWString(getStrDate(),std::locale(""));
}
//---------------------------------------------------------------------------
//Дата и время в виде строки dd.mm.yyyy hh:mm:ss пример 24.05.2010 15:20:26
std::string getDateTime()
{
/*
#if defined( _VC )
//Для проекта с ATL библиотекой
std::string tmp,res="";
SYSTEMTIME st;
GetLocalTime(&st);
//Дата
tmp=toStdStr(st.wDay);
if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
tmp=toStdStr(st.wMonth);
if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
res+=toStdStr(st.wYear)+" ";
//Время
tmp=toStdStr(st.wHour);
if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
tmp=toStdStr(st.wMinute);
if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
tmp=toStdStr(st.wSecond);
if(tmp.length()==1) res+="0"+tmp; else res+=tmp;
return res;
#endif
#if defined( _WX )
//Для кросплатформенного проекта wxWidgets
return "";
#endif
*/
std::string tmp,res="";
time_t t=time(NULL);
tm* st=localtime(&t);
//Дата
tmp=IntToStdStr(st->tm_mday);
if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
tmp=IntToStdStr(st->tm_mon+1);
if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
res+=IntToStdStr(st->tm_year+1900)+" ";
//Время
tmp=IntToStdStr(st->tm_hour);
if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
tmp=IntToStdStr(st->tm_min);
if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
tmp=IntToStdStr(st->tm_sec);
if(tmp.length()==1) res+="0"+tmp; else res+=tmp;
//delete st; //Ошибка памяти будет если удалю
return res;
}
//---------------------------------------------------------------------------
//Float в строку
/*std::string FloatToStdStr(float val)
{
std::ostringstream oss;
oss << val;
return oss.str();
}*/
//---------------------------------------------------------------------------
//Преобразовать в строку (Разделитель всегда точка)
//digits - Сколько цифр после запятой оставлять если -1 то по полной
std::string FloatToStdStr(double val, int digits,char sep)
{
std::ostringstream oss;
if(digits >= 0)
oss << std::fixed << std::setprecision( digits ) << val;
else oss << std::fixed << val;
std::string str=oss.str();
if(sep=='.')
std::replace( str.begin(), str.end(), ',', '.');
if(sep==',')
std::replace( str.begin(), str.end(), '.', ',');
int pos=MAX(str.find('.'),str.find(',')); //Позиция запятой в строке (TODO взять разделитель из системных параметров)
//Обрезаем строку
if(digits>=0 && pos>=0)
{ if(digits==0) digits=-1; //Чтоб убрать запятую
std::string result="";
result.append(str,0,pos+digits+1);
return result;
}else return str;
}
//---------------------------------------------------------------------------
std::wstring FloatToStdWStr(double val, int digits)
{
std::string str = FloatToStdStr(val,digits);
std::wstring wsTmp(str.begin(), str.end());
return wsTmp;
//return s2ws(str);
}
//---------------------------------------------------------------------------
template <typename T>
std::wstring toStdWStr(T val)
{
std::ostringstream oss;
oss << val;
std::string str=oss.str();
return StringToWString( str, std::locale(""));
}
//---------------------------------------------------------------------------
std::wstring IntToStdWStr(int val)
{
return toStdWStr(val);
}
//---------------------------------------------------------------------------
template<typename T>
T fromString(const std::string& s)
{
std::istringstream iss(s);
T res;
iss >> res;
return res;
}
//---------------------------------------------------------------------------
//Преобразовать строку в число
//str - Исходная строка с числом
//cutInt - вырезать из строки только цифры
int StdStrToInt(std::string& str, bool cutInt, int def)
{
if(cutInt)
{
std::string val="";
for(unsigned int i=0;i<str.length();i++)
{
if((str[i]=='-' && (val.length()==0 || val[0]!='-')) || str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9')
val+=str[i];
}
if(val=="") return def;
return fromString<int>(val);
}
if(str=="") return def;
return fromString<int>(str);
}
//---------------------------------------------------------------------------
//Преобразовать строку в число
//str - Исходная строка с числом
//cutInt - вырезать из строки только цифры
uint32_t StdStrToUInt(std::string& str, bool cutInt, uint32_t def)
{
if(cutInt)
{
std::string val="";
for(unsigned int i=0;i<str.length();i++)
{
if(str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9')
val+=str[i];
}
if(val=="") return def;
return fromString<int>(val);
}
if(str=="") return def;
return fromString<int>(str);
}
//---------------------------------------------------------------------------
float StdStrToFloat(std::string& str)
{
if(str=="") return 0;
return fromString<float>(str);
}
//---------------------------------------------------------------------------
double StdStrToDouble(std::string& str,double defval)
{
if(str=="") return defval;
return fromString<double>(str);
}
//---------------------------------------------------------------------------
double StdWStrToDouble(std::wstring str, double defval)
{
if (str == L"") return defval;
return fromWString<double>(str);
}
//---------------------------------------------------------------------------
template<typename T>
T fromWString(const std::wstring& s)
{
std::string str=WStringToString(s, std::locale(""));
std::istringstream iss(str);
T res;
iss >> res;
return res;
}
//---------------------------------------------------------------------------
int StdWStrToInt(const std::wstring& str, bool cutInt)
{
if(cutInt)
{
std::wstring val=L"";
for(unsigned int i=0;i<str.length();i++)
{
if((str[i]==L'-' && (val.length()==0 || val[0]!=L'-')) || str[i]==L'0' || str[i]==L'1' || str[i]==L'2' || str[i]==L'3' || str[i]==L'4' || str[i]==L'5' || str[i]==L'6' || str[i]==L'7' || str[i]==L'8' || str[i]==L'9')
val+=str[i];
}
if(val==L"") return 0;
return fromWString<int>(val);
}
if(str==L"") return 0;
return fromWString<int>(str);
}
//---------------------------------------------------------------------------
int StdWStrToUInt(const std::wstring& str, bool cutInt)
{
if(cutInt)
{
std::wstring val=L"";
for(unsigned int i=0;i<str.length();i++)
{
if(str[i]==L'0' || str[i]==L'1' || str[i]==L'2' || str[i]==L'3' || str[i]==L'4' || str[i]==L'5' || str[i]==L'6' || str[i]==L'7' || str[i]==L'8' || str[i]==L'9')
val+=str[i];
}
if(val==L"") return 0;
return fromWString<int>(val);
}
if(str==L"") return 0;
return fromWString<int>(str);
}
//---------------------------------------------------------------------------
///К верхнему регистру строку
std::wstring UpperCase(const std::wstring& str)
{
std::wstring res=L""; //TODO Надо выделить память
for(unsigned int i=0;i<str.length();i++)
{
switch( str[i] )
{
case L'a': res+=L'A'; break;
case L'b': res+=L'B'; break;
case L'c': res+=L'C'; break;
case L'd': res+=L'D'; break;
case L'e': res+=L'E'; break;
case L'f': res+=L'F'; break;
case L'g': res+=L'G'; break;
case L'h': res+=L'H'; break;
case L'i': res+=L'I'; break;
case L'j': res+=L'J'; break;
case L'k': res+=L'K'; break;
case L'l': res+=L'L'; break;
case L'm': res+=L'M'; break;
case L'n': res+=L'N'; break;
case L'o': res+=L'O'; break;
case L'p': res+=L'P'; break;
case L'q': res+=L'Q'; break;
case L'r': res+=L'R'; break;
case L's': res+=L'S'; break;
case L't': res+=L'T'; break;
case L'u': res+=L'U'; break;
case L'v': res+=L'V'; break;
case L'w': res+=L'W'; break;
case L'x': res+=L'X'; break;
case L'y': res+=L'Y'; break;
case L'z': res+=L'Z'; break;
case L'а': res+=L'А'; break;
case L'б': res+=L'Б'; break;
case L'в': res+=L'В'; break;
case L'г': res+=L'Г'; break;
case L'д': res+=L'Д'; break;
case L'е': res+=L'Е'; break;
case L'ё': res+=L'Ё'; break;
case L'ж': res+=L'Ж'; break;
case L'з': res+=L'З'; break;
case L'и': res+=L'И'; break;
case L'к': res+=L'К'; break;
case L'л': res+=L'Л'; break;
case L'м': res+=L'М'; break;
case L'н': res+=L'Н'; break;
case L'о': res+=L'О'; break;
case L'п': res+=L'П'; break;
case L'р': res+=L'Р'; break;
case L'с': res+=L'С'; break;
case L'т': res+=L'Т'; break;
case L'у': res+=L'У'; break;
case L'ф': res+=L'Ф'; break;
case L'х': res+=L'Х'; break;
case L'ц': res+=L'Ц'; break;
case L'ч': res+=L'Ч'; break;
case L'ш': res+=L'Ш'; break;
case L'щ': res+=L'Щ'; break;
case L'ъ': res+=L'Ъ'; break;
case L'ы': res+=L'Ы'; break;
case L'ь': res+=L'Ь'; break;
case L'э': res+=L'Э'; break;
case L'ю': res+=L'Ю'; break;
case L'я': res+=L'Я'; break;
default:
res+=str[i];
}
}
return res;
}
//---------------------------------------------------------------------------
///Получить строку до указанного символа если символа нет то вернёт всю строку.
std::string BeforeLast(std::string str,char ch)
{
int pos=0;
for(uint32_t i=0;i<str.length();i++)
{
if(str[i]==ch) pos=i;
}
if(pos==0) pos=str.length();
std::string result="";
result.append(str,0,pos);
return result;
}
//---------------------------------------------------------------------------
///Получить строку до указанного символа если символа нет то вернёт всю строку.
std::wstring BeforeWLast(std::wstring str,wchar_t ch)
{
int pos=0;
for(uint32_t i=0;i<str.length();i++)
{
if(str[i]==ch) pos=i;
}
if(pos==0) pos=str.length();
std::wstring result=L"";
result.append(str,0,pos);
return result;
}
//---------------------------------------------------------------------------
std::string BeforeFirst(std::string str,const unsigned char ch)
{
unsigned int pos=str.find(ch);
std::string result="";
result.append(str,0,pos);
return result;
}
//---------------------------------------------------------------------------
std::string BeforeFirst(std::string str,const char ch)
{
unsigned int pos=str.find(ch);
std::string result="";
result.append(str,0,pos);
return result;
}
//---------------------------------------------------------------------------
std::wstring BeforeWFirst(std::wstring str,const wchar_t ch)
{
unsigned int pos=str.find(ch);
std::wstring result=L"";
result.append(str,0,pos);
return result;
}
//---------------------------------------------------------------------------
std::string CutAfterFirst(std::string& str,std::string br)
{
size_t pos=str.find(br);
std::string result="";
if(pos==std::string::npos)
{
result.append(str);
str.erase();
}else
{
result.append(str,pos + br.size(),str.length() - pos - br.size());
str.erase(pos);
}
return result;
}
//---------------------------------------------------------------------------
//Если не найдёт нужный символ то вернёт всю строку
std::string CutAfterLast(std::string& str,const unsigned char ch)
{
std::string result="";
size_t pos=str.find_last_of(ch);
if(pos!=std::string::npos)
{
result.append(str,pos+1,str.length()-pos-1);
str.erase(pos);
}else
{
result.append(str);
str.erase();
}
return result;
}
//---------------------------------------------------------------------------
//Отрезать от строки до указанного символа если не найден символ отрезается вся строка
std::string CutBeforeFirst(std::string& str,const char ch)
{
int pos=str.find(ch);
std::string result="";
if(pos==-1)
{
result.append(str);
str.erase();
}else
{
result.append(str,0,pos);
str.erase(0,pos+1);
}
return result;
}
//---------------------------------------------------------------------------
//Отрезать от строки до указанного символа если не найден символ отрезается вся строка
std::string CutBeforeFirst(std::string& str,const std::string br)
{
int pos=str.find(br);
std::string result="";
if(pos==-1)
{
result.append(str);
str.erase();
}else
{
if(pos>0)
result.append(str,0,pos);
str.erase(0,pos+br.size());
}
return result;
}
//---------------------------------------------------------------------------
//Отрезать от строки до указанного символа если не найден символ отрезается вся строка
std::wstring CutBeforeWFirst(std::wstring& str,const wchar_t ch)
{
int pos=str.find(ch);
std::wstring result=L"";
if(pos==-1)
{
result.append(str);
str.erase();
}else
{
result.append(str,0,pos);
str.erase(0,pos+1);
}
return result;
}
//---------------------------------------------------------------------------
std::string AfterFirst(std::string str,const char ch)
{
unsigned int pos=str.find(ch);
std::string result="";
result.append(str,pos+1,str.size());
return result;
}
//---------------------------------------------------------------------------
std::wstring AfterWFirst(std::wstring str,const wchar_t ch)
{
unsigned int pos=str.find(ch);
std::wstring result=L"";
result.append(str,pos+1,str.size());
return result;
}
//---------------------------------------------------------------------------
//Всё после заданного разделителя, если разделитель не найден то сначала строки
std::string AfterLast(std::string str,const char ch)
{
int pos=str.find_last_of(ch)+1;
int len=str.length()-pos;
return str.substr(pos,len);
}
//---------------------------------------------------------------------------
std::string WStringToString(const std::wstring &wstr, const std::locale &loc, char default_char)
{
//std::wcout << L"wstr=" << wstr<< std::endl;;
if (wstr.empty())
return std::string();
//закоментил потому что маленькую букву я не преобразует
std::string ret;
ret.resize(wstr.length());
std::use_facet<std::ctype<wchar_t> >(loc).narrow(&wstr[0], &wstr[0] + wstr.length(), '?', &ret[0]);
return ret;
/*
std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
wchar_t const *first = wstr.c_str();
wchar_t const *last = first + wstr.size();
std::vector<char> result(wstr.size());
facet.narrow(first, last, default_char, &result[0]);
return std::string(result.begin(), result.end());
*/
/*
//setup converter
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( wstr );
return converted_str;
*/
/*
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.to_bytes(wstr);*/
/*
static std::wstring_convert< std::codecvt_utf8<wchar_t>, wchar_t > converter ;
return converter.to_bytes(wstr) ;
*/
}
//---------------------------------------------------------------------------
//Получить полный путь к текущему EXE файлу
std::wstring getExePathW(bool add)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
std::wstring str;
wchar_t pathBuf[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, pathBuf, MAX_PATH);
str = pathBuf;
str = BeforeWLast(str, L'\\');
if (add) str += L'\\';
return str;
#else
std::wstring str = L".";
if (add) str += L'\\';
return str;
#endif
return L"";
/*
это к DLL делал но не пригодилось (по хенделу)
std::wstring str;
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
wchar_t pathBuf[MAX_PATH] = {0};
HMODULE thisModule = 0;
BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&__FUNCTION__, &thisModule);
DWORD nLen = GetModuleFileName(thisModule, pathBuf, MAX_PATH);
str=pathBuf;
if(!add) str=BeforeWLast(str,L'\\')+L'\\';
#endif
return str;
*/
}
//---------------------------------------------------------------------------
/*std::string getExePath()
{
//если EXE то
//return ExtractFilePath(ParamStr(0)).c_str();
//Если DLL то
return "";
}*/
//---------------------------------------------------------------------------
//Получить полный путь к текущему EXE файлу
std::string getExePathA(bool add)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
std::string str;
char pathBuf[MAX_PATH] = {0};
GetModuleFileNameA(NULL,pathBuf,MAX_PATH);
str=pathBuf;
str=BeforeLast(str,'\\');
if (add) str += '\\';
return str;
#else
std::string str=".";
if (add) str += '\\';
return str;
#endif
return "";
}
//---------------------------------------------------------------------------
//Путь к дирректории приложений, для хранения настроек (если линукс то к томайней директории пользователя) без завершающего слеша
std::string getAppPath()
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
std::string path;
char szPath[MAX_PATH];
memset(szPath,0,MAX_PATH);
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)))
//if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath)))
{
path=szPath;
}
return path;
#else
struct passwd *pw = getpwuid(getuid());
return pw->pw_dir;
#endif
}
//---------------------------------------------------------------------------
//Добавить 0 в начало строоки если 1 символ для даты нужно
std::string add0(std::string str)
{
if(str.length()==1) return "0"+str;
else return str;
}
//---------------------------------------------------------------------------
//Конвертация из UTF16LE в UTF8
std::string convUTF16ToUTF8(const std::wstring& widestring)
{
unsigned int len8=0;
unsigned int len16=widestring.length();
const wchar_t* p16=widestring.data();
for(unsigned int i=0;i<len16;i++) //Подсчитываем размер буфера
{
if(p16[i]<=0x7f) len8++; else
if(p16[i]<=0x7ff) len8+=2; else
if(p16[i]<=0xffff) len8+=3; else
if(p16[i]<=0x10ffff) len8+=4;
}
unsigned char * p8=new unsigned char[len8];
unsigned int pos=0;
for(unsigned int i=0;i<len16;i++)
{
if(p16[i]<=0x7f)
{
p8[pos]=(unsigned char)p16[i];
pos++;
}else
if(p16[i]<=0x7ff) //110xxxxx, 10xxxxxx
{
p8[pos]=(p16[i]>>6 | 192) & 223;
pos++;
p8[pos]=(p16[i] | 128) & 191;
pos++;
}else
if(p16[i]<=0xffff) //1110xxxx 10xxxxxx 10xxxxxx
{
p8[pos]=(p16[i]>>12 | 224) & 239;
pos++;
p8[pos]=(p16[i]>>6 | 128) & 191;
pos++;
p8[pos]=(p16[i] | 128) & 191;
pos++;
}else
if(p16[i]<=0x10ffff) //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
{
p8[pos]=(p16[i]>>18 | 240) & 247;
pos++;
p8[pos]=(p16[i]>>12 | 128) & 191;
pos++;
p8[pos]=(p16[i]>>6 | 128) & 191;
pos++;
p8[pos]=(p16[i] | 128) & 191;
pos++;
}
}
std::string str;
str.append((char*)p8,len8);
delete[] p8;
return str;
}
//---------------------------------------------------------------------------
//Конвертация из UTF8 в UTF16LE
std::wstring convUTF8ToUTF16(const std::string& str)
{
unsigned int len16=0;
unsigned int len8=str.length();
const char* p8=str.data();
unsigned int i=0;
while(i<len8) //Подсчитываем сколько символов в строке
{
if((p8[i] & 0x80)==0) i++; else //0 в начале знач 1 символ
if((p8[i] & 0xF0)==0xF0) i+=4; else //11110xxx
if((p8[i] & 0xE0)==0xE0) i+=3; else //1110xxxx
if((p8[i] & 0xC0)==0xC0) i+=2; //110xxxxx
len16++;
}
wchar_t* p16=new wchar_t[len16];
unsigned int pos=0;
i=0;
while(i<len8)
{
if((p8[i] & 0x80)==0) //0xxxxxxx (0 в начале знач 1 символ)
{
p16[pos]=p8[i];
pos++; i++;
}else
if((p8[i] & 0xF0)==0xF0) //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
{
p16[pos]=((p8[i] & 0x7) << 18) | ((p8[i+1] & 0x3F) << 12) | ((p8[i+2] & 0x3F) << 6) | (p8[i+3] & 0x3F);
pos++; i+=4;
}else
if((p8[i] & 0xE0)==0xE0) //1110xxxx 10xxxxxx 10xxxxxx
{
p16[pos]=((p8[i] & 0xf) << 12) | ((p8[i+1] & 0x3F) << 6) | (p8[i+2] & 0x3F);
pos++; i+=3;
} else
if((p8[i] & 0xC0)==0xC0) //110xxxxx 10xxxxxx
{
p16[pos]=((p8[i] & 0x1F) << 6) | (p8[i+1] & 0x3F);
pos++; i+=2;
}else i++; //если дошло до сюда то ошибка
}
std::wstring wstr;
wstr.append(p16,len16);
delete[] p16;
return wstr;
}
//---------------------------------------------------------------------------
//Убрать начальные и конечные пробелы \t\r
void Trim(std::string& s)
{
TrimLeft(s);
TrimRight(s);
}
//---------------------------------------------------------------------------
std::string trim(const std::string & s)
{
size_t startPos = s.find_first_not_of(" \t\r");
if (startPos == std::string::npos)
return "";
size_t endPos = s.find_last_not_of(" \t\r");
return s.substr(startPos, endPos - startPos + 1);
}
//---------------------------------------------------------------------------
void TrimW(std::wstring& s)
{
TrimWLeft(s);
TrimWRight(s);
}
//---------------------------------------------------------------------------
void TrimWLeft(std::wstring& str)
{
size_t startpos = str.find_first_not_of(L" \t\f\n\r");
if (startpos != std::string::npos)
{
str = str.substr(startpos);
}
else
{
str.clear(); //Вся строка из спец символов
}
}
//---------------------------------------------------------------------------
void TrimWRight(std::wstring& str)
{
std::wstring::size_type endpos = str.find_last_not_of(L" \t\f\n\r");
if (endpos != std::string::npos)
{
str = str.substr(0, endpos + 1);
}
else
{
str.clear(); //Вся строка из спец символов
}
}
//---------------------------------------------------------------------------
void TrimLeft(std::string& str)
{
size_t startpos = str.find_first_not_of(" \t\f\n\r");
if(startpos != std::string::npos)
{
str = str.substr( startpos );
}else
{
str.clear(); //Вся строка из спец символов
}
}
//---------------------------------------------------------------------------
void TrimRight(std::string& str)
{
std::string::size_type endpos = str.find_last_not_of(" \t\f\n\r");
if( endpos != std::string::npos )
{
str = str.substr( 0, endpos+1 );
}else
{
str.clear(); //Вся строка из спец символов
}
}
//---------------------------------------------------------------------------
//Заменить текст str на тот что из txt
std::string printToPos(std::string str, int pos, std::string txt)
{
//Дополняю длину строки
if (str.length() < pos + txt.length()) {
str.append(std::string(pos + txt.length() - str.length(), ' '));
}
//Переписываю строку
for(long unsigned int i = 0; i < txt.length();i++) {
str[pos + i] = txt[i];
}
return str;
}
//---------------------------------------------------------------------------
//Разделить текст по разделителю на слова
std::vector<std::wstring> split(const std::wstring& str, wchar_t delimiter)
{
std::wstring temp;
std::vector<std::wstring> parts;
std::wstringstream wss(str);
while(std::getline(wss, temp, delimiter))
parts.push_back(temp);
return parts;
}
//---------------------------------------------------------------------------
void killProcessByName(const wchar_t *filename)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
/* HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(pEntry);
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes)
{
if (wcscmp(pEntry.szExeFile, filename) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
(DWORD)pEntry.th32ProcessID);
if (hProcess != NULL)
{
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);*/
#else
#endif
}
//---------------------------------------------------------------------------
bool dirExists(std::string path)
{
struct stat info;
if(stat( path.c_str(), &info ) != 0)
return 0;
else if(info.st_mode & S_IFDIR)
return 1;
else
return 0;
}
//---------------------------------------------------------------------------
//Создать папку
bool createFolder(std::string directory,int mode)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND)
CreateDirectoryA(directory.c_str(), NULL);
return true;
#else
mode_t tmp = mode; //На винде тен типа mode_t
int rez=0;
if(!dirExists(directory)){
rez=mkdir(directory.c_str(), mode); //Если папки нет то создать её
}
if(rez==0){
chmod(directory.c_str(), mode); //Бывало что при создании права не назначались
}
return rez==0;
#endif
}
//---------------------------------------------------------------------------
std::string intToString(int val)
{
std::stringstream ss;
ss << val;
return ss.str();
}
//---------------------------------------------------------------------------
std::string uintToString(unsigned int val)
{
std::stringstream ss;
ss << val;
return ss.str();
}
//---------------------------------------------------------------------------
std::string ullintToString(unsigned long long int val)
{
std::stringstream ss;
ss << val;
return ss.str();
}
}