gatelib  2.1
g_str_lib.h
Go to the documentation of this file.
1 
2 #pragma once
3 #include "g_car_base.h"
4 #include <stdio.h>
5 
6 #ifndef size_t
7 typedef unsigned int size_t;
8 #endif
9 
10 namespace g
11 {
12 static const size_t infinite = (size_t)-1;
13 namespace str
14 {
15 
22 static const int alloc_new = 0;
24 
30 wchar_t* to_widestr( const char* src , wchar_t* dst = (wchar_t*)alloc_new );
31 
32 
38 char* to_charstr( const wchar_t* src , char* dst = (char*)alloc_new );
39 
41 template<class T> inline size_t get_len( const T* aString )
42 {
43  if (aString != NULL)
44  {
45  size_t len;
46 
47  for (len = 0; aString[len] != 0; len++);
48 
49  return len;
50  }
51  else
52  {
53  return 0;
54  }
55 }
56 
60 template <class T> inline size_t str_copy( T* aDestP , const T* aSrcP , size_t aNumChars = infinite )
61 {
62  size_t i;
63 
64  if (aSrcP != NULL)
65  {
66  for ( i = 0; aSrcP[i] != 0 && i < aNumChars; i++)
67  {
68  aDestP[i] = aSrcP[i];
69  }
70 
71  aDestP[i] = 0;
72  return i;
73  }
74  else
75  {
76  aDestP[0] = 0; // = ""
77  return 0;
78  }
79 }
80 
81 
87 inline wchar_t* to_widestr( const char* aSrcP , wchar_t* aDstP )
88 {
89  size_t len = get_len(aSrcP);
90 
91  if (!len)
92  return 0;
93 
94  wchar_t* dst_p = (aDstP != alloc_new) ? aDstP : new wchar_t[len + 1];
95 
96  for (size_t i = 0; i <= len; i++)
97  {
98  dst_p[i] = *((unsigned char*)aSrcP + i);
99  }
100 
101  return dst_p;
102 }
103 
109 inline char* to_charstr( const wchar_t* aSrcP , char* aDstP )
110 {
111  size_t len = get_len(aSrcP);
112 
113  if (!len)
114  return 0;
115 
116  char* dst_p = (aDstP != alloc_new) ? aDstP : new char[len + 1];
117 
118  for (size_t i = 0; i <= len; i++)
119  {
120  dst_p[i] = static_cast<char>(aSrcP[i] & 0xff);
121  }
122 
123  return dst_p;
124 }
125 
142 template<class T> inline int str_compare( const T* aS1 , const T* aS2 , bool aIsCaseSens = true , size_t aNumChars = infinite )
143 {
144  if ( aS1 == NULL || *aS1 == 0 )
145  {
146  return ( aS2 == NULL || *aS2 == 0 )?0:-1;
147  }
148  else if ( aS2 == NULL || *aS2 == 0 )
149  {
150  return +1;
151  }
152  else
153  {
154  size_t i;
155 
156  for (i = 0; aS1[i] != 0 && aS2[i] != 0 && (size_t)i < aNumChars; i++)
157  {
158  switch ( car::chr_compare (aS1[i], aS2[i], aIsCaseSens) )
159  {
160  case 1: return 1;
161  case -1: return -1;
162  }
163  }
164 
165  if (i == aNumChars)
166  {
167  //in this case I've reached the character limit ( aNumChars )
168  return 0;
169  }
170  else if (aS1[i] == aS2[i])
171  {
172  //equal if the two characters are the terminator(0)
173  return 0;
174  }
175  else if ( aS1[i]==0 )
176  {
177  return -1; //aS1 is shorter in this case
178  }
179  else
180  {
181  return +1; //aS2 is shorter in this case
182  }
183  }
184 }
185 
195 template<class T> inline bool str_equal( const T* aS1 , const T* aS2 , bool aIsCaseSens = true , size_t aNumChars = infinite )
196 {
197  if ( ( aS1 == NULL && aS2 == NULL ) || ( aS1 == NULL && *aS2 == 0 ) || ( aS2 == NULL && *aS1 == 0 ) )
198  {
199  return true;
200  }
201  else
202  {
203  size_t i;
204 
205  for (i = 0; aS1[i] != 0 && aS2[i] != 0 && (size_t)i < aNumChars; i++)
206  {
207  if (!car::chr_equal(aS1[i], aS2[i], aIsCaseSens))
208  {
209  return false;
210  }
211  }
212 
213  if (i == aNumChars)
214  {
215  //in this case I've reached the character limit ( aNumChars )
216  return true;
217  }
218  else
219  {
220  //equal if the two characters are the terminator(0)
221  return (aS1[i] == aS2[i]); // = 0
222  }
223  }
224 }
225 
238 template<class T> inline size_t str_search( const T* aS1 , const T* aS2 , bool aIsCaseSens = true , size_t aNumChars = infinite )
239 {
240  size_t i;
241 
242  for ( i = 0 ; aS1[i] != 0 && i < aNumChars ; i++ )
243  {
244  bool found = true;
245 
246  for ( size_t j = 0 ; aS2[j] != 0 ; j++ )
247  {
248  if ( !car::chr_equal(aS1[i+j], aS2[j], aIsCaseSens) )
249  {
250  found = false;
251  break;
252  }
253  }
254 
255  if ( found )
256  {
257  return i;
258  }
259  }
260 
261  return i;
262 }
263 
274 template < class T >
275  inline size_t str_replace ( const T* aString , const T* aWhat , const T* aWith , T* aOutputBuffer , size_t aNumChars = infinite )
276 {
277  size_t num_read_chars = 0;
278  size_t what_len = g::str::get_len(aWhat);
279  size_t with_len = g::str::get_len(aWith);
280  size_t remaining_buffer_chars = aNumChars;
281 
282  if ( what_len == 0 )
283  {
284  return str_copy(aOutputBuffer,aString,aNumChars);
285  }
286 
287  for ( ; *aString != 0 && remaining_buffer_chars > 0 ; )
288  {
289  size_t offset = str_search ( aString , aWhat , true );
290 
291  if ( aString[offset] != 0 )
292  {
293  size_t temp_copied = str_copy(aOutputBuffer,aString,(remaining_buffer_chars>offset)?offset:remaining_buffer_chars);
294 
295  remaining_buffer_chars -= temp_copied;
296  num_read_chars += temp_copied;
297  aString += temp_copied;//moving in buffer
298  aOutputBuffer += temp_copied;//moving outbuffer
299 
300  if ( remaining_buffer_chars >= with_len )
301  {
302  num_read_chars += what_len;
303  aString += what_len;//moving in buffer
304 
305  //copy replacing word to output
306  temp_copied = str_copy(aOutputBuffer,aWith,(remaining_buffer_chars>with_len)?with_len:remaining_buffer_chars);
307 
308  //update counters again
309  remaining_buffer_chars -= temp_copied;
310  aOutputBuffer += temp_copied;//moving outbuffer
311  }
312  else
313  {
314  break;
315  }
316  }
317  else
318  {
319  //str_search fails: fill until end of string
320  size_t temp_copied = str_copy(aOutputBuffer,aString,remaining_buffer_chars);
321 
322  num_read_chars += temp_copied;
323  remaining_buffer_chars -= temp_copied;
324  aString += temp_copied;//moving in buffer
325  aOutputBuffer += temp_copied;//moving outbuffer
326  }
327  }
328 
329  *aOutputBuffer = 0;
330 
331  return num_read_chars;
332 }
333 
345 template < class T , class R , size_t S > inline R str_replace ( const T* aInput , const T* aWhat , const T* aWith )
346 {
347  //const int S = 1024;
348  T temp[S+1];
349  R result;
350 
351  while ( true )
352  {
353  size_t how_many = g::str::str_replace ( aInput , aWhat , aWith , temp , S );
354 
355  result += temp;
356 
357  if ( aInput[how_many] == 0 )//i'm at the end of the string
358  {
359  return result;
360  }
361  else
362  {
363  aInput += how_many;
364  }
365  }
366 }
367 
370 }// namespace str
371 }// namespace g
int str_compare(const T *aS1, const T *aS2, bool aIsCaseSens=true, size_t aNumChars=infinite)
Compares two strings.
Definition: g_str_lib.h:142
size_t get_len(const T *aString)
Returns the string length.
Definition: g_str_lib.h:41
Definition: g.mthread.ThreadSimpleEvent.h:5
char * to_charstr(const wchar_t *src, char *dst=(char *) alloc_new)
converts a wide gstr ( const wchar_t* ) to a wide one ( char* )
Definition: g_str_lib.h:109
size_t str_copy(T *aDestP, const T *aSrcP, size_t aNumChars=infinite)
Copies from aSrc to aDest up to a maximum of aNumChars characters (excluding terminator) ...
Definition: g_str_lib.h:60
wchar_t * to_widestr(const char *src, wchar_t *dst=(wchar_t *) alloc_new)
converts a byte gstr ( const char* ) to a wide one ( wchar_t* ).
Definition: g_str_lib.h:87
int chr_compare(T aC1, T aC2, bool aIsCaseSensitive)
Compares two chars.
Definition: g_car_base.h:88
bool str_equal(const T *aS1, const T *aS2, bool aIsCaseSens=true, size_t aNumChars=infinite)
Check two strings for equality.
Definition: g_str_lib.h:195
size_t str_search(const T *aS1, const T *aS2, bool aIsCaseSens=true, size_t aNumChars=infinite)
Searches aS2 inside aS1.
Definition: g_str_lib.h:238
R str_replace(const T *aInput, const T *aWhat, const T *aWith)
Replace aWhat with aWith inside aInput and returns the result as a class string (a std::string ...
Definition: g_str_lib.h:345