Used a more uniform of logging and added a commandline parser.
[UnsignedByte.git] / src / Sockets / Utility.cpp
blob867e3544a2b7c9e3a13dcc94c7717ff1c3a28809
1 /** \file Utility.cpp
2 ** \date 2004-02-13
3 ** \author grymse@alhem.net
4 **/
5 /*
6 Copyright (C) 2004-2007 Anders Hedstrom
8 This library is made available under the terms of the GNU GPL.
10 If you would like to use this library in a closed-source application,
11 a separate license agreement is available. For information about
12 the closed-source license agreement for the C++ sockets library,
13 please visit http://www.alhem.net/Sockets/license.html and/or
14 email license@alhem.net.
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License
18 as published by the Free Software Foundation; either version 2
19 of the License, or (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include "Utility.h"
31 #include "Parse.h"
32 #include "Ipv4Address.h"
33 #include "Ipv6Address.h"
34 #include "RandomNumber.h"
35 #include <vector>
36 #ifdef _WIN32
37 #include <time.h>
38 #else
39 #include <netdb.h>
40 #include <pthread.h>
41 #endif
42 #include <map>
44 #ifdef SOCKETS_NAMESPACE
45 namespace SOCKETS_NAMESPACE {
46 #endif
49 // statics
50 std::string Utility::m_host;
51 bool Utility::m_local_resolved = false;
52 ipaddr_t Utility::m_ip = 0;
53 std::string Utility::m_addr;
54 #ifdef ENABLE_IPV6
55 #ifdef IPPROTO_IPV6
56 struct in6_addr Utility::m_local_ip6;
57 std::string Utility::m_local_addr6;
58 #endif
59 #endif
62 std::string Utility::base64(const std::string& str_in)
64 std::string str;
65 Base64 m_b;
66 m_b.encode(str_in, str, false); // , false == do not add cr/lf
67 return str;
71 std::string Utility::base64d(const std::string& str_in)
73 std::string str;
74 Base64 m_b;
75 m_b.decode(str_in, str);
76 return str;
80 std::string Utility::l2string(long l)
82 std::string str;
83 char tmp[100];
84 sprintf(tmp,"%ld",l);
85 str = tmp;
86 return str;
90 std::string Utility::bigint2string(uint64_t l)
92 std::string str;
93 uint64_t tmp = l;
94 while (tmp)
96 uint64_t a = tmp % 10;
97 str = (char)(a + 48) + str;
98 tmp /= 10;
100 if (!str.size())
102 str = "0";
104 return str;
108 uint64_t Utility::atoi64(const std::string& str)
110 uint64_t l = 0;
111 for (size_t i = 0; i < str.size(); i++)
113 l = l * 10 + str[i] - 48;
115 return l;
119 unsigned int Utility::hex2unsigned(const std::string& str)
121 unsigned int r = 0;
122 for (size_t i = 0; i < str.size(); i++)
124 r = r * 16 + str[i] - 48 - ((str[i] >= 'A') ? 7 : 0) - ((str[i] >= 'a') ? 32 : 0);
126 return r;
131 * Encode string per RFC1738 URL encoding rules
132 * tnx rstaveley
134 std::string Utility::rfc1738_encode(const std::string& src)
136 static char hex[] = "0123456789ABCDEF";
137 std::string dst;
138 for (size_t i = 0; i < src.size(); i++)
140 if (isalnum(src[i]))
142 dst += src[i];
144 else
145 if (src[i] == ' ')
147 dst += '+';
149 else
151 unsigned char c = static_cast<unsigned char>(src[i]);
152 dst += '%';
153 dst += hex[c / 16];
154 dst += hex[c % 16];
157 return dst;
158 } // rfc1738_encode
162 * Decode string per RFC1738 URL encoding rules
163 * tnx rstaveley
165 std::string Utility::rfc1738_decode(const std::string& src)
167 std::string dst;
168 for (size_t i = 0; i < src.size(); i++)
170 if (src[i] == '%' && isxdigit(src[i + 1]) && isxdigit(src[i + 2]))
172 char c1 = src[++i];
173 char c2 = src[++i];
174 c1 = c1 - 48 - ((c1 >= 'A') ? 7 : 0) - ((c1 >= 'a') ? 32 : 0);
175 c2 = c2 - 48 - ((c2 >= 'A') ? 7 : 0) - ((c2 >= 'a') ? 32 : 0);
176 dst += (char)(c1 * 16 + c2);
178 else
179 if (src[i] == '+')
181 dst += ' ';
183 else
185 dst += src[i];
188 return dst;
189 } // rfc1738_decode
192 bool Utility::isipv4(const std::string& str)
194 int dots = 0;
195 // %! ignore :port?
196 for (size_t i = 0; i < str.size(); i++)
198 if (str[i] == '.')
199 dots++;
200 else
201 if (!isdigit(str[i]))
202 return false;
204 if (dots != 3)
205 return false;
206 return true;
210 bool Utility::isipv6(const std::string& str)
212 size_t qc = 0;
213 size_t qd = 0;
214 for (size_t i = 0; i < str.size(); i++)
216 qc += (str[i] == ':') ? 1 : 0;
217 qd += (str[i] == '.') ? 1 : 0;
219 if (qc > 7)
221 return false;
223 if (qd && qd != 3)
225 return false;
227 Parse pa(str,":.");
228 std::string tmp = pa.getword();
229 while (tmp.size())
231 if (tmp.size() > 4)
233 return false;
235 for (size_t i = 0; i < tmp.size(); i++)
237 if (tmp[i] < '0' || (tmp[i] > '9' && tmp[i] < 'A') ||
238 (tmp[i] > 'F' && tmp[i] < 'a') || tmp[i] > 'f')
240 return false;
244 tmp = pa.getword();
246 return true;
250 bool Utility::u2ip(const std::string& str, ipaddr_t& l)
252 struct sockaddr_in sa;
253 bool r = Utility::u2ip(str, sa);
254 memcpy(&l, &sa.sin_addr, sizeof(l));
255 return r;
259 #ifdef ENABLE_IPV6
260 #ifdef IPPROTO_IPV6
261 bool Utility::u2ip(const std::string& str, struct in6_addr& l)
263 struct sockaddr_in6 sa;
264 bool r = Utility::u2ip(str, sa);
265 l = sa.sin6_addr;
266 return r;
268 #endif
269 #endif
272 void Utility::l2ip(const ipaddr_t ip, std::string& str)
274 struct sockaddr_in sa;
275 memset(&sa, 0, sizeof(sa));
276 sa.sin_family = AF_INET;
277 memcpy(&sa.sin_addr, &ip, sizeof(sa.sin_addr));
278 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
282 void Utility::l2ip(const in_addr& ip, std::string& str)
284 struct sockaddr_in sa;
285 memset(&sa, 0, sizeof(sa));
286 sa.sin_family = AF_INET;
287 sa.sin_addr = ip;
288 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
292 #ifdef ENABLE_IPV6
293 #ifdef IPPROTO_IPV6
294 void Utility::l2ip(const struct in6_addr& ip, std::string& str,bool mixed)
296 char slask[100]; // l2ip temporary
297 *slask = 0;
298 unsigned int prev = 0;
299 bool skipped = false;
300 bool ok_to_skip = true;
301 if (mixed)
303 unsigned short x;
304 unsigned short addr16[8];
305 memcpy(addr16, &ip, sizeof(addr16));
306 for (size_t i = 0; i < 6; i++)
308 x = ntohs(addr16[i]);
309 if (*slask && (x || !ok_to_skip || prev))
310 strcat(slask,":");
311 if (x || !ok_to_skip)
313 sprintf(slask + strlen(slask),"%x", x);
314 if (x && skipped)
315 ok_to_skip = false;
317 else
319 skipped = true;
321 prev = x;
323 x = ntohs(addr16[6]);
324 sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255);
325 x = ntohs(addr16[7]);
326 sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255);
328 else
330 struct sockaddr_in6 sa;
331 memset(&sa, 0, sizeof(sa));
332 sa.sin6_family = AF_INET6;
333 sa.sin6_addr = ip;
334 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
335 return;
337 str = slask;
341 int Utility::in6_addr_compare(in6_addr a,in6_addr b)
343 for (size_t i = 0; i < 16; i++)
345 if (a.s6_addr[i] < b.s6_addr[i])
346 return -1;
347 if (a.s6_addr[i] > b.s6_addr[i])
348 return 1;
350 return 0;
352 #endif
353 #endif
356 void Utility::ResolveLocal()
358 char h[256];
360 // get local hostname and translate into ip-address
361 *h = 0;
362 gethostname(h,255);
364 if (Utility::u2ip(h, m_ip))
366 Utility::l2ip(m_ip, m_addr);
369 #ifdef ENABLE_IPV6
370 #ifdef IPPROTO_IPV6
371 memset(&m_local_ip6, 0, sizeof(m_local_ip6));
373 if (Utility::u2ip(h, m_local_ip6))
375 Utility::l2ip(m_local_ip6, m_local_addr6);
378 #endif
379 #endif
380 m_host = h;
381 m_local_resolved = true;
385 const std::string& Utility::GetLocalHostname()
387 if (!m_local_resolved)
389 ResolveLocal();
391 return m_host;
395 ipaddr_t Utility::GetLocalIP()
397 if (!m_local_resolved)
399 ResolveLocal();
401 return m_ip;
405 const std::string& Utility::GetLocalAddress()
407 if (!m_local_resolved)
409 ResolveLocal();
411 return m_addr;
415 #ifdef ENABLE_IPV6
416 #ifdef IPPROTO_IPV6
417 const struct in6_addr& Utility::GetLocalIP6()
419 if (!m_local_resolved)
421 ResolveLocal();
423 return m_local_ip6;
427 const std::string& Utility::GetLocalAddress6()
429 if (!m_local_resolved)
431 ResolveLocal();
433 return m_local_addr6;
435 #endif
436 #endif
439 void Utility::SetEnv(const std::string& var,const std::string& value)
441 #if (defined(SOLARIS8) || defined(SOLARIS))
443 static std::map<std::string, char *> vmap;
444 if (vmap.find(var) != vmap.end())
446 delete[] vmap[var];
448 vmap[var] = new char[var.size() + 1 + value.size() + 1];
449 sprintf(vmap[var], "%s=%s", var.c_str(), value.c_str());
450 putenv( vmap[var] );
452 #elif defined _WIN32
454 std::string slask = var + "=" + value;
455 _putenv( (char *)slask.c_str());
457 #else
458 setenv(var.c_str(), value.c_str(), 1);
459 #endif
463 std::string Utility::Sa2String(struct sockaddr *sa)
465 #ifdef ENABLE_IPV6
466 #ifdef IPPROTO_IPV6
467 if (sa -> sa_family == AF_INET6)
469 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
470 std::string tmp;
471 Utility::l2ip(sa6 -> sin6_addr, tmp);
472 return tmp + ":" + Utility::l2string(ntohs(sa6 -> sin6_port));
474 #endif
475 #endif
476 if (sa -> sa_family == AF_INET)
478 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
479 ipaddr_t a;
480 memcpy(&a, &sa4 -> sin_addr, 4);
481 std::string tmp;
482 Utility::l2ip(a, tmp);
483 return tmp + ":" + Utility::l2string(ntohs(sa4 -> sin_port));
485 return "";
489 void Utility::GetTime(struct timeval *p)
491 #ifdef _WIN32
492 FILETIME ft; // Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
493 GetSystemTimeAsFileTime(&ft);
494 uint64_t tt;
495 memcpy(&tt, &ft, sizeof(tt));
496 tt /= 10; // make it usecs
497 p->tv_sec = (long)tt / 1000000;
498 p->tv_usec = (long)tt % 1000000;
499 #else
500 gettimeofday(p, NULL);
501 #endif
505 std::auto_ptr<SocketAddress> Utility::CreateAddress(struct sockaddr *sa,socklen_t sa_len)
507 switch (sa -> sa_family)
509 case AF_INET:
510 if (sa_len == sizeof(struct sockaddr_in))
512 struct sockaddr_in *p = (struct sockaddr_in *)sa;
513 return std::auto_ptr<SocketAddress>(new Ipv4Address(*p));
515 break;
516 #ifdef ENABLE_IPV6
517 #ifdef IPPROTO_IPV6
518 case AF_INET6:
519 if (sa_len == sizeof(struct sockaddr_in6))
521 struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
522 return std::auto_ptr<SocketAddress>(new Ipv6Address(*p));
524 break;
525 #endif
526 #endif
528 return std::auto_ptr<SocketAddress>(NULL);
532 bool Utility::u2ip(const std::string& host, struct sockaddr_in& sa, int ai_flags)
534 memset(&sa, 0, sizeof(sa));
535 sa.sin_family = AF_INET;
536 #ifdef NO_GETADDRINFO
537 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv4(host))
539 Parse pa((char *)host.c_str(), ".");
540 union {
541 struct {
542 unsigned char b1;
543 unsigned char b2;
544 unsigned char b3;
545 unsigned char b4;
546 } a;
547 ipaddr_t l;
548 } u;
549 u.a.b1 = static_cast<unsigned char>(pa.getvalue());
550 u.a.b2 = static_cast<unsigned char>(pa.getvalue());
551 u.a.b3 = static_cast<unsigned char>(pa.getvalue());
552 u.a.b4 = static_cast<unsigned char>(pa.getvalue());
553 memcpy(&sa.sin_addr, &u.l, sizeof(sa.sin_addr));
554 return true;
556 #ifndef LINUX
557 struct hostent *he = gethostbyname( host.c_str() );
558 if (!he)
560 return false;
562 memcpy(&sa.sin_addr, he -> h_addr, sizeof(sa.sin_addr));
563 #else
564 struct hostent he;
565 struct hostent *result;
566 int myerrno;
567 char buf[2000];
568 int n = gethostbyname_r(host.c_str(), &he, buf, sizeof(buf), &result, &myerrno);
569 if (n)
571 return false;
573 memcpy(&sa.sin_addr, he.h_addr, 4);
574 #endif
575 return true;
576 #else
577 struct addrinfo hints;
578 memset(&hints, 0, sizeof(hints));
579 // AI_NUMERICHOST
580 // AI_CANONNAME
581 // AI_PASSIVE - server
582 // AI_ADDRCONFIG
583 // AI_V4MAPPED
584 // AI_ALL
585 // AI_NUMERICSERV
586 hints.ai_flags = ai_flags;
587 hints.ai_family = AF_INET;
588 hints.ai_socktype = 0;
589 hints.ai_protocol = 0;
590 struct addrinfo *res;
591 if (Utility::isipv4(host))
592 hints.ai_flags |= AI_NUMERICHOST;
593 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
594 if (!n)
596 static RandomNumber prng( true );
597 std::vector<struct addrinfo *> vec;
598 struct addrinfo *ai = res;
599 while (ai)
601 if (ai -> ai_addrlen == sizeof(sa))
602 vec.push_back( ai );
603 prng.next();
605 ai = ai -> ai_next;
607 if (!vec.size())
608 return false;
609 ai = vec[prng.next() % vec.size()];
611 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
613 freeaddrinfo(res);
614 return true;
616 std::string error = "Error: ";
617 #ifndef __CYGWIN__
618 error += gai_strerror(n);
619 #endif
620 return false;
621 #endif // NO_GETADDRINFO
625 #ifdef ENABLE_IPV6
626 #ifdef IPPROTO_IPV6
627 bool Utility::u2ip(const std::string& host, struct sockaddr_in6& sa, int ai_flags)
629 memset(&sa, 0, sizeof(sa));
630 sa.sin6_family = AF_INET6;
631 #ifdef NO_GETADDRINFO
632 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv6(host))
634 std::list<std::string> vec;
635 size_t x = 0;
636 for (size_t i = 0; i <= host.size(); i++)
638 if (i == host.size() || host[i] == ':')
640 std::string s = host.substr(x, i - x);
642 if (strstr(s.c_str(),".")) // x.x.x.x
644 Parse pa(s,".");
645 char slask[100]; // u2ip temporary hex2string conversion
646 unsigned long b0 = static_cast<unsigned long>(pa.getvalue());
647 unsigned long b1 = static_cast<unsigned long>(pa.getvalue());
648 unsigned long b2 = static_cast<unsigned long>(pa.getvalue());
649 unsigned long b3 = static_cast<unsigned long>(pa.getvalue());
650 sprintf(slask,"%lx",b0 * 256 + b1);
651 vec.push_back(slask);
652 sprintf(slask,"%lx",b2 * 256 + b3);
653 vec.push_back(slask);
655 else
657 vec.push_back(s);
660 x = i + 1;
663 size_t sz = vec.size(); // number of byte pairs
664 size_t i = 0; // index in in6_addr.in6_u.u6_addr16[] ( 0 .. 7 )
665 unsigned short addr16[8];
666 for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++)
668 std::string bytepair = *it;
669 if (bytepair.size())
671 addr16[i++] = htons(Utility::hex2unsigned(bytepair));
673 else
675 addr16[i++] = 0;
676 while (sz++ < 8)
678 addr16[i++] = 0;
682 memcpy(&sa.sin6_addr, addr16, sizeof(addr16));
683 return true;
685 #ifdef SOLARIS
686 int errnum = 0;
687 struct hostent *he = getipnodebyname( host.c_str(), AF_INET6, 0, &errnum );
688 #else
689 struct hostent *he = gethostbyname2( host.c_str(), AF_INET6 );
690 #endif
691 if (!he)
693 return false;
695 memcpy(&sa.sin6_addr,he -> h_addr_list[0],he -> h_length);
696 #ifdef SOLARIS
697 free(he);
698 #endif
699 return true;
700 #else
701 struct addrinfo hints;
702 memset(&hints, 0, sizeof(hints));
703 hints.ai_flags = ai_flags;
704 hints.ai_family = AF_INET6;
705 hints.ai_socktype = 0;
706 hints.ai_protocol = 0;
707 struct addrinfo *res;
708 if (Utility::isipv6(host))
709 hints.ai_flags |= AI_NUMERICHOST;
710 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
711 if (!n)
713 static RandomNumber prng( true );
714 std::vector<struct addrinfo *> vec;
715 struct addrinfo *ai = res;
716 while (ai)
718 if (ai -> ai_addrlen == sizeof(sa))
719 vec.push_back( ai );
720 prng.next();
722 ai = ai -> ai_next;
724 if (!vec.size())
725 return false;
726 ai = vec[prng.next() % vec.size()];
728 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
730 freeaddrinfo(res);
731 return true;
733 std::string error = "Error: ";
734 #ifndef __CYGWIN__
735 error += gai_strerror(n);
736 #endif
737 return false;
738 #endif // NO_GETADDRINFO
740 #endif // IPPROTO_IPV6
741 #endif // ENABLE_IPV6
744 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, int flags)
746 std::string service;
747 return Utility::reverse(sa, sa_len, hostname, service, flags);
751 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags)
753 hostname = "";
754 service = "";
755 #ifdef NO_GETADDRINFO
756 switch (sa -> sa_family)
758 case AF_INET:
759 if (flags & NI_NUMERICHOST)
761 union {
762 struct {
763 unsigned char b1;
764 unsigned char b2;
765 unsigned char b3;
766 unsigned char b4;
767 } a;
768 ipaddr_t l;
769 } u;
770 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
771 memcpy(&u.l, &sa_in -> sin_addr, sizeof(u.l));
772 char tmp[100];
773 sprintf(tmp, "%u.%u.%u.%u", u.a.b1, u.a.b2, u.a.b3, u.a.b4);
774 hostname = tmp;
775 return true;
777 else
779 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
780 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin_addr, sizeof(sa_in -> sin_addr), AF_INET);
781 if (h)
783 hostname = h -> h_name;
784 return true;
787 break;
788 #ifdef ENABLE_IPV6
789 case AF_INET6:
790 if (flags & NI_NUMERICHOST)
792 char slask[100]; // l2ip temporary
793 *slask = 0;
794 unsigned int prev = 0;
795 bool skipped = false;
796 bool ok_to_skip = true;
798 unsigned short addr16[8];
799 struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
800 memcpy(addr16, &sa_in6 -> sin6_addr, sizeof(addr16));
801 for (size_t i = 0; i < 8; i++)
803 unsigned short x = ntohs(addr16[i]);
804 if (*slask && (x || !ok_to_skip || prev))
805 strcat(slask,":");
806 if (x || !ok_to_skip)
808 sprintf(slask + strlen(slask),"%x", x);
809 if (x && skipped)
810 ok_to_skip = false;
812 else
814 skipped = true;
816 prev = x;
819 if (!*slask)
820 strcpy(slask, "::");
821 hostname = slask;
822 return true;
824 else
826 // %! TODO: ipv6 reverse lookup
827 struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)sa;
828 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin6_addr, sizeof(sa_in -> sin6_addr), AF_INET6);
829 if (h)
831 hostname = h -> h_name;
832 return true;
835 break;
836 #endif
838 return false;
839 #else
840 char host[NI_MAXHOST];
841 char serv[NI_MAXSERV];
842 // NI_NOFQDN
843 // NI_NUMERICHOST
844 // NI_NAMEREQD
845 // NI_NUMERICSERV
846 // NI_DGRAM
847 int n = getnameinfo(sa, sa_len, host, sizeof(host), serv, sizeof(serv), flags);
848 if (n)
850 // EAI_AGAIN
851 // EAI_BADFLAGS
852 // EAI_FAIL
853 // EAI_FAMILY
854 // EAI_MEMORY
855 // EAI_NONAME
856 // EAI_OVERFLOW
857 // EAI_SYSTEM
858 return false;
860 hostname = host;
861 service = serv;
862 return true;
863 #endif // NO_GETADDRINFO
867 bool Utility::u2service(const std::string& name, int& service, int ai_flags)
869 #ifdef NO_GETADDRINFO
870 // %!
871 return false;
872 #else
873 struct addrinfo hints;
874 service = 0;
875 memset(&hints, 0, sizeof(hints));
876 // AI_NUMERICHOST
877 // AI_CANONNAME
878 // AI_PASSIVE - server
879 // AI_ADDRCONFIG
880 // AI_V4MAPPED
881 // AI_ALL
882 // AI_NUMERICSERV
883 hints.ai_flags = ai_flags;
884 hints.ai_family = AF_UNSPEC;
885 hints.ai_socktype = 0;
886 hints.ai_protocol = 0;
887 struct addrinfo *res;
888 int n = getaddrinfo(NULL, name.c_str(), &hints, &res);
889 if (!n)
891 service = res -> ai_protocol;
892 freeaddrinfo(res);
893 return true;
895 return false;
896 #endif // NO_GETADDRINFO
900 unsigned long Utility::ThreadID()
902 #ifdef _WIN32
903 return GetCurrentThreadId();
904 #else
905 return (unsigned long)pthread_self();
906 #endif
910 std::string Utility::ToLower(const std::string& str)
912 std::string r;
913 for (size_t i = 0; i < str.size(); i++)
915 if (str[i] >= 'A' && str[i] <= 'Z')
916 r += str[i] | 32;
917 else
918 r += str[i];
920 return r;
924 std::string Utility::ToUpper(const std::string& str)
926 std::string r;
927 for (size_t i = 0; i < str.size(); i++)
929 if (str[i] >= 'a' && str[i] <= 'z')
930 r += (char)(str[i] - 32);
931 else
932 r += str[i];
934 return r;
938 std::string Utility::ToString(double d)
940 char tmp[100];
941 sprintf(tmp, "%f", d);
942 return tmp;
946 #ifdef SOCKETS_NAMESPACE
948 #endif