2 * Copyright (C) 2005-2010 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 <ace/TSS_T.h>
26 typedef ACE_TSS
<MTRand
> MTRandTSS
;
27 static MTRandTSS mtRand
;
29 int32
irand (int32 min
, int32 max
)
31 return int32 (mtRand
->randInt (max
- min
)) + min
;
34 uint32
urand (uint32 min
, uint32 max
)
36 return mtRand
->randInt (max
- min
) + min
;
41 return mtRand
->randInt ();
44 double rand_norm(void)
46 return mtRand
->randExc ();
49 double rand_chance (void)
51 return mtRand
->randExc (100.0);
54 Tokens
StrSplit(const std::string
&src
, const std::string
&sep
)
58 for (std::string::const_iterator i
= src
.begin(); i
!= src
.end(); i
++)
60 if (sep
.find(*i
) != std::string::npos
)
62 if (s
.length()) r
.push_back(s
);
70 if (s
.length()) r
.push_back(s
);
74 void stripLineInvisibleChars(std::string
&str
)
76 static std::string invChars
= " \t\7\n";
81 for(size_t pos
= 0; pos
< str
.size(); ++pos
)
83 if(invChars
.find(str
[pos
])!=std::string::npos
)
94 str
[wpos
++] = str
[pos
];
101 if(wpos
< str
.size())
102 str
.erase(wpos
,str
.size());
105 std::string
secsToTimeString(uint32 timeInSecs
, bool shortText
, bool hoursOnly
)
107 uint32 secs
= timeInSecs
% MINUTE
;
108 uint32 minutes
= timeInSecs
% HOUR
/ MINUTE
;
109 uint32 hours
= timeInSecs
% DAY
/ HOUR
;
110 uint32 days
= timeInSecs
/ DAY
;
112 std::ostringstream ss
;
114 ss
<< days
<< (shortText
? "d" : " Day(s) ");
115 if(hours
|| hoursOnly
)
116 ss
<< hours
<< (shortText
? "h" : " Hour(s) ");
120 ss
<< minutes
<< (shortText
? "m" : " Minute(s) ");
121 if(secs
|| (!days
&& !hours
&& !minutes
) )
122 ss
<< secs
<< (shortText
? "s" : " Second(s).");
128 uint32
TimeStringToSecs(const std::string
& timestring
)
132 uint32 multiplier
= 0;
134 for(std::string::const_iterator itr
= timestring
.begin(); itr
!= timestring
.end(); itr
++ )
145 case 'd': multiplier
= DAY
; break;
146 case 'h': multiplier
= HOUR
; break;
147 case 'm': multiplier
= MINUTE
; break;
148 case 's': multiplier
= 1; break;
149 default : return 0; //bad format
160 std::string
TimeToTimestampStr(time_t t
)
162 tm
* aTm
= localtime(&t
);
164 // MM month (2 digits 01-12)
165 // DD day (2 digits 01-31)
166 // HH hour (2 digits 00-23)
167 // MM minutes (2 digits 00-59)
168 // SS seconds (2 digits 00-59)
170 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
);
171 return std::string(buf
);
174 /// Check if the string is a valid ip address representation
175 bool IsIPAddress(char const* ipaddress
)
180 // Let the big boys do it.
181 // Drawback: all valid ip address formats are recognized e.g.: 12.23,121234,0xABCD)
182 return inet_addr(ipaddress
) != INADDR_NONE
;
186 uint32
CreatePIDFile(const std::string
& filename
)
188 FILE * pid_file
= fopen (filename
.c_str(), "w" );
189 if (pid_file
== NULL
)
193 DWORD pid
= GetCurrentProcessId();
195 pid_t pid
= getpid();
198 fprintf(pid_file
, "%d", pid
);
204 size_t utf8length(std::string
& utf8str
)
208 return utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
210 catch(std::exception
)
217 void utf8truncate(std::string
& utf8str
,size_t len
)
221 size_t wlen
= utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
227 utf8::utf8to16(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size(),&wstr
[0]);
229 char* oend
= utf8::utf16to8(wstr
.c_str(),wstr
.c_str()+wstr
.size(),&utf8str
[0]);
230 utf8str
.resize(oend
-(&utf8str
[0])); // remove unused tail
232 catch(std::exception
)
238 bool Utf8toWStr(char const* utf8str
, size_t csize
, wchar_t* wstr
, size_t& wsize
)
242 size_t len
= utf8::distance(utf8str
,utf8str
+csize
);
252 utf8::utf8to16(utf8str
,utf8str
+csize
,wstr
);
255 catch(std::exception
)
266 bool Utf8toWStr(const std::string
& utf8str
, std::wstring
& wstr
)
270 size_t len
= utf8::distance(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size());
273 utf8::utf8to16(utf8str
.c_str(),utf8str
.c_str()+utf8str
.size(),&wstr
[0]);
275 catch(std::exception
)
284 bool WStrToUtf8(wchar_t* wstr
, size_t size
, std::string
& utf8str
)
288 std::string utf8str2
;
289 utf8str2
.resize(size
*4); // allocate for most long case
291 char* oend
= utf8::utf16to8(wstr
,wstr
+size
,&utf8str2
[0]);
292 utf8str2
.resize(oend
-(&utf8str2
[0])); // remove unused tail
295 catch(std::exception
)
304 bool WStrToUtf8(std::wstring wstr
, std::string
& utf8str
)
308 std::string utf8str2
;
309 utf8str2
.resize(wstr
.size()*4); // allocate for most long case
311 char* oend
= utf8::utf16to8(wstr
.c_str(),wstr
.c_str()+wstr
.size(),&utf8str2
[0]);
312 utf8str2
.resize(oend
-(&utf8str2
[0])); // remove unused tail
315 catch(std::exception
)
324 typedef wchar_t const* const* wstrlist
;
326 std::wstring
GetMainPartOfName(std::wstring wname
, uint32 declension
)
328 // supported only Cyrillic cases
329 if(wname
.size() < 1 || !isCyrillicCharacter(wname
[0]) || declension
> 5)
332 // Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
334 static wchar_t const a_End
[] = { wchar_t(1), wchar_t(0x0430),wchar_t(0x0000)};
335 static wchar_t const o_End
[] = { wchar_t(1), wchar_t(0x043E),wchar_t(0x0000)};
336 static wchar_t const ya_End
[] = { wchar_t(1), wchar_t(0x044F),wchar_t(0x0000)};
337 static wchar_t const ie_End
[] = { wchar_t(1), wchar_t(0x0435),wchar_t(0x0000)};
338 static wchar_t const i_End
[] = { wchar_t(1), wchar_t(0x0438),wchar_t(0x0000)};
339 static wchar_t const yeru_End
[] = { wchar_t(1), wchar_t(0x044B),wchar_t(0x0000)};
340 static wchar_t const u_End
[] = { wchar_t(1), wchar_t(0x0443),wchar_t(0x0000)};
341 static wchar_t const yu_End
[] = { wchar_t(1), wchar_t(0x044E),wchar_t(0x0000)};
342 static wchar_t const oj_End
[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x0439),wchar_t(0x0000)};
343 static wchar_t const ie_j_End
[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x0439),wchar_t(0x0000)};
344 static wchar_t const io_j_End
[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x0439),wchar_t(0x0000)};
345 static wchar_t const o_m_End
[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x043C),wchar_t(0x0000)};
346 static wchar_t const io_m_End
[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x043C),wchar_t(0x0000)};
347 static wchar_t const ie_m_End
[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x043C),wchar_t(0x0000)};
348 static wchar_t const soft_End
[] = { wchar_t(1), wchar_t(0x044C),wchar_t(0x0000)};
349 static wchar_t const j_End
[] = { wchar_t(1), wchar_t(0x0439),wchar_t(0x0000)};
351 static wchar_t const* const dropEnds
[6][8] = {
352 { &a_End
[1], &o_End
[1], &ya_End
[1], &ie_End
[1], &soft_End
[1], &j_End
[1], NULL
, NULL
},
353 { &a_End
[1], &ya_End
[1], &yeru_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
},
354 { &ie_End
[1], &u_End
[1], &yu_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
},
355 { &u_End
[1], &yu_End
[1], &o_End
[1], &ie_End
[1], &soft_End
[1], &ya_End
[1], &a_End
[1], NULL
},
356 { &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
},
357 { &ie_End
[1], &i_End
[1], NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
360 for(wchar_t const * const* itr
= &dropEnds
[declension
][0]; *itr
; ++itr
)
362 size_t len
= size_t((*itr
)[-1]); // get length from string size field
364 if(wname
.substr(wname
.size()-len
,len
)==*itr
)
365 return wname
.substr(0,wname
.size()-len
);
371 bool utf8ToConsole(const std::string
& utf8str
, std::string
& conStr
)
373 #if PLATFORM == PLATFORM_WINDOWS
375 if(!Utf8toWStr(utf8str
,wstr
))
378 conStr
.resize(wstr
.size());
379 CharToOemBuffW(&wstr
[0],&conStr
[0],wstr
.size());
381 // not implemented yet
388 bool consoleToUtf8(const std::string
& conStr
,std::string
& utf8str
)
390 #if PLATFORM == PLATFORM_WINDOWS
392 wstr
.resize(conStr
.size());
393 OemToCharBuffW(&conStr
[0],&wstr
[0],conStr
.size());
395 return WStrToUtf8(wstr
,utf8str
);
397 // not implemented yet
403 bool Utf8FitTo(const std::string
& str
, std::wstring search
)
407 if(!Utf8toWStr(str
,temp
))
410 // converting to lower case
413 if(temp
.find(search
) == std::wstring::npos
)
419 void utf8printf(FILE *out
, const char *str
, ...)
423 vutf8printf(stdout
, str
, &ap
);
427 void vutf8printf(FILE *out
, const char *str
, va_list* ap
)
429 #if PLATFORM == PLATFORM_WINDOWS
430 char temp_buf
[32*1024];
431 wchar_t wtemp_buf
[32*1024];
433 size_t temp_len
= vsnprintf(temp_buf
, 32*1024, str
, *ap
);
435 size_t wtemp_len
= 32*1024-1;
436 Utf8toWStr(temp_buf
, temp_len
, wtemp_buf
, wtemp_len
);
438 CharToOemBuffW(&wtemp_buf
[0], &temp_buf
[0], wtemp_len
+1);
439 fprintf(out
, temp_buf
);
441 vfprintf(out
, str
, *ap
);
445 void hexEncodeByteArray(uint8
* bytes
, uint32 arrayLen
, std::string
& result
)
447 std::ostringstream ss
;
448 for(uint32 i
=0; i
<arrayLen
; ++i
)
450 for(uint8 j
=0; j
<2; ++j
)
452 unsigned char nibble
= 0x0F & (bytes
[i
]>>((1-j
)*4));
455 encodedNibble
= '0'+nibble
;
457 encodedNibble
= 'A'+nibble
-0x0A;