root/trunk/src/shared/Util.cpp @ 102

Revision 102, 11.8 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

Original author: w12x
Date: 2008-10-23 03:29:52-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Util.h"
22
23#include "sockets/socket_include.h"
24#include "utf8cpp/utf8.h"
25#include "mersennetwister/MersenneTwister.h"
26#include "zthread/ThreadLocal.h"
27
28typedef ZThread::ThreadLocal<MTRand> MTRandTSS;
29
30/* NOTE: Not sure if static initialization is ok for TSS objects ,
31 * as I see zthread uses custom implementation of the TSS
32 * ,and in the consturctor there is no code ,so I suppose its ok
33 * If its not ok ,change it to use singleton.
34 */
35static MTRandTSS mtRand;
36
37int32 irand (int32 min, int32 max)
38{
39  return int32 (mtRand.get ().randInt (max - min)) + min;
40}
41
42uint32 urand (uint32 min, uint32 max)
43{
44  return mtRand.get ().randInt (max - min) + min;
45}
46
47int32 rand32 ()
48{
49  return mtRand.get ().randInt ();
50}
51
52double rand_norm(void)
53{
54  return mtRand.get ().randExc ();
55}
56
57double rand_chance (void)
58{
59  return mtRand.get ().randExc (100.0);
60}
61
62Tokens StrSplit(const std::string &src, const std::string &sep)
63{
64    Tokens r;
65    std::string s;
66    for (std::string::const_iterator i = src.begin(); i != src.end(); i++)
67    {
68        if (sep.find(*i) != std::string::npos)
69        {
70            if (s.length()) r.push_back(s);
71            s = "";
72        }
73        else
74        {
75            s += *i;
76        }
77    }
78    if (s.length()) r.push_back(s);
79    return r;
80}
81
82void stripLineInvisibleChars(std::string &str)
83{
84    static std::string invChars = " \t\7";
85
86    size_t wpos = 0;
87
88    bool space = false;
89    for(size_t pos = 0; pos < str.size(); ++pos)
90    {
91        if(invChars.find(str[pos])!=std::string::npos)
92        {
93            if(!space)
94            {
95                str[wpos++] = ' ';
96                space = true;
97            }
98        }
99        else
100        {
101            if(wpos!=pos)
102                str[wpos++] = str[pos];
103            else
104                ++wpos;
105            space = false;
106        }
107    }
108
109    if(wpos < str.size())
110        str.erase(wpos,str.size());
111}
112
113std::string secsToTimeString(uint32 timeInSecs, bool shortText, bool hoursOnly)
114{
115    uint32 secs    = timeInSecs % MINUTE;
116    uint32 minutes = timeInSecs % HOUR / MINUTE;
117    uint32 hours   = timeInSecs % DAY  / HOUR;
118    uint32 days    = timeInSecs / DAY;
119
120    std::ostringstream ss;
121    if(days)
122        ss << days << (shortText ? "d" : " Day(s) ");
123    if(hours || hoursOnly)
124        ss << hours << (shortText ? "h" : " Hour(s) ");
125    if(!hoursOnly)
126    {
127        if(minutes)
128            ss << minutes << (shortText ? "m" : " Minute(s) ");
129        if(secs || (!days && !hours && !minutes) )
130            ss << secs << (shortText ? "s" : " Second(s).");
131    }
132
133    return ss.str();
134}
135
136uint32 TimeStringToSecs(std::string timestring)
137{
138    uint32 secs       = 0;
139    uint32 buffer     = 0;
140    uint32 multiplier = 0;
141
142    for(std::string::iterator itr = timestring.begin(); itr != timestring.end(); itr++ )
143    {
144        if(isdigit(*itr))
145        {
146            std::string str;                                //very complicated typecast char->const char*; is there no better way?
147            str += *itr;
148            const char* tmp = str.c_str();
149
150            buffer*=10;
151            buffer+=atoi(tmp);
152        }
153        else
154        {
155            switch(*itr)
156            {
157                case 'd': multiplier = DAY;     break;
158                case 'h': multiplier = HOUR;    break;
159                case 'm': multiplier = MINUTE;  break;
160                case 's': multiplier = 1;       break;
161                default : return 0;                         //bad format
162            }
163            buffer*=multiplier;
164            secs+=buffer;
165            buffer=0;
166        }
167    }
168
169    return secs;
170}
171
172std::string TimeToTimestampStr(time_t t)
173{
174    tm* aTm = localtime(&t);
175    //       YYYY   year
176    //       MM     month (2 digits 01-12)
177    //       DD     day (2 digits 01-31)
178    //       HH     hour (2 digits 00-23)
179    //       MM     minutes (2 digits 00-59)
180    //       SS     seconds (2 digits 00-59)
181    char buf[20];
182    snprintf(buf,20,"%04d-%02d-%02d_%02d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
183    return std::string(buf);
184}
185
186/// Check if the string is a valid ip address representation
187bool IsIPAddress(char const* ipaddress)
188{
189    if(!ipaddress)
190        return false;
191
192    // Let the big boys do it.
193    // Drawback: all valid ip address formats are recognized e.g.: 12.23,121234,0xABCD)
194    return inet_addr(ipaddress) != INADDR_NONE;
195}
196
197/// create PID file
198uint32 CreatePIDFile(std::string filename)
199{
200    FILE * pid_file = fopen (filename.c_str(), "w" );
201    if (pid_file == NULL)
202        return 0;
203
204#ifdef WIN32
205    DWORD pid = GetCurrentProcessId();
206#else
207    pid_t pid = getpid();
208#endif
209
210    fprintf(pid_file, "%d", pid );
211    fclose(pid_file);
212
213    return (uint32)pid;
214}
215
216size_t utf8length(std::string& utf8str)
217{
218    try
219    {
220        return utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
221    }
222    catch(std::exception)
223    {
224        utf8str = "";
225        return 0;
226    }
227}
228
229void utf8truncate(std::string& utf8str,size_t len)
230{
231    try
232    {
233        size_t wlen = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
234        if(wlen <= len)
235            return;
236
237        std::wstring wstr;
238        wstr.resize(wlen);
239        utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
240        wstr.resize(len);
241        char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str[0]);
242        utf8str.resize(oend-(&utf8str[0]));                 // remove unused tail
243    }
244    catch(std::exception)
245    {
246        utf8str = "";
247    }
248}
249
250bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
251{
252    try
253    {
254        size_t len = utf8::distance(utf8str,utf8str+csize);
255        if(len > wsize)
256        {
257            wsize = 0;
258            wstr = L"";
259            return false;
260        }
261
262        wsize = len;
263        utf8::utf8to16(utf8str,utf8str+csize,wstr);
264        wstr[len] = L'\0';
265    }
266    catch(std::exception)
267    {
268        wsize = 0;
269        wstr = L"";
270        return false;
271    }
272
273    return true;
274}
275
276bool Utf8toWStr(std::string utf8str, std::wstring& wstr)
277{
278    try
279    {
280        size_t len = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
281        wstr.resize(len);
282
283        utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
284    }
285    catch(std::exception)
286    {
287        wstr = L"";
288        return false;
289    }
290
291    return true;
292}
293
294bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
295{
296    try
297    {
298        std::string utf8str2;
299        utf8str2.resize(size*4);                            // allocate for most long case
300
301        char* oend = utf8::utf16to8(wstr,wstr+size,&utf8str2[0]);
302        utf8str2.resize(oend-(&utf8str2[0]));               // remove unused tail
303        utf8str = utf8str2;
304    }
305    catch(std::exception)
306    {
307        utf8str = "";
308        return false;
309    }
310
311    return true;
312}
313
314bool WStrToUtf8(std::wstring wstr, std::string& utf8str)
315{
316    try
317    {
318        std::string utf8str2;
319        utf8str2.resize(wstr.size()*4);                     // allocate for most long case
320
321        char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str2[0]);
322        utf8str2.resize(oend-(&utf8str2[0]));                // remove unused tail
323        utf8str = utf8str2;
324    }
325    catch(std::exception)
326    {
327        utf8str = "";
328        return false;
329    }
330
331    return true;
332}
333
334typedef wchar_t const* const* wstrlist;
335
336std::wstring GetMainPartOfName(std::wstring wname, uint32 declension)
337{
338    // supported only Cyrillic cases
339    if(wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5)
340        return wname;
341
342    // Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
343
344    static wchar_t const a_End[]    = { wchar_t(1), wchar_t(0x0430),wchar_t(0x0000)};
345    static wchar_t const o_End[]    = { wchar_t(1), wchar_t(0x043E),wchar_t(0x0000)};
346    static wchar_t const ya_End[]   = { wchar_t(1), wchar_t(0x044F),wchar_t(0x0000)};
347    static wchar_t const ie_End[]   = { wchar_t(1), wchar_t(0x0435),wchar_t(0x0000)};
348    static wchar_t const i_End[]    = { wchar_t(1), wchar_t(0x0438),wchar_t(0x0000)};
349    static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B),wchar_t(0x0000)};
350    static wchar_t const u_End[]    = { wchar_t(1), wchar_t(0x0443),wchar_t(0x0000)};
351    static wchar_t const yu_End[]   = { wchar_t(1), wchar_t(0x044E),wchar_t(0x0000)};
352    static wchar_t const oj_End[]   = { wchar_t(2), wchar_t(0x043E),wchar_t(0x0439),wchar_t(0x0000)};
353    static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x0439),wchar_t(0x0000)};
354    static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x0439),wchar_t(0x0000)};
355    static wchar_t const o_m_End[]  = { wchar_t(2), wchar_t(0x043E),wchar_t(0x043C),wchar_t(0x0000)};
356    static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x043C),wchar_t(0x0000)};
357    static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x043C),wchar_t(0x0000)};
358    static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C),wchar_t(0x0000)};
359    static wchar_t const j_End[]    = { wchar_t(1), wchar_t(0x0439),wchar_t(0x0000)};
360
361    static wchar_t const* const dropEnds[6][8] = {
362        { &a_End[1],  &o_End[1],    &ya_End[1],   &ie_End[1],  &soft_End[1], &j_End[1],    NULL,       NULL },
363        { &a_End[1],  &ya_End[1],   &yeru_End[1], &i_End[1],   NULL,         NULL,         NULL,       NULL },
364        { &ie_End[1], &u_End[1],    &yu_End[1],   &i_End[1],   NULL,         NULL,         NULL,       NULL },
365        { &u_End[1],  &yu_End[1],   &o_End[1],    &ie_End[1],  &soft_End[1], &ya_End[1],   &a_End[1],  NULL },
366        { &oj_End[1], &io_j_End[1], &ie_j_End[1], &o_m_End[1], &io_m_End[1], &ie_m_End[1], &yu_End[1], NULL },
367        { &ie_End[1], &i_End[1],    NULL,         NULL,        NULL,         NULL,         NULL,       NULL }
368    };
369
370    for(wchar_t const * const* itr = &dropEnds[declension][0]; *itr; ++itr)
371    {
372        size_t len = size_t((*itr)[-1]);                    // get length from string size field
373
374        if(wname.substr(wname.size()-len,len)==*itr)
375            return wname.substr(0,wname.size()-len);
376    }
377
378    return wname;
379}
380
381bool utf8ToConsole(std::string utf8str, std::string& conStr)
382{
383#if PLATFORM == PLATFORM_WINDOWS
384    std::wstring wstr;
385    if(!Utf8toWStr(utf8str,wstr))
386        return false;
387
388    conStr.resize(wstr.size());
389    CharToOemBuffW(&wstr[0],&conStr[0],wstr.size());
390#else
391    // not implemented yet
392    conStr = utf8str;
393#endif
394
395    return true;
396}
397
398bool consoleToUtf8(std::string conStr,std::string& utf8str)
399{
400#if PLATFORM == PLATFORM_WINDOWS
401    std::wstring wstr;
402    wstr.resize(conStr.size());
403    OemToCharBuffW(&conStr[0],&wstr[0],conStr.size());
404
405    return WStrToUtf8(wstr,utf8str);
406#else
407    // not implemented yet
408    utf8str = conStr;
409    return true;
410#endif
411}
412
413bool Utf8FitTo(std::string str, std::wstring search)
414{
415    std::wstring temp;
416
417    if(!Utf8toWStr(str,temp))
418        return false;
419
420    // converting to lower case
421    wstrToLower( temp );
422
423    if(temp.find(search) == std::wstring::npos)
424        return false;
425
426    return true;
427}
Note: See TracBrowser for help on using the browser.