Files

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;
}