big svn cleanup
[anytun.git] / src / Sockets / Utility.cpp
bloba80e2a8236d2e4904485dc80b5b22bb08572ce7a
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 "Base64.h"
36 #include <vector>
37 #ifdef _WIN32
38 #include <time.h>
39 #else
40 #include <netdb.h>
41 #include <pthread.h>
42 #endif
43 #include <map>
45 #ifdef SOCKETS_NAMESPACE
46 namespace SOCKETS_NAMESPACE {
47 #endif
50 // statics
51 std::string Utility::m_host;
52 bool Utility::m_local_resolved = false;
53 ipaddr_t Utility::m_ip = 0;
54 std::string Utility::m_addr;
55 #ifdef ENABLE_IPV6
56 #ifdef IPPROTO_IPV6
57 struct in6_addr Utility::m_local_ip6;
58 std::string Utility::m_local_addr6;
59 #endif
60 #endif
63 std::string Utility::base64(const std::string& str_in)
65 std::string str;
66 Base64 m_b;
67 m_b.encode(str_in, str, false); // , false == do not add cr/lf
68 return str;
72 std::string Utility::base64d(const std::string& str_in)
74 std::string str;
75 Base64 m_b;
76 m_b.decode(str_in, str);
77 return str;
81 std::string Utility::l2string(long l)
83 std::string str;
84 char tmp[100];
85 sprintf(tmp,"%ld",l);
86 str = tmp;
87 return str;
91 std::string Utility::bigint2string(uint64_t l)
93 std::string str;
94 uint64_t tmp = l;
95 while (tmp)
97 uint64_t a = tmp % 10;
98 str = (char)(a + 48) + str;
99 tmp /= 10;
101 if (!str.size())
103 str = "0";
105 return str;
109 uint64_t Utility::atoi64(const std::string& str)
111 uint64_t l = 0;
112 for (size_t i = 0; i < str.size(); i++)
114 l = l * 10 + str[i] - 48;
116 return l;
120 unsigned int Utility::hex2unsigned(const std::string& str)
122 unsigned int r = 0;
123 for (size_t i = 0; i < str.size(); i++)
125 r = r * 16 + str[i] - 48 - ((str[i] >= 'A') ? 7 : 0) - ((str[i] >= 'a') ? 32 : 0);
127 return r;
132 * Encode string per RFC1738 URL encoding rules
133 * tnx rstaveley
135 std::string Utility::rfc1738_encode(const std::string& src)
137 static char hex[] = "0123456789ABCDEF";
138 std::string dst;
139 for (size_t i = 0; i < src.size(); i++)
141 if (isalnum(src[i]))
143 dst += src[i];
145 else
146 if (src[i] == ' ')
148 dst += '+';
150 else
152 unsigned char c = static_cast<unsigned char>(src[i]);
153 dst += '%';
154 dst += hex[c / 16];
155 dst += hex[c % 16];
158 return dst;
159 } // rfc1738_encode
163 * Decode string per RFC1738 URL encoding rules
164 * tnx rstaveley
166 std::string Utility::rfc1738_decode(const std::string& src)
168 std::string dst;
169 for (size_t i = 0; i < src.size(); i++)
171 if (src[i] == '%' && isxdigit(src[i + 1]) && isxdigit(src[i + 2]))
173 char c1 = src[++i];
174 char c2 = src[++i];
175 c1 = c1 - 48 - ((c1 >= 'A') ? 7 : 0) - ((c1 >= 'a') ? 32 : 0);
176 c2 = c2 - 48 - ((c2 >= 'A') ? 7 : 0) - ((c2 >= 'a') ? 32 : 0);
177 dst += (char)(c1 * 16 + c2);
179 else
180 if (src[i] == '+')
182 dst += ' ';
184 else
186 dst += src[i];
189 return dst;
190 } // rfc1738_decode
193 bool Utility::isipv4(const std::string& str)
195 int dots = 0;
196 // %! ignore :port?
197 for (size_t i = 0; i < str.size(); i++)
199 if (str[i] == '.')
200 dots++;
201 else
202 if (!isdigit(str[i]))
203 return false;
205 if (dots != 3)
206 return false;
207 return true;
211 bool Utility::isipv6(const std::string& str)
213 size_t qc = 0;
214 size_t qd = 0;
215 for (size_t i = 0; i < str.size(); i++)
217 qc += (str[i] == ':') ? 1 : 0;
218 qd += (str[i] == '.') ? 1 : 0;
220 if (qc > 7)
222 return false;
224 if (qd && qd != 3)
226 return false;
228 Parse pa(str,":.");
229 std::string tmp = pa.getword();
230 while (tmp.size())
232 if (tmp.size() > 4)
234 return false;
236 for (size_t i = 0; i < tmp.size(); i++)
238 if (tmp[i] < '0' || (tmp[i] > '9' && tmp[i] < 'A') ||
239 (tmp[i] > 'F' && tmp[i] < 'a') || tmp[i] > 'f')
241 return false;
245 tmp = pa.getword();
247 return true;
251 bool Utility::u2ip(const std::string& str, ipaddr_t& l)
253 struct sockaddr_in sa;
254 bool r = Utility::u2ip(str, sa);
255 memcpy(&l, &sa.sin_addr, sizeof(l));
256 return r;
260 #ifdef ENABLE_IPV6
261 #ifdef IPPROTO_IPV6
262 bool Utility::u2ip(const std::string& str, struct in6_addr& l)
264 struct sockaddr_in6 sa;
265 bool r = Utility::u2ip(str, sa);
266 l = sa.sin6_addr;
267 return r;
269 #endif
270 #endif
273 void Utility::l2ip(const ipaddr_t ip, std::string& str)
275 struct sockaddr_in sa;
276 memset(&sa, 0, sizeof(sa));
277 sa.sin_family = AF_INET;
278 memcpy(&sa.sin_addr, &ip, sizeof(sa.sin_addr));
279 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
283 void Utility::l2ip(const in_addr& ip, std::string& str)
285 struct sockaddr_in sa;
286 memset(&sa, 0, sizeof(sa));
287 sa.sin_family = AF_INET;
288 sa.sin_addr = ip;
289 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
293 #ifdef ENABLE_IPV6
294 #ifdef IPPROTO_IPV6
295 void Utility::l2ip(const struct in6_addr& ip, std::string& str,bool mixed)
297 char slask[100]; // l2ip temporary
298 *slask = 0;
299 unsigned int prev = 0;
300 bool skipped = false;
301 bool ok_to_skip = true;
302 if (mixed)
304 unsigned short x;
305 unsigned short addr16[8];
306 memcpy(addr16, &ip, sizeof(addr16));
307 for (size_t i = 0; i < 6; i++)
309 x = ntohs(addr16[i]);
310 if (*slask && (x || !ok_to_skip || prev))
311 strcat(slask,":");
312 if (x || !ok_to_skip)
314 sprintf(slask + strlen(slask),"%x", x);
315 if (x && skipped)
316 ok_to_skip = false;
318 else
320 skipped = true;
322 prev = x;
324 x = ntohs(addr16[6]);
325 sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255);
326 x = ntohs(addr16[7]);
327 sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255);
329 else
331 struct sockaddr_in6 sa;
332 memset(&sa, 0, sizeof(sa));
333 sa.sin6_family = AF_INET6;
334 sa.sin6_addr = ip;
335 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
336 return;
338 str = slask;
342 int Utility::in6_addr_compare(in6_addr a,in6_addr b)
344 for (size_t i = 0; i < 16; i++)
346 if (a.s6_addr[i] < b.s6_addr[i])
347 return -1;
348 if (a.s6_addr[i] > b.s6_addr[i])
349 return 1;
351 return 0;
353 #endif
354 #endif
357 void Utility::ResolveLocal()
359 char h[256];
361 // get local hostname and translate into ip-address
362 *h = 0;
363 gethostname(h,255);
365 if (Utility::u2ip(h, m_ip))
367 Utility::l2ip(m_ip, m_addr);
370 #ifdef ENABLE_IPV6
371 #ifdef IPPROTO_IPV6
372 memset(&m_local_ip6, 0, sizeof(m_local_ip6));
374 if (Utility::u2ip(h, m_local_ip6))
376 Utility::l2ip(m_local_ip6, m_local_addr6);
379 #endif
380 #endif
381 m_host = h;
382 m_local_resolved = true;
386 const std::string& Utility::GetLocalHostname()
388 if (!m_local_resolved)
390 ResolveLocal();
392 return m_host;
396 ipaddr_t Utility::GetLocalIP()
398 if (!m_local_resolved)
400 ResolveLocal();
402 return m_ip;
406 const std::string& Utility::GetLocalAddress()
408 if (!m_local_resolved)
410 ResolveLocal();
412 return m_addr;
416 #ifdef ENABLE_IPV6
417 #ifdef IPPROTO_IPV6
418 const struct in6_addr& Utility::GetLocalIP6()
420 if (!m_local_resolved)
422 ResolveLocal();
424 return m_local_ip6;
428 const std::string& Utility::GetLocalAddress6()
430 if (!m_local_resolved)
432 ResolveLocal();
434 return m_local_addr6;
436 #endif
437 #endif
440 void Utility::SetEnv(const std::string& var,const std::string& value)
442 #if (defined(SOLARIS8) || defined(SOLARIS))
444 static std::map<std::string, char *> vmap;
445 if (vmap.find(var) != vmap.end())
447 delete[] vmap[var];
449 vmap[var] = new char[var.size() + 1 + value.size() + 1];
450 sprintf(vmap[var], "%s=%s", var.c_str(), value.c_str());
451 putenv( vmap[var] );
453 #elif defined _WIN32
455 std::string slask = var + "=" + value;
456 _putenv( (char *)slask.c_str());
458 #else
459 setenv(var.c_str(), value.c_str(), 1);
460 #endif
464 std::string Utility::Sa2String(struct sockaddr *sa)
466 #ifdef ENABLE_IPV6
467 #ifdef IPPROTO_IPV6
468 if (sa -> sa_family == AF_INET6)
470 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
471 std::string tmp;
472 Utility::l2ip(sa6 -> sin6_addr, tmp);
473 return tmp + ":" + Utility::l2string(ntohs(sa6 -> sin6_port));
475 #endif
476 #endif
477 if (sa -> sa_family == AF_INET)
479 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
480 ipaddr_t a;
481 memcpy(&a, &sa4 -> sin_addr, 4);
482 std::string tmp;
483 Utility::l2ip(a, tmp);
484 return tmp + ":" + Utility::l2string(ntohs(sa4 -> sin_port));
486 return "";
490 void Utility::GetTime(struct timeval *p)
492 #ifdef _WIN32
493 FILETIME ft; // Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
494 GetSystemTimeAsFileTime(&ft);
495 uint64_t tt;
496 memcpy(&tt, &ft, sizeof(tt));
497 tt /= 10; // make it usecs
498 p->tv_sec = (long)tt / 1000000;
499 p->tv_usec = (long)tt % 1000000;
500 #else
501 gettimeofday(p, NULL);
502 #endif
506 std::auto_ptr<SocketAddress> Utility::CreateAddress(struct sockaddr *sa,socklen_t sa_len)
508 switch (sa -> sa_family)
510 case AF_INET:
511 if (sa_len == sizeof(struct sockaddr_in))
513 struct sockaddr_in *p = (struct sockaddr_in *)sa;
514 return std::auto_ptr<SocketAddress>(new Ipv4Address(*p));
516 break;
517 #ifdef ENABLE_IPV6
518 #ifdef IPPROTO_IPV6
519 case AF_INET6:
520 if (sa_len == sizeof(struct sockaddr_in6))
522 struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
523 return std::auto_ptr<SocketAddress>(new Ipv6Address(*p));
525 break;
526 #endif
527 #endif
529 return std::auto_ptr<SocketAddress>(NULL);
533 bool Utility::u2ip(const std::string& host, struct sockaddr_in& sa, int ai_flags)
535 memset(&sa, 0, sizeof(sa));
536 sa.sin_family = AF_INET;
537 #ifdef NO_GETADDRINFO
538 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv4(host))
540 Parse pa((char *)host.c_str(), ".");
541 union {
542 struct {
543 unsigned char b1;
544 unsigned char b2;
545 unsigned char b3;
546 unsigned char b4;
547 } a;
548 ipaddr_t l;
549 } u;
550 u.a.b1 = static_cast<unsigned char>(pa.getvalue());
551 u.a.b2 = static_cast<unsigned char>(pa.getvalue());
552 u.a.b3 = static_cast<unsigned char>(pa.getvalue());
553 u.a.b4 = static_cast<unsigned char>(pa.getvalue());
554 memcpy(&sa.sin_addr, &u.l, sizeof(sa.sin_addr));
555 return true;
557 #ifndef LINUX
558 struct hostent *he = gethostbyname( host.c_str() );
559 if (!he)
561 return false;
563 memcpy(&sa.sin_addr, he -> h_addr, sizeof(sa.sin_addr));
564 #else
565 struct hostent he;
566 struct hostent *result = NULL;
567 int myerrno = 0;
568 char buf[2000];
569 int n = gethostbyname_r(host.c_str(), &he, buf, sizeof(buf), &result, &myerrno);
570 if (n || !result)
572 return false;
574 if (he.h_addr_list && he.h_addr_list[0])
575 memcpy(&sa.sin_addr, he.h_addr, 4);
576 else
577 return false;
578 #endif
579 return true;
580 #else
581 struct addrinfo hints;
582 memset(&hints, 0, sizeof(hints));
583 // AI_NUMERICHOST
584 // AI_CANONNAME
585 // AI_PASSIVE - server
586 // AI_ADDRCONFIG
587 // AI_V4MAPPED
588 // AI_ALL
589 // AI_NUMERICSERV
590 hints.ai_flags = ai_flags;
591 hints.ai_family = AF_INET;
592 hints.ai_socktype = 0;
593 hints.ai_protocol = 0;
594 struct addrinfo *res;
595 if (Utility::isipv4(host))
596 hints.ai_flags |= AI_NUMERICHOST;
597 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
598 if (!n)
600 static RandomNumber prng( true );
601 std::vector<struct addrinfo *> vec;
602 struct addrinfo *ai = res;
603 while (ai)
605 if (ai -> ai_addrlen == sizeof(sa))
606 vec.push_back( ai );
607 prng.next();
609 ai = ai -> ai_next;
611 if (!vec.size())
612 return false;
613 ai = vec[prng.next() % vec.size()];
615 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
617 freeaddrinfo(res);
618 return true;
620 std::string error = "Error: ";
621 #ifndef __CYGWIN__
622 error += gai_strerror(n);
623 #endif
624 return false;
625 #endif // NO_GETADDRINFO
629 #ifdef ENABLE_IPV6
630 #ifdef IPPROTO_IPV6
631 bool Utility::u2ip(const std::string& host, struct sockaddr_in6& sa, int ai_flags)
633 memset(&sa, 0, sizeof(sa));
634 sa.sin6_family = AF_INET6;
635 #ifdef NO_GETADDRINFO
636 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv6(host))
638 std::list<std::string> vec;
639 size_t x = 0;
640 for (size_t i = 0; i <= host.size(); i++)
642 if (i == host.size() || host[i] == ':')
644 std::string s = host.substr(x, i - x);
646 if (strstr(s.c_str(),".")) // x.x.x.x
648 Parse pa(s,".");
649 char slask[100]; // u2ip temporary hex2string conversion
650 unsigned long b0 = static_cast<unsigned long>(pa.getvalue());
651 unsigned long b1 = static_cast<unsigned long>(pa.getvalue());
652 unsigned long b2 = static_cast<unsigned long>(pa.getvalue());
653 unsigned long b3 = static_cast<unsigned long>(pa.getvalue());
654 sprintf(slask,"%lx",b0 * 256 + b1);
655 vec.push_back(slask);
656 sprintf(slask,"%lx",b2 * 256 + b3);
657 vec.push_back(slask);
659 else
661 vec.push_back(s);
664 x = i + 1;
667 size_t sz = vec.size(); // number of byte pairs
668 size_t i = 0; // index in in6_addr.in6_u.u6_addr16[] ( 0 .. 7 )
669 unsigned short addr16[8];
670 for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++)
672 std::string bytepair = *it;
673 if (bytepair.size())
675 addr16[i++] = htons(Utility::hex2unsigned(bytepair));
677 else
679 addr16[i++] = 0;
680 while (sz++ < 8)
682 addr16[i++] = 0;
686 memcpy(&sa.sin6_addr, addr16, sizeof(addr16));
687 return true;
689 #ifdef SOLARIS
690 int errnum = 0;
691 struct hostent *he = getipnodebyname( host.c_str(), AF_INET6, 0, &errnum );
692 #else
693 struct hostent *he = gethostbyname2( host.c_str(), AF_INET6 );
694 #endif
695 if (!he)
697 return false;
699 memcpy(&sa.sin6_addr,he -> h_addr_list[0],he -> h_length);
700 #ifdef SOLARIS
701 free(he);
702 #endif
703 return true;
704 #else
705 struct addrinfo hints;
706 memset(&hints, 0, sizeof(hints));
707 hints.ai_flags = ai_flags;
708 hints.ai_family = AF_INET6;
709 hints.ai_socktype = 0;
710 hints.ai_protocol = 0;
711 struct addrinfo *res;
712 if (Utility::isipv6(host))
713 hints.ai_flags |= AI_NUMERICHOST;
714 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
715 if (!n)
717 static RandomNumber prng( true );
718 std::vector<struct addrinfo *> vec;
719 struct addrinfo *ai = res;
720 while (ai)
722 if (ai -> ai_addrlen == sizeof(sa))
723 vec.push_back( ai );
724 prng.next();
726 ai = ai -> ai_next;
728 if (!vec.size())
729 return false;
730 ai = vec[prng.next() % vec.size()];
732 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
734 freeaddrinfo(res);
735 return true;
737 std::string error = "Error: ";
738 #ifndef __CYGWIN__
739 error += gai_strerror(n);
740 #endif
741 return false;
742 #endif // NO_GETADDRINFO
744 #endif // IPPROTO_IPV6
745 #endif // ENABLE_IPV6
748 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, int flags)
750 std::string service;
751 return Utility::reverse(sa, sa_len, hostname, service, flags);
755 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags)
757 hostname = "";
758 service = "";
759 #ifdef NO_GETADDRINFO
760 switch (sa -> sa_family)
762 case AF_INET:
763 if (flags & NI_NUMERICHOST)
765 union {
766 struct {
767 unsigned char b1;
768 unsigned char b2;
769 unsigned char b3;
770 unsigned char b4;
771 } a;
772 ipaddr_t l;
773 } u;
774 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
775 memcpy(&u.l, &sa_in -> sin_addr, sizeof(u.l));
776 char tmp[100];
777 sprintf(tmp, "%u.%u.%u.%u", u.a.b1, u.a.b2, u.a.b3, u.a.b4);
778 hostname = tmp;
779 return true;
781 else
783 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
784 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin_addr, sizeof(sa_in -> sin_addr), AF_INET);
785 if (h)
787 hostname = h -> h_name;
788 return true;
791 break;
792 #ifdef ENABLE_IPV6
793 case AF_INET6:
794 if (flags & NI_NUMERICHOST)
796 char slask[100]; // l2ip temporary
797 *slask = 0;
798 unsigned int prev = 0;
799 bool skipped = false;
800 bool ok_to_skip = true;
802 unsigned short addr16[8];
803 struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
804 memcpy(addr16, &sa_in6 -> sin6_addr, sizeof(addr16));
805 for (size_t i = 0; i < 8; i++)
807 unsigned short x = ntohs(addr16[i]);
808 if (*slask && (x || !ok_to_skip || prev))
809 strcat(slask,":");
810 if (x || !ok_to_skip)
812 sprintf(slask + strlen(slask),"%x", x);
813 if (x && skipped)
814 ok_to_skip = false;
816 else
818 skipped = true;
820 prev = x;
823 if (!*slask)
824 strcpy(slask, "::");
825 hostname = slask;
826 return true;
828 else
830 // %! TODO: ipv6 reverse lookup
831 struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)sa;
832 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin6_addr, sizeof(sa_in -> sin6_addr), AF_INET6);
833 if (h)
835 hostname = h -> h_name;
836 return true;
839 break;
840 #endif
842 return false;
843 #else
844 char host[NI_MAXHOST];
845 char serv[NI_MAXSERV];
846 // NI_NOFQDN
847 // NI_NUMERICHOST
848 // NI_NAMEREQD
849 // NI_NUMERICSERV
850 // NI_DGRAM
851 int n = getnameinfo(sa, sa_len, host, sizeof(host), serv, sizeof(serv), flags);
852 if (n)
854 // EAI_AGAIN
855 // EAI_BADFLAGS
856 // EAI_FAIL
857 // EAI_FAMILY
858 // EAI_MEMORY
859 // EAI_NONAME
860 // EAI_OVERFLOW
861 // EAI_SYSTEM
862 return false;
864 hostname = host;
865 service = serv;
866 return true;
867 #endif // NO_GETADDRINFO
871 bool Utility::u2service(const std::string& name, int& service, int ai_flags)
873 #ifdef NO_GETADDRINFO
874 // %!
875 return false;
876 #else
877 struct addrinfo hints;
878 service = 0;
879 memset(&hints, 0, sizeof(hints));
880 // AI_NUMERICHOST
881 // AI_CANONNAME
882 // AI_PASSIVE - server
883 // AI_ADDRCONFIG
884 // AI_V4MAPPED
885 // AI_ALL
886 // AI_NUMERICSERV
887 hints.ai_flags = ai_flags;
888 hints.ai_family = AF_UNSPEC;
889 hints.ai_socktype = 0;
890 hints.ai_protocol = 0;
891 struct addrinfo *res;
892 int n = getaddrinfo(NULL, name.c_str(), &hints, &res);
893 if (!n)
895 service = res -> ai_protocol;
896 freeaddrinfo(res);
897 return true;
899 return false;
900 #endif // NO_GETADDRINFO
904 unsigned long Utility::ThreadID()
906 #ifdef _WIN32
907 return GetCurrentThreadId();
908 #else
909 return (unsigned long)pthread_self();
910 #endif
914 std::string Utility::ToLower(const std::string& str)
916 std::string r;
917 for (size_t i = 0; i < str.size(); i++)
919 if (str[i] >= 'A' && str[i] <= 'Z')
920 r += str[i] | 32;
921 else
922 r += str[i];
924 return r;
928 std::string Utility::ToUpper(const std::string& str)
930 std::string r;
931 for (size_t i = 0; i < str.size(); i++)
933 if (str[i] >= 'a' && str[i] <= 'z')
934 r += (char)(str[i] - 32);
935 else
936 r += str[i];
938 return r;
942 std::string Utility::ToString(double d)
944 char tmp[100];
945 sprintf(tmp, "%f", d);
946 return tmp;
950 #ifdef SOCKETS_NAMESPACE
952 #endif