2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "sockets/socket_include.h"
22 #include "utf8cpp/utf8.h"
23 #include "mersennetwister/MersenneTwister.h"
24 #include "zthread/ThreadLocal.h"
26 typedef ZThread::ThreadLocal
<MTRand
> MTRandTSS
;
28 /* NOTE: Not sure if static initialization is ok for TSS objects ,
29 * as I see zthread uses custom implementation of the TSS
30 * ,and in the consturctor there is no code ,so I suppose its ok
31 * If its not ok ,change it to use singleton.
33 static MTRandTSS mtRand
;
35 int32
irand (int32 min
, int32 max
)
37 return int32 (mtRand
.get ().randInt (max
- min
)) + min
;
40 uint32
urand (uint32 min
, uint32 max
)
42 return mtRand
.get ().randInt (max
- min
) + min
;
47 return mtRand
.get ().randInt ();
50 double rand_norm(void)
52 return mtRand
.get ().randExc ();
55 double rand_chance (void)
57 return mtRand
.get ().randExc (100.0);
60 Tokens
StrSplit(const std::string
&src
, const std::string
&sep
)
64 for (std::string::const_iterator i
= src
.begin(); i
!= src
.end(); i
++)
66 if (sep
.find(*i
) != std::string::npos
)
68 if (s
.length()) r
.push_back(s
);
76 if (s
.length()) r
.push_back(s
);
80 void stripLineInvisibleChars(std::string
&str
)
82 static std::string invChars
= " \t\7";
87 for(size_t pos
= 0; pos
< str
.size(); ++pos
)
89 if(invChars
.find(str
[pos
])!=std::string::npos
)
100 str
[wpos
++] = str
[pos
];
107 if(wpos
< str
.size())
108 str
.erase(wpos
,str
.size());
111 std::string
secsToTimeString(uint32 timeInSecs
, bool shortText
, bool hoursOnly
)
113 uint32 secs
= timeInSecs
% MINUTE
;
114 uint32 minutes
= timeInSecs
% HOUR
/ MINUTE
;
115 uint32 hours
= timeInSecs
% DAY
/ HOUR
;
116 uint32 days
= timeInSecs
/ DAY
;
118 std::ostringstream ss
;
120 ss
<< days
<< (shortText
? "d" : " Day(s) ");
121 if(hours
|| hoursOnly
)
122 ss
<< hours
<< (shortText
? "h" : " Hour(s) ");
126 ss
<< minutes
<< (shortText
? "m" : " Minute(s) ");
127 if(secs
|| (!days
&& !hours
&& !minutes
) )
128 ss
<< secs
<< (shortText
? "s" : " Second(s).");
134 uint32
TimeStringToSecs(const std::string
& timestring
)
138 uint32 multiplier
= 0;
140 for(std::string::const_iterator itr
= timestring
.begin(); itr
!= timestring
.end(); itr
++ )
144 std::string str
; //very complicated typecast char->const char*; is there no better way?
146 const char* tmp
= str
.c_str();
155 case 'd': multiplier
= DAY
; break;
156 case 'h': multiplier
= HOUR
; break;
157 case 'm': multiplier
= MINUTE
; break;
158 case 's': multiplier
= 1; break;
159 default : return 0; //bad format
170 std::string
TimeToTimestampStr(time_t t
)
172 tm
* aTm
= localtime(&t
);
174 // MM month (2 digits 01-12)
175 // DD day (2 digits 01-31)
176 // HH hour (2 digits 00-23)
177 // MM minutes (2 digits 00-59)
178 // SS seconds (2 digits 00-59)
180 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
);
181 return std::string(buf
);
184 /// Check if the string is a valid ip address representation
185 bool IsIPAddress(char const* ipaddress
)
190 // Let the big boys do it.
191 // Drawback: all valid ip address formats are recognized e.g.: 12.23,121234,0xABCD)
192 return inet_addr(ipaddress
) != INADDR_NONE
;
196 uint32
CreatePIDFile(const std::string
& filename
)
198 FILE * pid_file
= fopen (filename
.c_str(), "w" );
199 if (pid_file
== NULL
)
203 DWORD pid
= GetCurrentProcessId();
205 pid_t pid
= getpid();
208 fprintf(pid_file
, "%d", pid
);
214 size_t utf8length(std::string
& utf8str
)
218 return utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
220 catch(std::exception
)
227 void utf8truncate(std::string
& utf8str
,size_t len
)
231 size_t wlen
= utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
237 utf8::utf8to16(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size(),&wstr
[0]);
239 char* oend
= utf8::utf16to8(wstr
.c_str(),wstr
.c_str()+wstr
.size(),&utf8str
[0]);
240 utf8str
.resize(oend
-(&utf8str
[0])); // remove unused tail
242 catch(std::exception
)
248 bool Utf8toWStr(char const* utf8str
, size_t csize
, wchar_t* wstr
, size_t& wsize
)
252 size_t len
= utf8::distance(utf8str
,utf8str
+csize
);
261 utf8::utf8to16(utf8str
,utf8str
+csize
,wstr
);
264 catch(std::exception
)
274 bool Utf8toWStr(const std::string
& utf8str
, std::wstring
& wstr
)
278 size_t len
= utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
281 utf8::utf8to16(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size(),&wstr
[0]);
283 catch(std::exception
)
292 bool WStrToUtf8(wchar_t* wstr
, size_t size
, std::string
& utf8str
)
296 std::string utf8str2
;
297 utf8str2
.resize(size
*4); // allocate for most long case
299 char* oend
= utf8::utf16to8(wstr
,wstr
+size
,&utf8str2
[0]);
300 utf8str2
.resize(oend
-(&utf8str2
[0])); // remove unused tail
303 catch(std::exception
)
312 bool WStrToUtf8(std::wstring wstr
, std::string
& utf8str
)
316 std::string utf8str2
;
317 utf8str2
.resize(wstr
.size()*4); // allocate for most long case
319 char* oend
= utf8::utf16to8(wstr
.c_str(),wstr
.c_str()+wstr
.size(),&utf8str2
[0]);
320 utf8str2
.resize(oend
-(&utf8str2
[0])); // remove unused tail
323 catch(std::exception
)
332 typedef wchar_t const* const* wstrlist
;
334 std::wstring
GetMainPartOfName(std::wstring wname
, uint32 declension
)
336 // supported only Cyrillic cases
337 if(wname
.size() < 1 || !isCyrillicCharacter(wname
[0]) || declension
> 5)
340 // Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
342 static wchar_t const a_End
[] = { wchar_t(1), wchar_t(0x0430),wchar_t(0x0000)};
343 static wchar_t const o_End
[] = { wchar_t(1), wchar_t(0x043E),wchar_t(0x0000)};
344 static wchar_t const ya_End
[] = { wchar_t(1), wchar_t(0x044F),wchar_t(0x0000)};
345 static wchar_t const ie_End
[] = { wchar_t(1), wchar_t(0x0435),wchar_t(0x0000)};
346 static wchar_t const i_End
[] = { wchar_t(1), wchar_t(0x0438),wchar_t(0x0000)};
347 static wchar_t const yeru_End
[] = { wchar_t(1), wchar_t(0x044B),wchar_t(0x0000)};
348 static wchar_t const u_End
[] = { wchar_t(1), wchar_t(0x0443),wchar_t(0x0000)};
349 static wchar_t const yu_End
[] = { wchar_t(1), wchar_t(0x044E),wchar_t(0x0000)};
350 static wchar_t const oj_End
[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x0439),wchar_t(0x0000)};
351 static wchar_t const ie_j_End
[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x0439),wchar_t(0x0000)};
352 static wchar_t const io_j_End
[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x0439),wchar_t(0x0000)};
353 static wchar_t const o_m_End
[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x043C),wchar_t(0x0000)};
354 static wchar_t const io_m_End
[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x043C),wchar_t(0x0000)};
355 static wchar_t const ie_m_End
[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x043C),wchar_t(0x0000)};
356 static wchar_t const soft_End
[] = { wchar_t(1), wchar_t(0x044C),wchar_t(0x0000)};
357 static wchar_t const j_End
[] = { wchar_t(1), wchar_t(0x0439),wchar_t(0x0000)};
359 static wchar_t const* const dropEnds
[6][8] = {
360 { &a_End
[1], &o_End
[1], &ya_End
[1], &ie_End
[1], &soft_End
[1], &j_End
[1], NULL
, NULL
},
361 { &a_End
[1], &ya_End
[1], &yeru_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
},
362 { &ie_End
[1], &u_End
[1], &yu_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
},
363 { &u_End
[1], &yu_End
[1], &o_End
[1], &ie_End
[1], &soft_End
[1], &ya_End
[1], &a_End
[1], NULL
},
364 { &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
},
365 { &ie_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
368 for(wchar_t const * const* itr
= &dropEnds
[declension
][0]; *itr
; ++itr
)
370 size_t len
= size_t((*itr
)[-1]); // get length from string size field
372 if(wname
.substr(wname
.size()-len
,len
)==*itr
)
373 return wname
.substr(0,wname
.size()-len
);
379 bool utf8ToConsole(const std::string
& utf8str
, std::string
& conStr
)
381 #if PLATFORM == PLATFORM_WINDOWS
383 if(!Utf8toWStr(utf8str
,wstr
))
386 conStr
.resize(wstr
.size());
387 CharToOemBuffW(&wstr
[0],&conStr
[0],wstr
.size());
389 // not implemented yet
396 bool consoleToUtf8(const std::string
& conStr
,std::string
& utf8str
)
398 #if PLATFORM == PLATFORM_WINDOWS
400 wstr
.resize(conStr
.size());
401 OemToCharBuffW(&conStr
[0],&wstr
[0],conStr
.size());
403 return WStrToUtf8(wstr
,utf8str
);
405 // not implemented yet
411 bool Utf8FitTo(const std::string
& str
, std::wstring search
)
415 if(!Utf8toWStr(str
,temp
))
418 // converting to lower case
421 if(temp
.find(search
) == std::wstring::npos
)