178 lines
4.1 KiB
C++
178 lines
4.1 KiB
C++
#include "libdiff.h"
|
|
|
|
#include <sys/timeb.h>
|
|
#include <errno.h>
|
|
#include <iconv.h>
|
|
#include <cstring>
|
|
#include <algorithm>
|
|
#include <sys/resource.h>
|
|
|
|
using namespace std;
|
|
|
|
ostream& operator<<(ostream &out, const pthread_mutex_t m)
|
|
{
|
|
out << &m;
|
|
return out;
|
|
}
|
|
|
|
void LockMutex(pthread_mutex_t &m)
|
|
{
|
|
int mres;
|
|
while ((mres = pthread_mutex_lock(&m)) != 0)
|
|
{
|
|
if (mres != EAGAIN)
|
|
{
|
|
throw (string)("Fatal error acquiring mutex");
|
|
}
|
|
}
|
|
}
|
|
|
|
void ReleaseMutex(pthread_mutex_t &m)
|
|
{
|
|
int mres = pthread_mutex_unlock(&m);
|
|
if (mres != 0)
|
|
{
|
|
throw (string)("Error releasing mutex " + ToString(m) + " res = " + ToString(mres));
|
|
}
|
|
}
|
|
|
|
int Round(double v)
|
|
{
|
|
if (v < -1e-4) return -(int)(-v + 0.5);
|
|
else return (int)(v + 0.5);
|
|
}
|
|
|
|
void CP866ToUTF8(unsigned char *src, unsigned char *dest, int destlen)
|
|
{
|
|
iconv_t icd = iconv_open("UTF-8", "CP866");
|
|
if (icd == (iconv_t)-1)
|
|
{
|
|
throw (string)("Unable to open iconv descriptor, errno = " + ToString(errno));
|
|
}
|
|
size_t slen = strlen((char*)src);
|
|
destlen--;
|
|
// странные временные переменные, потому что иначе компилятор ругается, что
|
|
// результат приведения типов - не lvalue
|
|
char *s = (char*)src;
|
|
char *d = (char*)dest;
|
|
size_t dl = destlen;
|
|
size_t t = iconv(icd, &s, &slen, &d, &dl);
|
|
iconv_close(icd);
|
|
if (t == (size_t)-1)
|
|
{
|
|
throw (string)("Error during string conversion, errno = " + ToString(errno));
|
|
}
|
|
// терминируем строку, iconv сам этого не сделает
|
|
d[0] = 0;
|
|
}
|
|
|
|
string CP1251ToUTF8(const string &src)
|
|
{
|
|
unsigned char *dest = new unsigned char[src.length() * 4];
|
|
CP1251ToUTF8((const unsigned char *)src.c_str(), dest, src.length() * 4);
|
|
string res((char*)dest);
|
|
delete[] dest;
|
|
return res;
|
|
}
|
|
|
|
void CP1251ToUTF8(const unsigned char *src, unsigned char *dest, int destlen)
|
|
{
|
|
iconv_t icd = iconv_open("UTF-8", "CP1251");
|
|
if (icd == (iconv_t)-1)
|
|
{
|
|
throw (string)("Unable to open iconv descriptor, errno = " + ToString(errno));
|
|
}
|
|
size_t slen = strlen((char*)src);
|
|
destlen--;
|
|
// странные временные переменные, потому что иначе компилятор ругается, что
|
|
// результат приведения типов - не lvalue
|
|
char *s = (char*)src;
|
|
char *d = (char*)dest;
|
|
size_t dl = destlen;
|
|
size_t t = iconv(icd, &s, &slen, &d, &dl);
|
|
iconv_close(icd);
|
|
if (t == (size_t)-1)
|
|
{
|
|
throw (string)("Error during string conversion, errno = " + ToString(errno));
|
|
}
|
|
// терминируем строку, iconv сам этого не сделает
|
|
d[0] = 0;
|
|
}
|
|
|
|
int UnpackBCD(int a)
|
|
{
|
|
if ((a & 0xF) > 9 ||
|
|
((a >> 4) & 0xF) > 9) throw (string)("Wrong BCD number: " + ToString(a));
|
|
return (((a >> 4) & 0xF) * 10) + (a & 0xF);
|
|
}
|
|
|
|
bool CheckBCD(int a)
|
|
{
|
|
if ((a & 0xF) > 9 ||
|
|
((a >> 4) & 0xF) > 9) return false;
|
|
return true;
|
|
}
|
|
|
|
int PackBCD(int a)
|
|
{
|
|
return (((a / 10) % 10) << 4) | (a % 10);
|
|
}
|
|
|
|
unsigned long long GetMilliseconds()
|
|
{
|
|
struct timeb tm;
|
|
if (ftime(&tm) == -1)
|
|
{
|
|
// should never happen in fact
|
|
throw (string)("ftime() failed somehow");
|
|
}
|
|
unsigned long long res = tm.time;
|
|
res *= 1000;
|
|
res += tm.millitm;
|
|
return res;
|
|
}
|
|
|
|
string ReplaceAll(string text, string pattern, string replacement)
|
|
{
|
|
while (1)
|
|
{
|
|
size_t pos = text.find(pattern);
|
|
if (pos == string::npos) return text;
|
|
text = text.replace(pos, pattern.length(), replacement);
|
|
}
|
|
}
|
|
|
|
string IntToString(int a, int base)
|
|
{
|
|
// no itoa in modern C++, what a pity
|
|
int sign = a < 0 ? -1 : 1;
|
|
if (a < 0) a = -a;
|
|
string res;
|
|
while (a > 0)
|
|
{
|
|
int cur = a % base;
|
|
char c = cur + '0';
|
|
if (cur > 9) c = cur + 'A' - 10;
|
|
res += c;
|
|
a /= base;
|
|
}
|
|
if (sign < 0) res += '-';
|
|
reverse(res.begin(), res.end());
|
|
return res;
|
|
}
|
|
|
|
int RaiseFDLimit()
|
|
{
|
|
struct rlimit rl;
|
|
if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
|
|
{
|
|
return -1;
|
|
}
|
|
rl.rlim_cur = rl.rlim_max;
|
|
if (setrlimit(RLIMIT_NOFILE, &rl) != 0)
|
|
{
|
|
return -1;
|
|
}
|
|
return rl.rlim_cur;
|
|
}
|