X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/327ec384624ea69aa0e02f89d5513e31752fef90..0efa04fc1be8738fc2e5c683cf9604d5c4603252:/stglibs/common.lib/common.cpp?ds=sidebyside diff --git a/stglibs/common.lib/common.cpp b/stglibs/common.lib/common.cpp index 57b37bdf..3361adb3 100644 --- a/stglibs/common.lib/common.cpp +++ b/stglibs/common.lib/common.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #endif #include @@ -83,6 +84,44 @@ using namespace std; +#ifdef WIN32 +//----------------------------------------------------------------------------- +const char * inet_ntop(int af, const void * src, char * dst, unsigned long length) +{ +struct sockaddr_in addr; +addr.sin_family = af; +addr.sin_port = 0; +memcpy(&addr.sin_addr.s_addr, src, sizeof(addr.sin_addr.s_addr)); +if (WSAAddressToStringA(reinterpret_cast(&addr), sizeof(addr), 0, dst, &length)) + { + return NULL; + } +return dst; +} +//----------------------------------------------------------------------------- +int inet_pton(int af, const char * src, void * dst) +{ +// Fuck you Microsoft! +// Why the hell not to use const char *? +size_t slen = strlen(src); +char * buf = new char[slen + 1]; +strncpy(buf, src, slen + 1); +buf[slen] = 0; +struct sockaddr_in addr; +addr.sin_family = af; +addr.sin_port = 0; +addr.sin_addr.s_addr = 0; +int length = sizeof(addr); +if (WSAStringToAddressA(buf, af, 0, reinterpret_cast(&addr), &length)) + { + delete[] buf; + return -1; + } +memcpy(dst, &addr, sizeof(addr)); +delete[] buf; +return 1; +} +#endif //----------------------------------------------------------------------------- int strtodouble2(const char * s, double &a) { @@ -330,12 +369,6 @@ void Encode12(char * dst, const char * src, size_t srcLen) { for (size_t i = 0; i <= srcLen; i++) { - if (src[i] == 0) - { - dst[i * 2] = 'a'; - dst[i * 2 + 1] = 'a'; - break; - } char c1 = src[i] & 0x0f; char c2 = (src[i] & 0xf0) >> 4; @@ -762,6 +795,7 @@ if (errno == ERANGE) return 0; } +#ifndef WIN32 //--------------------------------------------------------------------------- int str2x(const std::string & str, long long & x) { @@ -782,6 +816,7 @@ if (errno == ERANGE) return 0; } +#endif //--------------------------------------------------------------------------- const std::string & x2str(unsigned x, std::string & s) { @@ -827,8 +862,35 @@ std::string & Trim(std::string & val) return TrimR(TrimL(val)); } //--------------------------------------------------------------------------- +#ifdef WIN32 +static int is_leap(unsigned y) +{ + y += 1900; + return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); +} +#endif +//--------------------------------------------------------------------------- + time_t stg_timegm(struct tm * brokenTime) { +#ifdef WIN32 +static const unsigned ndays[2][12] ={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; +time_t res = 0; +for (int i = 70; i < brokenTime->tm_year; ++i) + res += is_leap(i) ? 366 : 365; +for (int i = 0; i < brokenTime->tm_mon; ++i) + res += ndays[is_leap(brokenTime->tm_year)][i]; +res += brokenTime->tm_mday - 1; +res *= 24; +res += brokenTime->tm_hour; +res *= 60; +res += brokenTime->tm_min; +res *= 60; +res += brokenTime->tm_sec; +return res; +#else #ifdef HAVE_TIMEGM return timegm(brokenTime); #else @@ -844,7 +906,8 @@ else unsetenv("TZ"); tzset(); return ret; -#endif +#endif // HAVE_TIMEGM +#endif // WIN32 } //--------------------------------------------------------------------------- std::string IconvString(const std::string & source, @@ -864,7 +927,7 @@ strncpy(inBuf, source.c_str(), source.length()); inBuf[source.length()] = 0; -#if defined(FREE_BSD) || defined(FREE_BSD5) +#if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32) const char * srcPos = inBuf; #else char * srcPos = inBuf; @@ -916,4 +979,81 @@ delete[] inBuf; return dst; } -//--------------------------------------------------------------------------- + +int ParseYesNo(const std::string & str, bool * val) +{ +if (0 == strncasecmp(str.c_str(), "yes", 3)) + { + *val = true; + return 0; + } + +if (0 == strncasecmp(str.c_str(), "no", 2)) + { + *val = false; + return 0; + } + +return -1; +} + +int ParseInt(const std::string & str, int * val) +{ +if (str2x(str, *val)) + return -1; +return 0; +} + +int ParseUnsigned(const string & str, unsigned * val) +{ +if (str2x(str, *val)) + return -1; +return 0; +} + +int ParseIntInRange(const string & str, int min, int max, int * val) +{ +if (ParseInt(str, val) != 0) + return -1; + +if (*val < min || *val > max) + return -1; + +return 0; +} + +int ParseUnsignedInRange(const string & str, unsigned min, + unsigned max, unsigned * val) +{ +if (ParseUnsigned(str, val) != 0) + return -1; + +if (*val < min || *val > max) + return -1; + +return 0; +} + +bool WaitPackets(int sd) +{ +fd_set rfds; +FD_ZERO(&rfds); +FD_SET(sd, &rfds); + +struct timeval tv; +tv.tv_sec = 0; +tv.tv_usec = 500000; + +int res = select(sd + 1, &rfds, NULL, NULL, &tv); +if (res == -1) // Error + { + if (errno != EINTR) + printfd(__FILE__, "Error on select: '%s'\n", strerror(errno)); + return false; + } + +if (res == 0) // Timeout + return false; + +return true; +}