00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Utility.h"
00033 #include "Parse.h"
00034 #include "Ipv4Address.h"
00035 #include "Ipv6Address.h"
00036 #include "Base64.h"
00037 #include <vector>
00038 #ifdef _WIN32
00039 #include <time.h>
00040 #else
00041 #include <netdb.h>
00042 #include <pthread.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #endif
00046
00047 #ifdef LINUX
00048 #include <cxxabi.h>
00049 #include <execinfo.h>
00050 #include <dlfcn.h>
00051 #endif
00052
00053 #include <map>
00054
00055 #ifdef SOCKETS_NAMESPACE
00056 namespace SOCKETS_NAMESPACE {
00057 #endif
00058
00059
00060
00061 #define TWIST_IA 397
00062 #define TWIST_IB (TWIST_LEN - TWIST_IA)
00063 #define UMASK 0x80000000
00064 #define LMASK 0x7FFFFFFF
00065 #define MATRIX_A 0x9908B0DF
00066 #define TWIST(b,i,j) ((b)[i] & UMASK) | ((b)[j] & LMASK)
00067 #define MAGIC_TWIST(s) (((s) & 1) * MATRIX_A)
00068
00069
00070
00071 std::string Utility::m_host;
00072 bool Utility::m_local_resolved = false;
00073 ipaddr_t Utility::m_ip = 0;
00074 std::string Utility::m_addr;
00075 #ifdef ENABLE_IPV6
00076 #ifdef IPPROTO_IPV6
00077 struct in6_addr Utility::m_local_ip6;
00078 std::string Utility::m_local_addr6;
00079 #endif
00080 #endif
00081 const char *Utility::Logo =
00082 "iVBORw0KGgoAAAANSUhEUgAAAGAAAABeCAIAAABTioayAAAACXBIWXMAAABkAAAAZAAPlsXdAAAAUHRF"
00083 "WHRSYXcgcHJvZmlsZSB0eXBlIEFQUDEyAApnZW5lcmljIHByb2ZpbGUKICAgICAgMTUKNDQ3NTYzNmI3"
00084 "OTAwMDEwMDA0MDAwMDAwM2MwMDAwCg2F1B0AABb4SURBVHja7Xx7rGVXed/3WGs/zvPeuTPXMzbjcUpq"
00085 "HAwlpQlYoUlDaJsAiVuFFKSKGlUlKgXqIKJAKxfRR4IUZEpSt1FoQEK4oYQEErlSFAoKIEoo2BQasBmc"
00086 "2NjyYzxz5957Hnufvfd6fF
00087 "jgA6QI4AOkCOADpAjgA6QI4AOkCOADpAjgA6QI4AOkCOADpAjgA6QI4AOkCOADpAjgA6QMxVHHtfoUWx"
00088 "/dP+C5fvABGv4gwBAK9qPWg5NLbvrjIY302ujgapAmKrQQiqC3xAQQF0H1AIcyXSq4XeZdegfedfWs78"
00089 "jYKAAgDi3sVri4mqzH+D9DSTu+I2dyVNTEFRl34GUTUikiqotrgoAqqIAhBxqzj7ZocAighXWJUuI0Cq"
00090 "injJ+SMAIZKolkXlGrOzM61mjfckCoN+X9UjorU26wgb7HTSPAfDRlVVFQAR21NeOT26XAC1p10CpKoI"
00091 "iKTO+ckkFpO4vVX1Bh3kkKRsDCIBE4sIMRNx8FTPYgwQfJ1k4ZpT3W4nAQBVQaSF/1pcw+VE63JrEKiC"
00092 "KhChC83Fi6EYEyp2uzxYN4kFY6H1O63TIUQAiCIIEgK5Rke7zWhUE2a9AR+/JunmpIr7of/eA2hhWREA"
00093 "QUlBkGg8af7s7E4n75+6Lu/2iBkUAgJLhP2+RkSJsNU5ACUCQCAyxTQ88eS0rt1gSGdOD621Ik8zs8uH"
00094 "0eUCSDSqCDHGUD/2mCvLXpbWp051bEqqGoIAINHeVRHRJTMREQBEACQEUDa0vT07/2QZvbvxphO9vhGh"
00095 "1m0j0uVzSysGaOF6QASJQvD4yKN1UeiZ053eULzX4FsspB221RdVZWYARaTFaeYXjIgiqqpEag16jw9+"
00096 "e3daTH/gBevHjw1EoIXle0ODdJH/KQiCxiiPPOLrWX7taeh1o3ek8wQH26jUao1qa1ZPy6VbgNovtIAi"
00097 "gCoZK17l3GPNdFLf8H2djY1cRAlJUfHyhP+VAbQM6gsPAt/404uzypw509vYoMYhKCHOQxsAiAohaqtL"
00098 "OhdEUlAm8iEQEgAQIRHHGJGQkBSAjILyhXNaN9VzTuOgn6jOl9yXQ49WvJpXEFUhoAcf2t7apn7f5p04"
00099 "K9XVXkVcE4IXiSoRUEkFVYiAEZnZMltmoxFUKAYFJRWQiK4JwUfvoncxBnUNKMTBMUVKzj2OdSNzXC6P"
00100 "ka1mLbZMdkCQSbZ36q3z2Oma4yesAipwEI8iLkTD4GNEBGZGAEJSBUBQ0RAcqLBJBdRYC0gxKKqKqgrE"
00101 "4FUFgNAY7xFAOx0a79KTT4bvu4FVlYAUFRVgpXp0WID2W6gqIMXGyeOPN73ORm8QrcUQRFUUTNNEAIyt"
00102 "CxJ1PmQ2H093vvr1L0rUm5
00103 "MqSj8e60JMPl9ddvSBRiVlBYaURbgQYtXI+qAhKce7JxLuMkGquq3K63GA0YEBFEFAEFNWx8rP7nV75w"
00104 "/sJjhs31z7n54vaWd3Vd10nWFQ1EBACERlERaHc0vrD1eNNEIkMkIURQNMY0Lj7+xGzz5CCxCMqwak/0"
00105 "7H3QUnf2LZR0VoWHHh7PytnO9nnnQ1XVohoVIqioMBMRGEuGbZbar977xe88+tDx9ecURVNUoZgUs6Is"
00106 "at80TfAxBAEFkdi40ASoqqqYTJomqoIoEhkyNs0StlRV9qlzJSGLCuy391XICjRoEbmEGR9/fFo10utC"
00107 "jFrOast2Vk2NtYRoGANCkiRRJDHm22fPfvozf3jL33w1BXvx4v+alOV4NPLONT5KlCyzPsQIEHxwXtTR"
00108 "aLQ7Gu0W5cw5EAVERKC800nyrndxNmucF8OrzxhXFcUQMLjGl1N7zanrTGKStEtkvJcYNAbxPjLbpglV"
00109 "1YjAuacufPx37+72jv3A837iqYtPlbNpPXNFWU3GRftNERGVEGII4l10LpSzejwqyqKqZm46KVUpeA1e"
00110 "isKRZe+SyaSZJ2ErlRVFMVBGGs2aAMYQ9fs9BXFumqdJmiaACCCzqlHwosY7+MQnP/LYYw/f9o/vEORi"
00111 "Ot0d7c6qZjQeVVWTcjYYWCIBTBHBeW1qrWqqinp3tF3WTROVrXGunhTNeBTKWTOMvU7emUz1+IYCoEgk"
00112 "4vnEDq1QzxKgpwcvbZfsFy5MQ+xaE0WAmLrdfpIgoRKRQlTVqm66nfSP/uj3P/PH/+0fvvbtJzb/Su0q"
00113 "1/jJZFqU1WRazGY7H/3ob/R6HcTYRmtCCh6cl0e+862imDnvkUwIDag4J87HPLfBu3FwwetzTiVsCXSV"
00114 "FaNnr0HL4AUAIhEVgzOjUeHzWgHyvEekWZIzY5TIDACwPjz2rW9/84MffN8PvvjlP/wjP1nVZac7dL6a"
00115 "TkvX+GJaFdPxZz/7iRi0hR0ASZkIFCXv9WMjdV0llpUzUGFkaxVJJECSmrKYNnXsJAKSrDBpfMYALW/O"
00116 "Eh1VJcCyno2mNRECYlPXzAwgT20V/W5qEzZs2NhmWrz/vf8u65x4zWtuZ+LhIMsTU1bFZFq4BqbT0ax0"
00117 "r339e05ec7KtRFtjIWhVO+T0Dz555wP/+3M+oAIoAmOa5mLTTGIkgqIsbd6/OCnO9NciRAa+agDtR2oJ"
00118 "kAiEIGTs5uZ6NZv1el0RiTEAQu0ccQYosQl33fUr933ts6dP3/C+975FoicGBNy+cFEizqpqVpZFUW2e"
00119 "uOn0mTMqjoiYGaJOZ42xPR9pMhkVxSwEQJQonsgAKJMR0PX19cY51amE1sL2V74PZW6HctLt8CISI6hQ"
00120 "nnYIaTjsqcJ4PBkOB8SAqDHGTqf7B7939+/8zm+dueH5SL3zF84bY0UFVMqicIJFUZSzWTkbAVVpKgRC"
00121 "BIjqnEuzCNhUs3I2mznvptNadcyUEHOWdkSE2cQYm8apoggorcA3rwagef4sKCJRBNgIBFVjDB8/fgxQ"
00122 "CAEMJIbP3n
00123 "uqpSOwhBogICIGrTVE3tQpQQfZqmo9F0Y70nogrKtLJgf9gwL6KiAKBN02xvT4hNJ82SxBpj806GKDFI"
00124 "1ci7/tVbtnYvvPvffHzj2BnndrMsURCM5D35RqtZ5byv66quK9FgjHZSawzPLYUQALwPABCjDIdZU9fW"
00125 "2DRLvZO6dgpS13WeZ7z4yQqToVVokGqMAgAhhG6WFeV4wIOqruumMgZ63WN3vu9f3PeVz7/lbXfe/MJb"
00126 "Gr+1udlhQiT1XqsZGwoiERRANEQBVQARjcQUQqjrWhQBE5B51EeEPM+tsSKSJmysb1wdY0ySTGIZY0RE"
00127 "YFxuq1w1gFpPqICiEqIqmMEgiYLdXj8EEY1BJOHhf/34f/7QB371lpfd+qpXvzHEyclret2cLRMAlI3v"
00128 "pmnVjGblyLtZiD4ExxiJmE1AVIkBAEV0NqtCmAFAjI0hCKJISMgxQpJam1gFcFUTfIyArFHEECEAtstj"
00129 "OETGeDgTUxBRERWJqpLnSZKse+/KcrZ+bC3GEIKcP7f9s6+7/Wd++o2G0RqXGCOxVrLGMIJToB
00130 "zbUveN6NL/GvelOMs43jJ6whZgYAUcny1MUmRveyv/X31teve+73v3Bra5JkTlW982nWAQUEBERmTVKM"
00131 "Isv8bCVu+hmXXJel1dYxey/eh6ZxVdNs7QZrNpLEMhMxAmhTBwhUeDMa7wxz7PWstY21lCZp0zREtDtG"
00132 "HzuzWspxk3XTTm7zxB8/Dnlm5gOBzup44byrfVo3ShAsl3mPCCnG2FaL8jzzPjDJcDAb9oeJpcRaZiZC"
00133 "xMPuxj4zDbp0N1nb/wQRReRQz8qwneVZr9dLOQHQKN4FCUFOHM97nTSxIU1SQxo8MkdgyDLV2Yyk6fWU"
00134 "2Tvv+r0OmVxViAgBQwQmO1hT2fWMIc0MU56kxrkmhIgISnFnvBMa6XZ0Y70bJBplFQReDaPmUKt5XToi"
00135 "RRFNU5zNJiJxe3tre3u7KIrZrDQGT2z0+13D7NfWkk996g/f855f3tiwSWKtMYNB3uvRqVPZ5qY9ccKc"
00136 "vKY/HOS+abwPTdOUsxJQAcQa3Niwv/4f7rh48dGN4700tb1+59ix9SxNsyzPsk6ScJoRES+LVIvjsLKi"
00137 "ehBgjJLmJkmwqmaIEKOv6zgcDpxzdTUeDrKsY/MMyun2nz14v4+QWOyvZ9NCT5ywk0kwhGxoPK0Iw/qg"
00138 "U85ciLC+1i3ruH7c7OzG8U519ptfrsvbmAFJCEkAu71OFLVJXnG0SSNRwPJyi2QlnKJnpkFPN+aWyoLz"
00139 "aSARcmIBxK2tHcvzPM1s42rF2Ol0vnX/N19766t+6idv/dR
00140 "+MMf/M3f/ujdx453Bv38Xe+648v33hsovPGNb3jlT7z0H/z9n/3zBx6KkhCa7dHk4siNp6WPMai4GIJG"
00141 "wKDqDBgFBMW2ugmEK/HShzAxvfStqnY6eaebpanpdPJer9fr9YbD9aIs3vGOn7/x+T/0mte99fOf+0JZ"
00142 "lI88svvuf/3OW156653v/y+TIv7Ld75z89RzP/yh3woOzn774XvuuefMDX/17W+9vdM99f67fv+vv/jl"
00143 "7/iltzS1AyARcc4XRbmzuzuZTMbjcTWrfFNp8IbpcvAwnrGTXr7uV19cfGoMV43b2dkarh/LbYaIaUbf"
00144 "eejPLfX/2Vt/hTJ8/W1vfujBb9x371cfefTs2Qfvu/9bX5lOii
00145 "H8yXvvCZH/nRV9z1n37ZED7y8NlvfPMBm6RENktTiUmU2B5NMfFVsTHs4JxedVUBgqfxTlodVkREQiRE"
00146 "JNVojbm4s9sd9keTOs+zaRUn4wJIHYhR7vWG1iaN4zw
00147 "PvCKV77uyScKQnvt6RcgZszZbT
00148 "nk8KkJCIkEANwfra4PxT57Z3dra2tqbj0ckzN06K3Y/d/WtPPPrgPb97dzGbfP+NNyMZSjqv+pk31BL/"
00149 "9IGvKcdXvOLnPvHxDzx57tGbnv+jtjvcOHndaLv4O3/39Zsbx
00150 "CsDMuIBowf68Ghr0NHSWirTIxwgBVQyhihiDKupjmfU2b
00151 "Rz5y529/+D3Dwdrtb/+3onLTTT/0kh9+5clrT2+evLZ201/4xbt+49d/6Rfe/HsR4bZ/9M5ud2392HUm"
00152 "SceTqTWapMY19Xh31xhuw8RyDojz97CKKPbMMuk9hgIAqMYoPkgIsWl81YSmcXXtnYshiCiUVd3t9fP+"
00153 "cGen9JK6Wpxz3W7X+4CIAJQwjXYvbhw/Nhx0ETUEr5CIRiZFgBDZC168uGWTZH1tfXd0AQkG/Rx02s3T"
00154 "3e1t72O/lyeGU8M2NVlms4ST1GRpkjCzQaI5P+SqFcwAgWhu98zExMzCDDEqqnbSrKkbonrQ607KWQOB"
00155 "GVRdmggzxhgQ0sFaDzE0bjwcDijgaLzT7XXSxDCR81HqsLm5joiI/sRG3/k6S7GqtWncrCz7vV7CbFqa"
00156 "DBG1eLTri7lSH1p/njVAC2p3a1ZKRERMFJmZSIkQBFTVIJbTadaV4SDLsgBIWZ4TikosyzKx1DQ+SQkB"
00157 "kDyA63Sp3zej8e7aYNhNE05w0aQACJTHFBGYOuPR7nA4yJIENBIxMzK1xwKhuXmtAKFD7WoAzkMYEREJ"
00158 "MzMLMRCRkIAAgaYWm2rqfTUc9m3CXqssyQhtt7NujPU+IAKSVFWVZMYIGAOdLDWGi2ICACFERMzzXCCy"
00159 "yqwoZ0XFDIYYRdkYYiIGNkgEhpEJiYB4CdBhI9khlxoICETErMzIBjkSMxsDqggiURRUEyYf/YXz59Is"
00160 "TfJMYrDWpmnqQ8VMbAwADQd9UW2aRlUUYlFOo8S6rtsklFgIzWh7R6MYTgAEoR2XmdtXNmwMG95nYiuR"
00161 "w0axNlwwozEkEcPcD0GMGgnaOiGAGkKTdmdlHZq65BJIh8Oh840PfmNjw9qWA62EqBrTNEGisiyzPGFI"
00162 "xuPx1JfqAwJYNqCKCIw0d3zMhtttJSbGuYXNHZAeXomeGUBLYmXLgSYijUogimCIhMgyBKMqGiOqIiIH"
00163 "RVBREUTpdVIVqYMGH3cu7HgNaZ5d3NoZrq0577zz62trTV1bm0gUDca5xte7KgKItuV3LsYlanUHmcka"
00164 "NoaMIUJc1IBWoz7PUoP2ZQZKBAJEIkjEzMaiVVElEdMypZhBZP4rEQGANElSRBWJIhrBVc1Ove28Q8RY"
00165 "haIsOnmH0bZfZgbLRkXaaN2GLGY2xliLxpJN2FhmA8xIzEiEuMo1x7MBaLHawAVNGZCQW1IUoFVVAYmg"
00166 "iqpxUVTbIxPh3O7AkgGANLeimpqEEKPIsDdUEcaIBubETpnT69oYBQDMxIaY0RhjDVvDlts8A1ur3zfJ"
00167 "w3qjFVDw2m4mImKGKGqYhUEtAMRFJQQAQaIsd0HaQonu8Z3mbHsCBInYEvD2XRsSIszTHWPYWDaGrGVr"
00168 "rbXGEhkmg0SkiwxoZezdZ5sHPb0w1IZ7JmajAmqVFFnm21OMqAARkVQgxgiw7Kab3+OFz8BFjaldNMBy"
00169 "qbe0LGZmA3PjssYYYoPGEDMiQbtiRpx35V3ltdg+QwNEIAAlMECw10CICIEQiABAJUIUbQmtqm2nwZ6z"
00170 "WNxwwkV/Ai5Aovk6GA2zMcSGbELWmsQYYykxzKZNf9r4vr9n76omirAvnC3nxAjAtOCLIyoQARIgYowa"
00171 "YqQAIiBRFz0sqqD7am+I+5WH2hxiniAbg8aSNdZYtoYSIsNsGKmNa4gAArrSGHZ4H7QPo7YnDIgVgBRV"
00172 "ERNgDG3sjRikLYSKgJCIggrqJYRLFNhvVy0TcZEQGottOmgNW0OGqTUuwqU54cpb7lZCwZt7IiKAFhhS"
00173 "QEbECNrmJoTIJMIUAkdZCqqAzjf3W19Ne9pD86yPGYnJEBlLxpBhYwwZg0xA7TGvbyxnskom8Ep40stZ"
00174 "KQEqoKIAKBChUSRAAgJgJolqWH2MIlFUVEi17VFddnjMzYsIFot0ZAZitMxsyDAaZDZIDLioJQAoos49"
00175 "0F9OEmcr863QFhqNhIotNoREFEVjUCIlQVGKIhpx2ciyNLNFgbJ1K+16AucHATOaeWFjrzxGcwtfrfNZ"
00176 "NUB7ffCgiECttpMitMUPYQJBiCRRMLaaIyAK836fvS2kdqt9bmI8RwqJgQiZieep6Tx3aksul6+xdJUa"
00177 "tLyBrZlw6ywVkQCh7elSZozCoqqCCu0eP+3xefZyn7k/MqhtcjNXJ8KFNQG2vAVcphp7r6u8qMuB/b7e"
00178 "sbYFF1RVZb5vFURk7nsIVEV0uaEluFeraAFibJkuS+Rg8bnuux8rYwNdIYBgX/chwDy2qMCCM4xzy4I2"
00179 "c95rFtzPN1jokS42BeZnJmrLKC0ul8XvXAmAYMlZaiGY3+TWHWP7CIa9msBfmALCHJe9dcjyKRZIl7Sq"
00180 "fI+1hV+CUXu5oHvE8z2a9SJz0Zb7vO/JHrjvKRSLh5vsQ2+Oy+Wb+JUC6LuAden47Wf/HxO9Igb1Xca9"
00181 "ks8PWjjvxXV+F7X4f/12/sUrC9KVfsDSpcPtIbX/sq+aQf1FubpPoPoekKOHvB0gRwAdIEcAHSBHAB0g"
00182 "RwAdIEcAHSBHAB0gRwAdIEcAHSBHAB0gRwAdIP8HqHccFP4Rq4QAAAAASUVORK5CYII=";
00183
00184
00185 std::string Utility::base64(const std::string& str_in)
00186 {
00187 std::string str;
00188 Base64 m_b;
00189 m_b.encode(str_in, str, false);
00190 return str;
00191 }
00192
00193
00194 std::string Utility::base64d(const std::string& str_in)
00195 {
00196 std::string str;
00197 Base64 m_b;
00198 m_b.decode(str_in, str);
00199 return str;
00200 }
00201
00202
00203 std::string Utility::l2string(long l)
00204 {
00205 std::string str;
00206 char tmp[100];
00207 snprintf(tmp,sizeof(tmp),"%ld",l);
00208 str = tmp;
00209 return str;
00210 }
00211
00212
00213 std::string Utility::bigint2string(int64_t l)
00214 {
00215 std::string str;
00216 int64_t tmp = l;
00217 if (l < 0)
00218 {
00219 str = "-";
00220 tmp = -l;
00221 }
00222 while (tmp)
00223 {
00224 uint64_t a = tmp % 10;
00225 str = (char)(a + 48) + str;
00226 tmp /= 10;
00227 }
00228 if (!str.size())
00229 {
00230 str = "0";
00231 }
00232 return str;
00233 }
00234
00235
00236 std::string Utility::bigint2string(uint64_t l)
00237 {
00238 std::string str;
00239 uint64_t tmp = l;
00240 while (tmp)
00241 {
00242 uint64_t a = tmp % 10;
00243 str = (char)(a + 48) + str;
00244 tmp /= 10;
00245 }
00246 if (!str.size())
00247 {
00248 str = "0";
00249 }
00250 return str;
00251 }
00252
00253
00254 uint64_t Utility::atoi64(const std::string& str)
00255 {
00256 uint64_t l = 0;
00257 for (size_t i = 0; i < str.size(); ++i)
00258 {
00259 l = l * 10 + str[i] - 48;
00260 }
00261 return l;
00262 }
00263
00264
00265 unsigned int Utility::hex2unsigned(const std::string& str)
00266 {
00267 unsigned int r = 0;
00268 for (size_t i = 0; i < str.size(); ++i)
00269 {
00270 r = r * 16 + str[i] - 48 - ((str[i] >= 'A') ? 7 : 0) - ((str[i] >= 'a') ? 32 : 0);
00271 }
00272 return r;
00273 }
00274
00275
00276
00277
00278
00279
00280 std::string Utility::rfc1738_encode(const std::string& src)
00281 {
00282 static char hex[] = "0123456789ABCDEF";
00283 std::string dst;
00284 for (size_t i = 0; i < src.size(); ++i)
00285 {
00286 unsigned char c = static_cast<unsigned char>(src[i]);
00287 if (isalnum(c))
00288 {
00289 dst += c;
00290 }
00291 else
00292 if (c == ' ')
00293 {
00294 dst += '+';
00295 }
00296 else
00297 {
00298 dst += '%';
00299 dst += hex[c / 16];
00300 dst += hex[c % 16];
00301 }
00302 }
00303 return dst;
00304 }
00305
00306
00307
00308
00309
00310
00311 std::string Utility::rfc1738_decode(const std::string& src)
00312 {
00313 std::string dst;
00314 for (size_t i = 0; i < src.size(); ++i)
00315 {
00316 if (src[i] == '%' && isxdigit(src[i + 1]) && isxdigit(src[i + 2]))
00317 {
00318 char c1 = src[++i];
00319 char c2 = src[++i];
00320 c1 = c1 - 48 - ((c1 >= 'A') ? 7 : 0) - ((c1 >= 'a') ? 32 : 0);
00321 c2 = c2 - 48 - ((c2 >= 'A') ? 7 : 0) - ((c2 >= 'a') ? 32 : 0);
00322 dst += (char)(c1 * 16 + c2);
00323 }
00324 else
00325 if (src[i] == '+')
00326 {
00327 dst += ' ';
00328 }
00329 else
00330 {
00331 dst += src[i];
00332 }
00333 }
00334 return dst;
00335 }
00336
00337
00338 bool Utility::isipv4(const std::string& str)
00339 {
00340 int dots = 0;
00341
00342 for (size_t i = 0; i < str.size(); ++i)
00343 {
00344 if (str[i] == '.')
00345 dots++;
00346 else
00347 if (!isdigit(str[i]))
00348 return false;
00349 }
00350 if (dots != 3)
00351 return false;
00352 return true;
00353 }
00354
00355
00356 bool Utility::isipv6(const std::string& str)
00357 {
00358 size_t qc = 0;
00359 size_t qd = 0;
00360 for (size_t i = 0; i < str.size(); ++i)
00361 {
00362 qc += (str[i] == ':') ? 1 : 0;
00363 qd += (str[i] == '.') ? 1 : 0;
00364 }
00365 if (qc > 7)
00366 {
00367 return false;
00368 }
00369 if (qd && qd != 3)
00370 {
00371 return false;
00372 }
00373 Parse pa(str,":.");
00374 std::string tmp = pa.getword();
00375 while (tmp.size())
00376 {
00377 if (tmp.size() > 4)
00378 {
00379 return false;
00380 }
00381 for (size_t i = 0; i < tmp.size(); ++i)
00382 {
00383 if (tmp[i] < '0' || (tmp[i] > '9' && tmp[i] < 'A') ||
00384 (tmp[i] > 'F' && tmp[i] < 'a') || tmp[i] > 'f')
00385 {
00386 return false;
00387 }
00388 }
00389
00390 tmp = pa.getword();
00391 }
00392 return true;
00393 }
00394
00395
00396 bool Utility::u2ip(const std::string& str, ipaddr_t& l)
00397 {
00398 struct sockaddr_in sa;
00399 bool r = Utility::u2ip(str, sa);
00400 memcpy(&l, &sa.sin_addr, sizeof(l));
00401 return r;
00402 }
00403
00404
00405 #ifdef ENABLE_IPV6
00406 #ifdef IPPROTO_IPV6
00407 bool Utility::u2ip(const std::string& str, struct in6_addr& l)
00408 {
00409 struct sockaddr_in6 sa;
00410 bool r = Utility::u2ip(str, sa);
00411 l = sa.sin6_addr;
00412 return r;
00413 }
00414 #endif
00415 #endif
00416
00417
00418 void Utility::l2ip(const ipaddr_t ip, std::string& str)
00419 {
00420 struct sockaddr_in sa;
00421 memset(&sa, 0, sizeof(sa));
00422 sa.sin_family = AF_INET;
00423 memcpy(&sa.sin_addr, &ip, sizeof(sa.sin_addr));
00424 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
00425 }
00426
00427
00428 void Utility::l2ip(const in_addr& ip, std::string& str)
00429 {
00430 struct sockaddr_in sa;
00431 memset(&sa, 0, sizeof(sa));
00432 sa.sin_family = AF_INET;
00433 sa.sin_addr = ip;
00434 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
00435 }
00436
00437
00438 #ifdef ENABLE_IPV6
00439 #ifdef IPPROTO_IPV6
00440 void Utility::l2ip(const struct in6_addr& ip, std::string& str,bool mixed)
00441 {
00442 char slask[100];
00443 *slask = 0;
00444 unsigned int prev = 0;
00445 bool skipped = false;
00446 bool ok_to_skip = true;
00447 if (mixed)
00448 {
00449 unsigned short x;
00450 unsigned short addr16[8];
00451 memcpy(addr16, &ip, sizeof(addr16));
00452 for (size_t i = 0; i < 6; ++i)
00453 {
00454 x = ntohs(addr16[i]);
00455 if (*slask && (x || !ok_to_skip || prev))
00456 {
00457 #if defined( _WIN32) && !defined(__CYGWIN__)
00458 strcat_s(slask,sizeof(slask),":");
00459 #else
00460 strcat(slask,":");
00461 #endif
00462 }
00463 if (x || !ok_to_skip)
00464 {
00465 snprintf(slask + strlen(slask),sizeof(slask) - strlen(slask),"%x", x);
00466 if (x && skipped)
00467 ok_to_skip = false;
00468 }
00469 else
00470 {
00471 skipped = true;
00472 }
00473 prev = x;
00474 }
00475 x = ntohs(addr16[6]);
00476 snprintf(slask + strlen(slask),sizeof(slask) - strlen(slask),":%u.%u",x / 256,x & 255);
00477 x = ntohs(addr16[7]);
00478 snprintf(slask + strlen(slask),sizeof(slask) - strlen(slask),".%u.%u",x / 256,x & 255);
00479 }
00480 else
00481 {
00482 struct sockaddr_in6 sa;
00483 memset(&sa, 0, sizeof(sa));
00484 sa.sin6_family = AF_INET6;
00485 sa.sin6_addr = ip;
00486 Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST);
00487 return;
00488 }
00489 str = slask;
00490 }
00491
00492
00493 int Utility::in6_addr_compare(in6_addr a,in6_addr b)
00494 {
00495 for (size_t i = 0; i < 16; ++i)
00496 {
00497 if (a.s6_addr[i] < b.s6_addr[i])
00498 return -1;
00499 if (a.s6_addr[i] > b.s6_addr[i])
00500 return 1;
00501 }
00502 return 0;
00503 }
00504 #endif
00505 #endif
00506
00507
00508 void Utility::ResolveLocal()
00509 {
00510 char h[256];
00511
00512
00513 *h = 0;
00514 gethostname(h,255);
00515 {
00516 if (Utility::u2ip(h, m_ip))
00517 {
00518 Utility::l2ip(m_ip, m_addr);
00519 }
00520 }
00521 #ifdef ENABLE_IPV6
00522 #ifdef IPPROTO_IPV6
00523 memset(&m_local_ip6, 0, sizeof(m_local_ip6));
00524 {
00525 if (Utility::u2ip(h, m_local_ip6))
00526 {
00527 Utility::l2ip(m_local_ip6, m_local_addr6);
00528 }
00529 }
00530 #endif
00531 #endif
00532 m_host = h;
00533 m_local_resolved = true;
00534 }
00535
00536
00537 const std::string& Utility::GetLocalHostname()
00538 {
00539 if (!m_local_resolved)
00540 {
00541 ResolveLocal();
00542 }
00543 return m_host;
00544 }
00545
00546
00547 ipaddr_t Utility::GetLocalIP()
00548 {
00549 if (!m_local_resolved)
00550 {
00551 ResolveLocal();
00552 }
00553 return m_ip;
00554 }
00555
00556
00557 const std::string& Utility::GetLocalAddress()
00558 {
00559 if (!m_local_resolved)
00560 {
00561 ResolveLocal();
00562 }
00563 return m_addr;
00564 }
00565
00566
00567 #ifdef ENABLE_IPV6
00568 #ifdef IPPROTO_IPV6
00569 const struct in6_addr& Utility::GetLocalIP6()
00570 {
00571 if (!m_local_resolved)
00572 {
00573 ResolveLocal();
00574 }
00575 return m_local_ip6;
00576 }
00577
00578
00579 const std::string& Utility::GetLocalAddress6()
00580 {
00581 if (!m_local_resolved)
00582 {
00583 ResolveLocal();
00584 }
00585 return m_local_addr6;
00586 }
00587 #endif
00588 #endif
00589
00590
00591 const std::string Utility::GetEnv(const std::string& name)
00592 {
00593 #if defined( _WIN32) && !defined(__CYGWIN__)
00594 size_t sz = 0;
00595 char tmp[2048];
00596 if (getenv_s(&sz, tmp, sizeof(tmp), name.c_str()))
00597 {
00598 *tmp = 0;
00599 }
00600 return tmp;
00601 #else
00602 char *s = getenv(name.c_str());
00603 if (!s)
00604 return "";
00605 return s;
00606 #endif
00607 }
00608
00609
00610 void Utility::SetEnv(const std::string& var,const std::string& value)
00611 {
00612 #if (defined(SOLARIS8) || defined(SOLARIS))
00613 {
00614 static std::map<std::string, char *> vmap;
00615 if (vmap.find(var) != vmap.end())
00616 {
00617 delete[] vmap[var];
00618 }
00619 size_t sz = var.size() + 1 + value.size() + 1;
00620 vmap[var] = new char[sz];
00621 snprintf(vmap[var], sz, "%s=%s", var.c_str(), value.c_str());
00622 putenv( vmap[var] );
00623 }
00624 #elif defined _WIN32
00625 {
00626 std::string slask = var + "=" + value;
00627 _putenv( (char *)slask.c_str());
00628 }
00629 #else
00630 setenv(var.c_str(), value.c_str(), 1);
00631 #endif
00632 }
00633
00634
00635 std::string Utility::Sa2String(struct sockaddr *sa)
00636 {
00637 #ifdef ENABLE_IPV6
00638 #ifdef IPPROTO_IPV6
00639 if (sa -> sa_family == AF_INET6)
00640 {
00641 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
00642 std::string tmp;
00643 Utility::l2ip(sa6 -> sin6_addr, tmp);
00644 return tmp + ":" + Utility::l2string(ntohs(sa6 -> sin6_port));
00645 }
00646 #endif
00647 #endif
00648 if (sa -> sa_family == AF_INET)
00649 {
00650 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
00651 ipaddr_t a;
00652 memcpy(&a, &sa4 -> sin_addr, 4);
00653 std::string tmp;
00654 Utility::l2ip(a, tmp);
00655 return tmp + ":" + Utility::l2string(ntohs(sa4 -> sin_port));
00656 }
00657 return "";
00658 }
00659
00660
00661 void Utility::GetTime(struct timeval *p)
00662 {
00663 #ifdef _WIN32
00664 FILETIME ft;
00665 GetSystemTimeAsFileTime(&ft);
00666 uint64_t tt;
00667 memcpy(&tt, &ft, sizeof(tt));
00668 tt /= 10;
00669 p->tv_sec = (long)tt / 1000000;
00670 p->tv_usec = (long)tt % 1000000;
00671 #else
00672 gettimeofday(p, NULL);
00673 #endif
00674 }
00675
00676
00677 std::auto_ptr<SocketAddress> Utility::CreateAddress(struct sockaddr *sa,socklen_t sa_len)
00678 {
00679 switch (sa -> sa_family)
00680 {
00681 case AF_INET:
00682 if (sa_len == sizeof(struct sockaddr_in))
00683 {
00684 struct sockaddr_in *p = (struct sockaddr_in *)sa;
00685 return std::auto_ptr<SocketAddress>(new Ipv4Address(*p));
00686 }
00687 break;
00688 #ifdef ENABLE_IPV6
00689 #ifdef IPPROTO_IPV6
00690 case AF_INET6:
00691 if (sa_len == sizeof(struct sockaddr_in6))
00692 {
00693 struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
00694 return std::auto_ptr<SocketAddress>(new Ipv6Address(*p));
00695 }
00696 break;
00697 #endif
00698 #endif
00699 }
00700 return std::auto_ptr<SocketAddress>(NULL);
00701 }
00702
00703
00704 bool Utility::u2ip(const std::string& host, struct sockaddr_in& sa, int ai_flags)
00705 {
00706 memset(&sa, 0, sizeof(sa));
00707 sa.sin_family = AF_INET;
00708 #ifdef NO_GETADDRINFO
00709 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv4(host))
00710 {
00711 Parse pa((char *)host.c_str(), ".");
00712 union {
00713 struct {
00714 unsigned char b1;
00715 unsigned char b2;
00716 unsigned char b3;
00717 unsigned char b4;
00718 } a;
00719 ipaddr_t l;
00720 } u;
00721 u.a.b1 = static_cast<unsigned char>(pa.getvalue());
00722 u.a.b2 = static_cast<unsigned char>(pa.getvalue());
00723 u.a.b3 = static_cast<unsigned char>(pa.getvalue());
00724 u.a.b4 = static_cast<unsigned char>(pa.getvalue());
00725 memcpy(&sa.sin_addr, &u.l, sizeof(sa.sin_addr));
00726 return true;
00727 }
00728 #ifndef LINUX
00729 struct hostent *he = gethostbyname( host.c_str() );
00730 if (!he)
00731 {
00732 return false;
00733 }
00734 memcpy(&sa.sin_addr, he -> h_addr, sizeof(sa.sin_addr));
00735 #else
00736 struct hostent he;
00737 struct hostent *result = NULL;
00738 int myerrno = 0;
00739 char buf[2000];
00740 int n = gethostbyname_r(host.c_str(), &he, buf, sizeof(buf), &result, &myerrno);
00741 if (n || !result)
00742 {
00743 return false;
00744 }
00745 if (he.h_addr_list && he.h_addr_list[0])
00746 memcpy(&sa.sin_addr, he.h_addr, 4);
00747 else
00748 return false;
00749 #endif
00750 return true;
00751 #else
00752 struct addrinfo hints;
00753 memset(&hints, 0, sizeof(hints));
00754
00755
00756
00757
00758
00759
00760
00761 hints.ai_flags = ai_flags;
00762 hints.ai_family = AF_INET;
00763 hints.ai_socktype = 0;
00764 hints.ai_protocol = 0;
00765 struct addrinfo *res;
00766 if (Utility::isipv4(host))
00767 hints.ai_flags |= AI_NUMERICHOST;
00768 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
00769 if (!n)
00770 {
00771 std::vector<struct addrinfo *> vec;
00772 struct addrinfo *ai = res;
00773 while (ai)
00774 {
00775 if (ai -> ai_addrlen == sizeof(sa))
00776 vec.push_back( ai );
00777 ai = ai -> ai_next;
00778 }
00779 if (!vec.size())
00780 return false;
00781 ai = vec[Utility::Rnd() % vec.size()];
00782 {
00783 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
00784 }
00785 freeaddrinfo(res);
00786 return true;
00787 }
00788 std::string error = "Error: ";
00789 #ifndef __CYGWIN__
00790 error += gai_strerror(n);
00791 #endif
00792 return false;
00793 #endif // NO_GETADDRINFO
00794 }
00795
00796
00797 #ifdef ENABLE_IPV6
00798 #ifdef IPPROTO_IPV6
00799 bool Utility::u2ip(const std::string& host, struct sockaddr_in6& sa, int ai_flags)
00800 {
00801 memset(&sa, 0, sizeof(sa));
00802 sa.sin6_family = AF_INET6;
00803 #ifdef NO_GETADDRINFO
00804 if ((ai_flags & AI_NUMERICHOST) != 0 || isipv6(host))
00805 {
00806 std::list<std::string> vec;
00807 size_t x = 0;
00808 for (size_t i = 0; i <= host.size(); ++i)
00809 {
00810 if (i == host.size() || host[i] == ':')
00811 {
00812 std::string s = host.substr(x, i - x);
00813
00814 if (strstr(s.c_str(),"."))
00815 {
00816 Parse pa(s,".");
00817 char slask[100];
00818 unsigned long b0 = static_cast<unsigned long>(pa.getvalue());
00819 unsigned long b1 = static_cast<unsigned long>(pa.getvalue());
00820 unsigned long b2 = static_cast<unsigned long>(pa.getvalue());
00821 unsigned long b3 = static_cast<unsigned long>(pa.getvalue());
00822 snprintf(slask,sizeof(slask),"%lx",b0 * 256 + b1);
00823 vec.push_back(slask);
00824 snprintf(slask,sizeof(slask),"%lx",b2 * 256 + b3);
00825 vec.push_back(slask);
00826 }
00827 else
00828 {
00829 vec.push_back(s);
00830 }
00831
00832 x = i + 1;
00833 }
00834 }
00835 size_t sz = vec.size();
00836 size_t i = 0;
00837 unsigned short addr16[8];
00838 for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
00839 {
00840 std::string bytepair = *it;
00841 if (bytepair.size())
00842 {
00843 addr16[i++] = htons(Utility::hex2unsigned(bytepair));
00844 }
00845 else
00846 {
00847 addr16[i++] = 0;
00848 while (sz++ < 8)
00849 {
00850 addr16[i++] = 0;
00851 }
00852 }
00853 }
00854 memcpy(&sa.sin6_addr, addr16, sizeof(addr16));
00855 return true;
00856 }
00857 #ifdef SOLARIS
00858 int errnum = 0;
00859 struct hostent *he = getipnodebyname( host.c_str(), AF_INET6, 0, &errnum );
00860 #else
00861 struct hostent *he = gethostbyname2( host.c_str(), AF_INET6 );
00862 #endif
00863 if (!he)
00864 {
00865 return false;
00866 }
00867 memcpy(&sa.sin6_addr,he -> h_addr_list[0],he -> h_length);
00868 #ifdef SOLARIS
00869 free(he);
00870 #endif
00871 return true;
00872 #else
00873 struct addrinfo hints;
00874 memset(&hints, 0, sizeof(hints));
00875 hints.ai_flags = ai_flags;
00876 hints.ai_family = AF_INET6;
00877 hints.ai_socktype = 0;
00878 hints.ai_protocol = 0;
00879 struct addrinfo *res;
00880 if (Utility::isipv6(host))
00881 hints.ai_flags |= AI_NUMERICHOST;
00882 int n = getaddrinfo(host.c_str(), NULL, &hints, &res);
00883 if (!n)
00884 {
00885 std::vector<struct addrinfo *> vec;
00886 struct addrinfo *ai = res;
00887 while (ai)
00888 {
00889 if (ai -> ai_addrlen == sizeof(sa))
00890 vec.push_back( ai );
00891 ai = ai -> ai_next;
00892 }
00893 if (!vec.size())
00894 return false;
00895 ai = vec[Utility::Rnd() % vec.size()];
00896 {
00897 memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen);
00898 }
00899 freeaddrinfo(res);
00900 return true;
00901 }
00902 std::string error = "Error: ";
00903 #ifndef __CYGWIN__
00904 error += gai_strerror(n);
00905 #endif
00906 return false;
00907 #endif // NO_GETADDRINFO
00908 }
00909 #endif // IPPROTO_IPV6
00910 #endif // ENABLE_IPV6
00911
00912
00913 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, int flags)
00914 {
00915 std::string service;
00916 return Utility::reverse(sa, sa_len, hostname, service, flags);
00917 }
00918
00919
00920 bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags)
00921 {
00922 hostname = "";
00923 service = "";
00924 #ifdef NO_GETADDRINFO
00925 switch (sa -> sa_family)
00926 {
00927 case AF_INET:
00928 if (flags & NI_NUMERICHOST)
00929 {
00930 union {
00931 struct {
00932 unsigned char b1;
00933 unsigned char b2;
00934 unsigned char b3;
00935 unsigned char b4;
00936 } a;
00937 ipaddr_t l;
00938 } u;
00939 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
00940 memcpy(&u.l, &sa_in -> sin_addr, sizeof(u.l));
00941 char tmp[100];
00942 snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u", u.a.b1, u.a.b2, u.a.b3, u.a.b4);
00943 hostname = tmp;
00944 return true;
00945 }
00946 else
00947 {
00948 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
00949 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin_addr, sizeof(sa_in -> sin_addr), AF_INET);
00950 if (h)
00951 {
00952 hostname = h -> h_name;
00953 return true;
00954 }
00955 }
00956 break;
00957 #ifdef ENABLE_IPV6
00958 case AF_INET6:
00959 if (flags & NI_NUMERICHOST)
00960 {
00961 char slask[100];
00962 *slask = 0;
00963 unsigned int prev = 0;
00964 bool skipped = false;
00965 bool ok_to_skip = true;
00966 {
00967 unsigned short addr16[8];
00968 struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
00969 memcpy(addr16, &sa_in6 -> sin6_addr, sizeof(addr16));
00970 for (size_t i = 0; i < 8; ++i)
00971 {
00972 unsigned short x = ntohs(addr16[i]);
00973 if (*slask && (x || !ok_to_skip || prev))
00974 {
00975 #if defined( _WIN32) && !defined(__CYGWIN__)
00976 strcat_s(slask, sizeof(slask),":");
00977 #else
00978 strcat(slask,":");
00979 #endif
00980 }
00981 if (x || !ok_to_skip)
00982 {
00983 snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),"%x", x);
00984 if (x && skipped)
00985 ok_to_skip = false;
00986 }
00987 else
00988 {
00989 skipped = true;
00990 }
00991 prev = x;
00992 }
00993 }
00994 if (!*slask)
00995 {
00996 #if defined( _WIN32) && !defined(__CYGWIN__)
00997 strcpy_s(slask, sizeof(slask), "::");
00998 #else
00999 strcpy(slask, "::");
01000 #endif
01001 }
01002 hostname = slask;
01003 return true;
01004 }
01005 else
01006 {
01007
01008 struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)sa;
01009 struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin6_addr, sizeof(sa_in -> sin6_addr), AF_INET6);
01010 if (h)
01011 {
01012 hostname = h -> h_name;
01013 return true;
01014 }
01015 }
01016 break;
01017 #endif
01018 }
01019 return false;
01020 #else
01021 char host[NI_MAXHOST];
01022
01023
01024
01025
01026
01027 int n = getnameinfo(sa, sa_len, host, sizeof(host), NULL, 0, flags);
01028 if (n)
01029 {
01030
01031
01032
01033
01034
01035
01036
01037
01038 return false;
01039 }
01040 hostname = host;
01041 return true;
01042 #endif // NO_GETADDRINFO
01043 }
01044
01045
01046 bool Utility::u2service(const std::string& name, int& service, int ai_flags)
01047 {
01048 #ifdef NO_GETADDRINFO
01049
01050 return false;
01051 #else
01052 struct addrinfo hints;
01053 service = 0;
01054 memset(&hints, 0, sizeof(hints));
01055
01056
01057
01058
01059
01060
01061
01062 hints.ai_flags = ai_flags;
01063 hints.ai_family = AF_UNSPEC;
01064 hints.ai_socktype = 0;
01065 hints.ai_protocol = 0;
01066 struct addrinfo *res;
01067 int n = getaddrinfo(NULL, name.c_str(), &hints, &res);
01068 if (!n)
01069 {
01070 service = res -> ai_protocol;
01071 freeaddrinfo(res);
01072 return true;
01073 }
01074 return false;
01075 #endif // NO_GETADDRINFO
01076 }
01077
01078
01079 unsigned long Utility::ThreadID()
01080 {
01081 #ifdef _WIN32
01082 return GetCurrentThreadId();
01083 #else
01084 return (unsigned long)pthread_self();
01085 #endif
01086 }
01087
01088
01089 std::string Utility::ToLower(const std::string& str)
01090 {
01091 std::string r;
01092 for (size_t i = 0; i < str.size(); ++i)
01093 {
01094 if (str[i] >= 'A' && str[i] <= 'Z')
01095 r += str[i] | 32;
01096 else
01097 r += str[i];
01098 }
01099 return r;
01100 }
01101
01102
01103 std::string Utility::ToUpper(const std::string& str)
01104 {
01105 std::string r;
01106 for (size_t i = 0; i < str.size(); ++i)
01107 {
01108 if (str[i] >= 'a' && str[i] <= 'z')
01109 r += (char)(str[i] - 32);
01110 else
01111 r += str[i];
01112 }
01113 return r;
01114 }
01115
01116
01117 std::string Utility::ToString(double d)
01118 {
01119 char tmp[100];
01120 snprintf(tmp, sizeof(tmp), "%f", d);
01121 return tmp;
01122 }
01123
01124
01125 unsigned long Utility::Rnd()
01126 {
01127 static Utility::Rng generator( (unsigned long)time(NULL) );
01128 return generator.Get();
01129 }
01130
01131
01132 Utility::Rng::Rng(unsigned long seed) : m_value( 0 )
01133 {
01134 m_tmp[0] = seed & 0xffffffffUL;
01135 for (int i = 1; i < TWIST_LEN; ++i)
01136 {
01137 m_tmp[i] = (1812433253UL * (m_tmp[i - 1] ^ (m_tmp[i - 1] >> 30)) + i);
01138 }
01139 }
01140
01141
01142 unsigned long Utility::Rng::Get()
01143 {
01144 unsigned long val = m_tmp[m_value];
01145 ++m_value;
01146 if (m_value == TWIST_LEN)
01147 {
01148 for (int i = 0; i < TWIST_IB; ++i)
01149 {
01150 unsigned long s = TWIST(m_tmp, i, i + 1);
01151 m_tmp[i] = m_tmp[i + TWIST_IA] ^ (s >> 1) ^ MAGIC_TWIST(s);
01152 }
01153 {
01154 for (int i = 0; i < TWIST_LEN - 1; ++i)
01155 {
01156 unsigned long s = TWIST(m_tmp, i, i + 1);
01157 m_tmp[i] = m_tmp[i - TWIST_IB] ^ (s >> 1) ^ MAGIC_TWIST(s);
01158 }
01159 }
01160 unsigned long s = TWIST(m_tmp, TWIST_LEN - 1, 0);
01161 m_tmp[TWIST_LEN - 1] = m_tmp[TWIST_IA - 1] ^ (s >> 1) ^ MAGIC_TWIST(s);
01162
01163 m_value = 0;
01164 }
01165 return val;
01166 }
01167
01168
01169 bool Utility::ncmap_compare::operator()(const std::string& x, const std::string& y) const
01170 {
01171 return strcasecmp(x.c_str(), y.c_str()) < 0;
01172 }
01173
01174
01175 Utility::Uri::Uri(const std::string& url) : m_url(url), m_port(0), m_path(url)
01176 {
01177 size_t pos = url.find("://");
01178 if (pos != std::string::npos)
01179 {
01180 m_protocol = Utility::ToLower(url.substr(0, pos));
01181 m_port = (m_protocol == "http") ? 80 :
01182 (m_protocol == "https") ? 443 : 0;
01183 m_host = url.substr(pos + 3);
01184 pos = m_host.find("/");
01185 if (pos != std::string::npos)
01186 {
01187 m_path = m_host.substr(pos);
01188 m_host = m_host.substr(0, pos);
01189 }
01190 pos = m_host.find("@");
01191 if (pos != std::string::npos)
01192 {
01193 m_user = m_host.substr(0, pos);
01194 m_host = m_host.substr(pos + 1);
01195 }
01196 pos = m_user.find(":");
01197 if (pos != std::string::npos)
01198 {
01199 m_auth = m_user.substr(pos + 1);
01200 m_user = m_user.substr(0, pos);
01201 }
01202 pos = m_host.find(":");
01203 if (pos != std::string::npos)
01204 {
01205 m_port = atoi(m_host.substr(pos + 1).c_str());
01206 m_host = m_host.substr(0, pos);
01207 }
01208 }
01209 pos = m_path.find("?");
01210 if (pos != std::string::npos)
01211 {
01212 m_uri = m_path.substr(0, pos);
01213 m_query_string = m_path.substr(pos + 1);
01214 }
01215 else
01216 {
01217 m_uri = m_path;
01218 }
01219 pos = std::string::npos;
01220 for (size_t i = 0; i < m_uri.size(); ++i)
01221 if (m_uri[i] == '/')
01222 pos = i;
01223 if (pos != std::string::npos)
01224 m_file = m_uri.substr(pos + 1);
01225 pos = std::string::npos;
01226 for (size_t i = 0; i < m_uri.size(); ++i)
01227 if (m_uri[i] == '.')
01228 pos = i;
01229 if (pos != std::string::npos)
01230 m_ext = m_uri.substr(pos + 1);
01231 }
01232
01233
01234 Utility::Path::Path(const std::string& _str)
01235 {
01236 std::string str = _str;
01237 for (size_t i = 0; i < str.size(); ++i)
01238 {
01239 #ifdef _WIN32
01240 if (str[i] == '/')
01241 str[i] = '\\';
01242 #else
01243 if (str[i] == '\\')
01244 str[i] = '/';
01245 #endif
01246 }
01247 #ifndef _WIN32
01248 struct stat st;
01249 stat(str.c_str(), &st);
01250 if (S_ISDIR(st.st_mode))
01251 {
01252 m_path = str;
01253 return;
01254 }
01255 #endif
01256 size_t x = 0;
01257 for (size_t i = 0; i < str.size(); ++i)
01258 if (str[i] == '/' || str[i] == '\\')
01259 x = i + 1;
01260 m_path = str.substr(0, x);
01261 m_file = str.substr(x);
01262 for (size_t i = 0; i < m_file.size(); ++i)
01263 if (m_file[i] == '.')
01264 m_ext = m_file.substr(i + 1);
01265 }
01266
01267
01268 const std::string Utility::Stack()
01269 {
01270 #if defined LINUX
01271 #define BFSIZE 255
01272 void *buffer[BFSIZE];
01273 int n = backtrace(buffer, BFSIZE);
01274 char **res = backtrace_symbols(buffer, n);
01275 std::string tmp;
01276 for (int i = 0; i < n; ++i)
01277 {
01278 std::string x = res[i];
01279 std::string plus;
01280 std::string addr;
01281 size_t pos = x.find("(");
01282 if (pos != std::string::npos)
01283 {
01284 x = x.substr(pos + 1);
01285
01286 pos = x.find(")");
01287 if (pos != std::string::npos)
01288 {
01289 addr = x.substr(pos + 1);
01290 x = x.substr(0, pos);
01291 }
01292
01293 pos = x.find("+");
01294 if (pos != std::string::npos)
01295 {
01296 plus = x.substr(pos);
01297 x = x.substr(0, pos);
01298 }
01299 }
01300 char zz[1000];
01301 {
01302 size_t sz = 1000;
01303 int status = 0;
01304 abi::__cxa_demangle( x.c_str(), zz, &sz, &status);
01305
01306 if (!status)
01307 {
01308 tmp += zz;
01309 tmp += plus;
01310 tmp += addr;
01311 }
01312 else
01313 {
01314 tmp += res[i];
01315 }
01316 tmp += "\n";
01317 }
01318
01319 if (0)
01320 {
01321 Dl_info info;
01322 int n = dladdr(buffer[i], &info);
01323 if (!n)
01324 printf("%d: dladdr() failed\n", i);
01325 else
01326 {
01327 size_t sz = 1000;
01328 int status = 0;
01329 abi::__cxa_demangle( info.dli_sname, zz, &sz, &status);
01330
01331 printf("%d: %s: %s\n", i, info.dli_fname, info.dli_sname);
01332 if (!status)
01333 printf(" %s\n", zz);
01334 }
01335 }
01336 }
01337 free(res);
01338 return tmp;
01339 #else
01340 return "Not available";
01341 #endif
01342 }
01343
01344
01345 const std::string Utility::FromUtf8(const std::string& str)
01346 {
01347 if (!str.size())
01348 return "";
01349 std::string r;
01350 for (size_t i = 0; i < str.size(); ++i)
01351 {
01352 if (i < str.size() - 1 && (str[i] & 0xe0) == 0xc0 && (str[i + 1] & 0xc0) == 0x80)
01353 {
01354 int c1 = str[i] & 0x1f;
01355 int c2 = str[++i] & 0x3f;
01356 int c = (c1 << 6) + c2;
01357 r += (char)c;
01358 }
01359 else
01360 {
01361 r += str[i];
01362 }
01363 }
01364 return r;
01365 }
01366
01367
01368
01369 const std::string Utility::ToUtf8(const std::string& str)
01370 {
01371 if (str.empty())
01372 return "";
01373 std::string r;
01374 for (size_t i = 0; i < str.size(); ++i)
01375 {
01376 if (((unsigned)str[i] & 0x80) == 0x80)
01377 {
01378 r += (str[i] >> 6) | 0xc0;
01379 r += (str[i] & 0x3f) | 0x80;
01380 }
01381 else
01382 {
01383 r += str[i];
01384 }
01385 }
01386 return r;
01387 }
01388
01389
01390 const Utility::Path Utility::CurrentDirectory()
01391 {
01392 #ifdef _WIN32
01393 TCHAR slask[MAX_PATH + 1];
01394 DWORD ret =
01395 #ifdef UNICODE
01396 ::GetCurrentDirectoryW(MAX_PATH, slask);
01397 #else
01398 ::GetCurrentDirectoryA(MAX_PATH, slask);
01399 #endif
01400 if (!ret)
01401 {
01402 *slask = 0;
01403 DWORD err = GetLastError();
01404 }
01405 return Path(slask);
01406 #else
01407 char slask[32000];
01408 if (!getcwd(slask, 32000))
01409 {
01410 return Path(".");
01411 }
01412 return Path(slask);
01413 #endif
01414 }
01415
01416
01417 bool Utility::ChangeDirectory(const Utility::Path& to_dir)
01418 {
01419 #ifdef _WIN32
01420 return SetCurrentDirectory(to_dir.GetPath().c_str()) ? true : false;
01421 #else
01422 if (chdir( to_dir.GetPath().c_str() ) == -1)
01423 {
01424 return false;
01425 }
01426 return true;
01427 #endif
01428 }
01429
01430
01431 void Utility::Sleep(int ms)
01432 {
01433 #ifdef _WIN32
01434 ::Sleep(ms);
01435 #else
01436 struct timeval tv;
01437 tv.tv_sec = ms / 1000;
01438 tv.tv_usec = (ms % 1000) * 1000;
01439 select(0, NULL, NULL, NULL, &tv);
01440 #endif
01441 }
01442
01443
01444 #ifdef SOCKETS_NAMESPACE
01445 }
01446 #endif
01447