📄 utility.cpp.svn-base
字号:
#ifdef _WIN32
FILETIME ft; // Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
GetSystemTimeAsFileTime(&ft);
uint64_t tt;
memcpy(&tt, &ft, sizeof(tt));
tt /= 10; // make it usecs
p->tv_sec = (long)tt / 1000000;
p->tv_usec = (long)tt % 1000000;
#else
gettimeofday(p, NULL);
#endif
}
std::auto_ptr<SocketAddress> Utility::CreateAddress(struct sockaddr *sa,socklen_t sa_len)
{
switch (sa -> sa_family)
{
case AF_INET:
if (sa_len == sizeof(struct sockaddr_in))
{
struct sockaddr_in *p = (struct sockaddr_in *)sa;
return std::auto_ptr<SocketAddress>(new Ipv4Address(*p));
}
break;
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
case AF_INET6:
if (sa_len == sizeof(struct sockaddr_in6))
{
struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
return std::auto_ptr<SocketAddress>(new Ipv6Address(*p));
}
break;
#endif
#endif
}
return std::auto_ptr<SocketAddress>(NULL);
}
bool Utility::u2ip(const std::string& host, struct sockaddr_in& sa, int ai_flags)
{
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
#ifdef NO_GETADDRINFO
if ((ai_flags & AI_NUMERICHOST) != 0 || isipv4(host))
{
Parse pa((char *)host.c_str(), ".");
union {
struct {
unsigned char b1;
unsigned char b2;
unsigned char b3;
unsigned char b4;
} a;
ipaddr_t l;
} u;
u.a.b1 = static_cast<unsigned char>(pa.getvalue());
u.a.b2 = static_cast<unsigned char>(pa.getvalue());
u.a.b3 = static_cast<unsigned char>(pa.getvalue());
u.a.b4 = static_cast<unsigned char>(pa.getvalue());
memcpy(&sa.sin_addr, &u.l, sizeof(sa.sin_addr));
return true;
}
#ifndef LINUX
struct hostent *he = gethostbyname( host.c_str() );
if (!he)
{
return false;
}
memcpy(&sa.sin_addr, he -> h_addr, sizeof(sa.sin_addr));
#else
struct hostent he;
struct hostent *result = NULL;
int myerrno = 0;
char buf[2000];
int n = gethostbyname_r(host.c_str(), &he, buf, sizeof(buf), &result, &myerrno);
if (n || !result)
{
return false;
}
if (he.h_addr_list && he.h_addr_list[0])
memcpy(&sa.sin_addr, he.h_addr, 4);
else
return false;
#endif
return true;
#else
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
// AI_NUMERICHOST
// AI_CANONNAME
// AI_PASSIVE - server
// AI_ADDRCONFIG
// AI_V4MAPPED
// AI_ALL
// AI_NUMERICSERV
hints.ai_flags = ai_flags;
hints.ai_family = AF_INET;
hints.ai_socktype = 0;
hints.ai_protocol = 0;
struct addrinfo *res;
if (Utility::isipv4(host))
hints.ai_flags |= AI_NUMERICHOST;
int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
if (!n)
{
std::vector<struct addrinfo *> vec;
struct addrinfo *ai = res;
while (ai)
{
if (ai -> ai_addrlen == sizeof(sa))
vec.push_back( ai );
ai = ai -> ai_next;
}
if (vec.empty())
return false;
ai = vec[Utility::Rnd() % vec.size()];
{
memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
}
freeaddrinfo(res);
return true;
}
std::string error = "Error: ";
#ifndef __CYGWIN__
error += gai_strerror(n);
#endif
return false;
#endif // NO_GETADDRINFO
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
bool Utility::u2ip(const std::string& host, struct sockaddr_in6& sa, int ai_flags)
{
memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6;
#ifdef NO_GETADDRINFO
if ((ai_flags & AI_NUMERICHOST) != 0 || isipv6(host))
{
std::list<std::string> vec;
size_t x = 0;
for (size_t i = 0; i <= host.size(); i++)
{
if (i == host.size() || host[i] == ':')
{
std::string s = host.substr(x, i - x);
//
if (strstr(s.c_str(),".")) // x.x.x.x
{
Parse pa(s,".");
char slask[100]; // u2ip temporary hex2string conversion
unsigned long b0 = static_cast<unsigned long>(pa.getvalue());
unsigned long b1 = static_cast<unsigned long>(pa.getvalue());
unsigned long b2 = static_cast<unsigned long>(pa.getvalue());
unsigned long b3 = static_cast<unsigned long>(pa.getvalue());
sprintf(slask,"%lx",b0 * 256 + b1);
vec.push_back(slask);
sprintf(slask,"%lx",b2 * 256 + b3);
vec.push_back(slask);
}
else
{
vec.push_back(s);
}
//
x = i + 1;
}
}
size_t sz = vec.size(); // number of byte pairs
size_t i = 0; // index in in6_addr.in6_u.u6_addr16[] ( 0 .. 7 )
unsigned short addr16[8];
for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++)
{
std::string bytepair = *it;
if (!bytepair.empty())
{
addr16[i++] = htons(Utility::hex2unsigned(bytepair));
}
else
{
addr16[i++] = 0;
while (sz++ < 8)
{
addr16[i++] = 0;
}
}
}
memcpy(&sa.sin6_addr, addr16, sizeof(addr16));
return true;
}
#ifdef SOLARIS
int errnum = 0;
struct hostent *he = getipnodebyname( host.c_str(), AF_INET6, 0, &errnum );
#else
struct hostent *he = gethostbyname2( host.c_str(), AF_INET6 );
#endif
if (!he)
{
return false;
}
memcpy(&sa.sin6_addr,he -> h_addr_list[0],he -> h_length);
#ifdef SOLARIS
free(he);
#endif
return true;
#else
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = ai_flags;
hints.ai_family = AF_INET6;
hints.ai_socktype = 0;
hints.ai_protocol = 0;
struct addrinfo *res;
if (Utility::isipv6(host))
hints.ai_flags |= AI_NUMERICHOST;
int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
if (!n)
{
std::vector<struct addrinfo *> vec;
struct addrinfo *ai = res;
while (ai)
{
if (ai -> ai_addrlen == sizeof(sa))
vec.push_back( ai );
ai = ai -> ai_next;
}
if (vec.empty())
return false;
ai = vec[Utility::Rnd() % vec.size()];
{
memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
}
freeaddrinfo(res);
return true;
}
std::string error = "Error: ";
#ifndef __CYGWIN__
error += gai_strerror(n);
#endif
return false;
#endif // NO_GETADDRINFO
}
#endif // IPPROTO_IPV6
#endif // ENABLE_IPV6
bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, int flags)
{
std::string service;
return Utility::reverse(sa, sa_len, hostname, service, flags);
}
bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags)
{
hostname = "";
service = "";
#ifdef NO_GETADDRINFO
switch (sa -> sa_family)
{
case AF_INET:
if (flags & NI_NUMERICHOST)
{
union {
struct {
unsigned char b1;
unsigned char b2;
unsigned char b3;
unsigned char b4;
} a;
ipaddr_t l;
} u;
struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
memcpy(&u.l, &sa_in -> sin_addr, sizeof(u.l));
char tmp[100];
sprintf(tmp, "%u.%u.%u.%u", u.a.b1, u.a.b2, u.a.b3, u.a.b4);
hostname = tmp;
return true;
}
else
{
struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin_addr, sizeof(sa_in -> sin_addr), AF_INET);
if (h)
{
hostname = h -> h_name;
return true;
}
}
break;
#ifdef ENABLE_IPV6
case AF_INET6:
if (flags & NI_NUMERICHOST)
{
char slask[100]; // l2ip temporary
*slask = 0;
unsigned int prev = 0;
bool skipped = false;
bool ok_to_skip = true;
{
unsigned short addr16[8];
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
memcpy(addr16, &sa_in6 -> sin6_addr, sizeof(addr16));
for (size_t i = 0; i < 8; i++)
{
unsigned short x = ntohs(addr16[i]);
if (*slask && (x || !ok_to_skip || prev))
strcat(slask,":");
if (x || !ok_to_skip)
{
sprintf(slask + strlen(slask),"%x", x);
if (x && skipped)
ok_to_skip = false;
}
else
{
skipped = true;
}
prev = x;
}
}
if (!*slask)
strcpy(slask, "::");
hostname = slask;
return true;
}
else
{
// %! TODO: ipv6 reverse lookup
struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)sa;
struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin6_addr, sizeof(sa_in -> sin6_addr), AF_INET6);
if (h)
{
hostname = h -> h_name;
return true;
}
}
break;
#endif
}
return false;
#else
char host[NI_MAXHOST];
char serv[NI_MAXSERV];
// NI_NOFQDN
// NI_NUMERICHOST
// NI_NAMEREQD
// NI_NUMERICSERV
// NI_DGRAM
int n = getnameinfo(sa, sa_len, host, sizeof(host), serv, sizeof(serv), flags);
if (n)
{
// EAI_AGAIN
// EAI_BADFLAGS
// EAI_FAIL
// EAI_FAMILY
// EAI_MEMORY
// EAI_NONAME
// EAI_OVERFLOW
// EAI_SYSTEM
return false;
}
hostname = host;
service = serv;
return true;
#endif // NO_GETADDRINFO
}
bool Utility::u2service(const std::string& name, int& service, int ai_flags)
{
#ifdef NO_GETADDRINFO
// %!
return false;
#else
struct addrinfo hints;
service = 0;
memset(&hints, 0, sizeof(hints));
// AI_NUMERICHOST
// AI_CANONNAME
// AI_PASSIVE - server
// AI_ADDRCONFIG
// AI_V4MAPPED
// AI_ALL
// AI_NUMERICSERV
hints.ai_flags = ai_flags;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = 0;
hints.ai_protocol = 0;
struct addrinfo *res;
int n = getaddrinfo(NULL, name.c_str(), &hints, &res);
if (!n)
{
service = res -> ai_protocol;
freeaddrinfo(res);
return true;
}
return false;
#endif // NO_GETADDRINFO
}
unsigned long Utility::ThreadID()
{
#ifdef _WIN32
return GetCurrentThreadId();
#else
return (unsigned long)pthread_self();
#endif
}
std::string Utility::ToLower(const std::string& str)
{
std::string r;
for (size_t i = 0; i < str.size(); i++)
{
if (str[i] >= 'A' && str[i] <= 'Z')
r += str[i] | 32;
else
r += str[i];
}
return r;
}
std::string Utility::ToUpper(const std::string& str)
{
std::string r;
for (size_t i = 0; i < str.size(); i++)
{
if (str[i] >= 'a' && str[i] <= 'z')
r += (char)(str[i] - 32);
else
r += str[i];
}
return r;
}
std::string Utility::ToString(double d)
{
char tmp[100];
sprintf(tmp, "%f", d);
return tmp;
}
unsigned long Utility::Rnd()
{
static Utility::Rng generator( time(NULL) );
return generator.Get();
}
Utility::Rng::Rng(unsigned long seed) : m_value( 0 )
{
m_tmp[0]= seed & 0xffffffffUL;
for (int i = 1; i < TWIST_LEN; i++)
{
m_tmp[i] = (1812433253UL * (m_tmp[i - 1] ^ (m_tmp[i - 1] >> 30)) + i);
}
}
unsigned long Utility::Rng::Get()
{
unsigned long val = m_tmp[m_value];
++m_value;
if (m_value == TWIST_LEN)
{
for (int i = 0; i < TWIST_IB; ++i)
{
unsigned long s = TWIST(m_tmp, i, i + 1);
m_tmp[i] = m_tmp[i + TWIST_IA] ^ (s >> 1) ^ MAGIC_TWIST(s);
}
{
for (int i = 0; i < TWIST_LEN - 1; ++i)
{
unsigned long s = TWIST(m_tmp, i, i + 1);
m_tmp[i] = m_tmp[i - TWIST_IB] ^ (s >> 1) ^ MAGIC_TWIST(s);
}
}
unsigned long s = TWIST(m_tmp, TWIST_LEN - 1, 0);
m_tmp[TWIST_LEN - 1] = m_tmp[TWIST_IA - 1] ^ (s >> 1) ^ MAGIC_TWIST(s);
m_value = 0;
}
return val;
}
#ifdef SOCKETS_NAMESPACE
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -