EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
utils_string.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Captnoord, Bloody.Rabbit
24 */
25 
26 #include "eve-core.h"
27 
28 #include "utils/utils_string.h"
29 
30 const std::string NULL_STRING = "NULL";
31 
32 std::string GenerateKey( size_t length )
33 {
34  static const char CHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
35  static const size_t CHARS_COUNT = sizeof( CHARS ) / sizeof( char );
36 
37  std::string key;
38 
39  for(; 0 < length; --length)
40  key += CHARS[ MakeRandomInt( 0, CHARS_COUNT - 1 ) ];
41 
42  return key;
43 }
44 
45 bool IsNumber( char c )
46 {
47  return 0 != isdigit( c );
48 }
49 
50 bool IsNumber( const char* str, size_t len )
51 {
52  // skip sign if there is one
53  if( len >= 1 )
54  {
55  if( '-' == str[0]
56  || '+' == str[0] )
57  {
58  str += 1;
59  len -= 1;
60  }
61  }
62 
63  if( 0 == len )
64  return false;
65 
66  bool seenDec = false;
67  for(; len > 0; ++str, --len)
68  {
69  if( !IsNumber( *str ) )
70  {
71  if( !seenDec && '.' == *str )
72  seenDec = true;
73  else
74  return false;
75  }
76  }
77 
78  return true;
79 }
80 
81 bool IsNumber( const std::string& str )
82 {
83  return IsNumber( str.c_str(), str.length() );
84 }
85 
86 bool IsHexNumber( char c )
87 {
88  return 0 != isxdigit( c );
89 }
90 
91 bool IsHexNumber( const char* str, size_t len )
92 {
93  // skip sign if there is one
94  if( 1 >= len )
95  {
96  if( '-' == str[0]
97  || '+' == str[0] )
98  {
99  str += 1;
100  len -= 1;
101  }
102  }
103 
104  // skip "0x" or "0X" prefix if there is one
105  if( 2 >= len )
106  {
107  if( '0' == str[0]
108  && ( 'x' == str[1]
109  || 'X' == str[1] ) )
110  {
111  str += 2;
112  len -= 2;
113  }
114  }
115 
116  if( 0 == len )
117  return false;
118 
119  for(; len > 0; ++str, --len)
120  {
121  if( !IsHexNumber( *str ) )
122  return false;
123  }
124 
125  return true;
126 }
127 
128 bool IsHexNumber( const std::string& str )
129 {
130  return IsHexNumber( str.c_str(), str.length() );
131 }
132 
133 bool IsPrintable( char c )
134 {
135  // They seem to expect it unsigned ...
136  const unsigned char _c = c;
137 
138  return ( isgraph( _c ) || isspace( _c ) );
139 }
140 
141 bool IsPrintable( const char* str, size_t len )
142 {
143  for(; len > 0; ++str, --len)
144  {
145  if( !IsPrintable( *str ) )
146  return false;
147  }
148 
149  return true;
150 }
151 
152 bool IsPrintable( const std::string& str )
153 {
154  return IsPrintable( str.c_str(), str.size() );
155 }
156 
157 #define _ITOA_BUFLEN 21
158 
159 const char* itoa( int64 num )
160 {
161  static char buf[ _ITOA_BUFLEN ];
162  memset( buf, 0, _ITOA_BUFLEN );
163 
164  snprintf( buf, _ITOA_BUFLEN, "%li", num );
165 
166  return buf;
167 }
168 
169 void ListToINString( const std::vector<int32>& ints, std::string& into, const char* if_empty )
170 {
171  if( ints.empty() )
172  {
173  into = if_empty;
174  return;
175  }
176 
177  /*
178  * Some small theory about numbers to strings
179  *
180  * the max size of a number converted to
181  * a string is:
182  * uint32 -1 results in
183  * "4294967295" which is 10 characters.
184  */
185  size_t format_index = into.size();
186  into.resize( format_index + ints.size() * ( 10 + 1 ) );
187 
188  std::vector<int32>::const_iterator cur, end;
189  cur = ints.begin();
190  end = ints.end();
191  for(; cur != end; ++cur)
192  {
193  if( ( cur + 1 ) != end )
194  format_index += snprintf( &into[ format_index ], 12, "%i,", *cur );
195  else
196  // last value to be printed
197  format_index += snprintf( &into[ format_index ], 11, "%i", *cur );
198  }
199 }
200 
201 void MakeUpperString( const char* source, char* target )
202 {
203  if( !target )
204  return;
205 
206  for(; *source; ++target, ++source )
207  *target = toupper( *source );
208 
209  *target = 0;
210 }
211 
212 void MakeLowerString( const char* source, char* target )
213 {
214  if( !target )
215  return;
216 
217  for(; *source; ++target, ++source )
218  *target = tolower( *source );
219 
220  *target = 0;
221 }
222 
223 bool PyDecodeEscape( const char* str, Buffer& into )
224 {
225  const size_t len = strlen( str );
226  const char* const end = str + len;
227 
228  while( str < end )
229  {
230  if( *str != '\\' )
231  {
232  into.Append< char >( *str++ );
233  continue;
234  }
235 
236  if( ++str == end )
237  //ended with a \ char
238  return false;
239 
240  int c;
241  switch( *str++ )
242  {
243  /* XXX This assumes ASCII! */
244  case '\n': break; /* ? */
245  case '\\': into.Append< char >( '\\' ); break;
246  case '\'': into.Append< char >( '\'' ); break;
247  case '\"': into.Append< char >( '\"' ); break;
248  case 'b': into.Append< char >( '\b' ); break;
249  case 'f': into.Append< char >( '\014' ); break; /* FF */
250  case 't': into.Append< char >( '\t' ); break;
251  case 'n': into.Append< char >( '\n' ); break;
252  case 'r': into.Append< char >( '\r' ); break;
253  case 'v': into.Append< char >( '\013' ); break; /* VT */
254  case 'a': into.Append< char >( '\007' ); break; /* BEL, not classic C */
255 
256  case '0':
257  case '1':
258  case '2':
259  case '3':
260  case '4':
261  case '5':
262  case '6':
263  case '7':
264  c = str[-1] - '0';
265  if( '0' <= *str && *str <= '7' )
266  {
267  c = ( c << 3 ) + *str++ - '0';
268  if( '0' <= *str && *str <= '7' )
269  c = ( c << 3 ) + *str++ - '0';
270  }
271  into.Append< uint8 >( c );
272  break;
273 
274  case 'x':
275  if( isxdigit( str[0] ) && isxdigit( str[1] ) )
276  {
277  unsigned int x = 0;
278  c = *str++;
279 
280  if( isdigit(c) )
281  x = c - '0';
282  else if( islower(c) )
283  x = 10 + c - 'a';
284  else
285  x = 10 + c - 'A';
286 
287  x = x << 4;
288  c = *str++;
289 
290  if( isdigit(c) )
291  x += c - '0';
292  else if( islower(c) )
293  x += 10 + c - 'a';
294  else
295  x += 10 + c - 'A';
296 
297  into.Append< uint8 >( x );
298  break;
299  }
300  //"invalid \\x escape");
301  return false;
302 
303  default:
304  return false;
305  }
306  }
307 
308  return true;
309 }
310 
311 void SearchReplace( std::string& subject, const std::string& search, const std::string& replace )
312 {
313  std::string::size_type pos = 0;
314  while( ( pos = subject.find( search, pos ) ) != std::string::npos )
315  {
316  subject.replace( pos, search.length(), replace );
317  pos += replace.length();
318  }
319 }
320 
321 void SplitPath( const std::string& path, std::vector<std::string>& into )
322 {
323  const char* p = path.c_str();
324  const char* begin = p;
325  size_t len = 0;
326 
327  for(; *p != '\0'; ++p)
328  {
329  if( *p == '/' || *p == '\\' )
330  {
331  into.push_back( std::string( begin, len ) );
332  len = 0;
333  begin = p + 1;
334  }
335  else
336  {
337  ++len;
338  }
339  }
340 
341  if( begin < p )
342  into.push_back( std::string( begin, len ) );
343 }
void Append(const T &value)
Appends a single value to buffer.
Definition: Buffer.h:437
unsigned __int8 uint8
Definition: eve-compat.h:46
bool PyDecodeEscape(const char *str, Buffer &into)
Decodes string escapes into actual characters.
#define _ITOA_BUFLEN
void SplitPath(const std::string &path, std::vector< std::string > &into)
Splits path to its components.
bool IsPrintable(char c)
Checks whether character is printable.
Generic class for buffers.
Definition: Buffer.h:40
void MakeLowerString(const char *source, char *target)
tolower() for strings.
bool IsHexNumber(char c)
Checks whether character is a hexadecimal number.
#define snprintf
Definition: eve-compat.h:184
void MakeUpperString(const char *source, char *target)
toupper() for strings.
const std::string NULL_STRING
std::string to use where you would use NULL for const char*.
bool IsNumber(char c)
Checks whether character is a number.
int64 MakeRandomInt(int64 low, int64 high)
Generates random integer from interval [low; high].
Definition: misc.cpp:109
signed __int64 int64
Definition: eve-compat.h:51
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type() key(value)-Send an OnRemoteMessage" ) COMMAND( setbpattr
std::string GenerateKey(size_t length)
Generates random key.
void SearchReplace(std::string &subject, const std::string &search, const std::string &replace)
Does search & replace on subject.
void ListToINString(const std::vector< int32 > &ints, std::string &into, const char *if_empty)
const char * itoa(int64 num)
Convers num to string.