hce-node application  1.4.3
HCE Hierarchical Cluster Engine node application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
String.cpp
Go to the documentation of this file.
1 #include <String.h>
3 {
4  data = (char *) malloc(1);
5  if(!data)
6  {
7  return;
8  }
9  data[0] = '\0';
10  len = 0;
11 }
12 
13 String::String(const char *src)
14 {
15  data = strdup(src);
16  if(data)
17  {
18  len = strlen(data);
19  }
20  else
21  {
22  len = 0;
23  }
24 }
25 
26 String::String(const char *src, unsigned int len)
27 {
28  data = (char *) malloc(len + 1);
29  if(!data)
30  {
31  this->len = 0;
32  return;
33  }
34  memcpy(data, src, len);
35  data[len] = '\0';
36  this->len = len;
37 }
38 
39 String::String(const String & str)
40 {
41  len = str.len;
42  data = (char *) malloc(len + 1);
43  if(!data)
44  {
45  len = 0;
46  return;
47  }
48  memcpy(data, str.data, len + 1);
49 }
50 
52 {
53  free(data);
54 }
55 
57 {
58  if (str.len)
59  {
60  data = (char *) realloc(data, len + str.len + 1);
61  if(data)
62  {
63  memcpy(data + len, str.data, str.len + 1);
64  len += str.len;
65  }
66  }
67  return *this;
68 }
69 
71 {
72  if (&s == this)
73  return *this;
74  free(data);
75  data = strdup(s.data);
76  len = s.len;
77  return *this;
78 }
79 
81 {
82  String c(*this);
83  c += b;
84  return c;
85 }
86 
87 String & String::operator=(const char *str)
88 {
89  free(data);
90  len = strlen(str);
91  data = strdup(str);
92  return *this;
93 }
94 
96 {
97  return (strcmp(data, str.data) == 0);
98 }
99 
101 {
102  return (strcmp(data, str.data) != 0);
103 }
104 
106 {
107  return (strcmp(data, str.data) > 0);
108 }
109 
111 {
112  return (strcmp(data, str.data) < 0);
113 }
114 
115 char &String::operator[] (unsigned int index)
116 {
117  return data[index];
118 }
119 
121 {
122  char *start = data;
123  if (len)
124  {
125  char *buf = (char *) malloc(len << 1);
126  if(!buf)
127  {
128  return;
129  }
130  unsigned int i = 0;
131  while (*data)
132  {
133  if (*data == '\'' || *data == '\"' || *data == '\\')
134  {
135  buf[i++] = '\\';
136  }
137  buf[i++] = *data;
138  data++;
139  }
140  buf[i] = '\0';
141  len = i;
142  buf = (char *) realloc(buf, i + 1);
143  if(!buf)
144  {
145  len = 0;
146  return;
147  }
148  free(start);
149  data = buf;
150  }
151 }
152 
153 void String::replace(const char *search, const char *replace, unsigned int limit)
154 {
155  int s_len = strlen(search);
156  int r_len = strlen(replace);
157  int pos = 0;
158  int delta = r_len - s_len;
159  unsigned int count = 0;
160  while (pos < int (len) && (limit == 0 || (limit > 0 && count < limit)))
161  {
162  if (!strncmp(data + pos, search, s_len))
163  {
164  len += delta;
165  char *buf = (char *) malloc(len + 1);
166  if(!buf)
167  {
168  return;
169  }
170  if (pos)
171  memcpy(buf, data, pos);
172  memcpy(buf + pos, replace, r_len);
173  memcpy(buf + pos + r_len, data + pos + s_len, len - delta - pos - s_len + 1);
174  free(data);
175  data = buf;
176  pos += r_len;
177  }
178  else
179  {
180  pos++;
181  }
182  }
183 }
184 
185 int String::fastReplace(const char *search, const char *replace, unsigned int limit)
186 {
187  register int start, slen, delta, dlen, rlen;
188  int idx = 0;
189  unsigned int count = 0;
190  char *buf;
191  slen = strlen(search);
192  rlen = strlen(replace);
193  delta = rlen - slen;
194  dlen = len;
195  while ((start = fastStrPos(data + idx, search)) >= 0 && !(limit > 0 && limit <= count))
196  {
197  buf = (char *) malloc(dlen + delta + 1);
198  if(!buf)
199  {
200  return count;
201  }
202  start += idx;
203  if (start)
204  memcpy(buf, data, start);
205  memcpy(buf + start, replace, rlen);
206  memcpy(buf + start + rlen, data + start + slen, dlen - (start + slen));
207  dlen += delta;
208  free(data);
209  buf[dlen] = 0;
210  data = buf;
211  idx = start + rlen;
212  count++;
213  }
214  len = dlen;
215  return count;
216 }
217 
218 int String::strPos(const char *search, unsigned int offset)
219 {
220  char *start = strstr(data + offset, search);
221  if (start)
222  {
223  return int (start - data);
224  }
225  return -1;
226 }
227 
228 int String::fastStrPos(const char *search, unsigned int offset)
229 {
230  int plen;
231  int d[256];
232  register int c;
233  register int pindx;
234  register int cmppos;
235  register int endpos;
236  char *data_res = data + offset;
237  plen = strlen(search);
238  for (c = 0; c < 256; c++)
239  {
240  d[c] = len;
241  }
242  for (c = 0; c < plen - 1; c++)
243  {
244  d[search[c] & 0377] = plen - 1 - c;
245  }
246  for (endpos = plen - 1; endpos < int (len);)
247  {
248  for (cmppos = endpos, pindx = (plen - 1); pindx >= 0; cmppos--, pindx--)
249  {
250  if (data_res[cmppos] != search[pindx])
251  {
252  endpos += d[data_res[endpos] & 0377];
253  break;
254  }
255  }
256  if (pindx < 0)
257  {
258  return endpos - (plen - 1) + offset;
259  }
260  }
261  return -1;
262 }
263 
264 int String::fastStrPos(const unsigned char *haystack, int hlen, const unsigned char *needle, int nlen, unsigned int offset)
265 {
266  size_t scan = 0;
267  size_t bad_char_skip[UCHAR_MAX + 1];
268  if (nlen <= 0 || !haystack || !needle)
269  return -1;
270  haystack += offset;
271  const unsigned char *start = haystack;
272  hlen -= offset;
273  for (scan = 0; scan <= UCHAR_MAX; scan = scan + 1)
274  {
275  bad_char_skip[scan] = nlen;
276  }
277  size_t last = nlen - 1;
278  for (scan = 0; scan < last; scan = scan + 1)
279  {
280  bad_char_skip[(unsigned int)(needle[scan])] = last - scan;
281  }
282  while (hlen >= nlen)
283  {
284  for (scan = last; haystack[scan] == needle[scan]; scan = scan - 1)
285  if (scan == 0)
286  return int(haystack - start) + offset;
287  hlen -= bad_char_skip[(unsigned int)(haystack[last])];
288  haystack += bad_char_skip[(unsigned int)(haystack[last])];
289  }
290  return -1;
291 }
292 int String::fastStrPos(const char *data_tmp, const char *search)
293 {
294  int len = strlen(data_tmp);
295  int plen;
296  int d[256];
297  register int c;
298  register int pindx;
299  register int cmppos;
300  register int endpos;
301  plen = strlen(search);
302  for (c = 0; c < 256; c++)
303  {
304  d[c] = len;
305  }
306  for (c = 0; c < plen - 1; c++)
307  {
308  d[search[c] & 0377] = plen - 1 - c;
309  }
310  for (endpos = plen - 1; endpos < len;)
311  {
312  for (cmppos = endpos, pindx = (plen - 1); pindx >= 0; cmppos--, pindx--)
313  {
314  if (data_tmp[cmppos] != search[pindx])
315  {
316  endpos += d[data_tmp[endpos] & 0377];
317  break;
318  }
319  }
320  if (pindx < 0)
321  {
322  return endpos - (plen - 1);
323  }
324  }
325  return -1;
326 }
327 
329 {
330  char symbols[]="0123456789ABCDEF";
331  char *encoded = NULL;
332  register int enc_len = 0;
333  encoded = (char *) malloc(len * 3 + 1);
334  if(!encoded)
335  {
336  return;
337  }
338  for (unsigned int i = 0; i < len; i++)
339  {
340  if (data[i] < 45 || (data[i] == 47) || (data[i] > 57 && data[i] < 65)
341  || (data[i] > 90 && data[i] < 95) || (data[i] == 96)
342  || (data[i] > 122))
343  {
344  encoded[enc_len++] = '%';
345  encoded[enc_len++] = symbols[(((u_int8_t)data[i]) >> 4) & 0xF];
346  encoded[enc_len++] = symbols[u_int8_t(data[i]) & 0xF];
347  }
348  else
349  {
350  encoded[enc_len] = data[i];
351  enc_len++;
352  }
353  }
354  encoded = (char *) realloc(encoded, enc_len + 1);
355  if(encoded)
356  {
357  encoded[enc_len] = 0;
358  free(data);
359  data = encoded;
360  len = enc_len;
361  }
362 }
363 
365 {
366 #define FROM_HEX( x ) ((((x)>=0x30) && ((x)<=0x39))? ((x) - 0x30) : ((x) - 'A' + 0xA))
367  char *decoded = (char *) malloc(len + 1);
368  if(!decoded)
369  {
370  return;
371  }
372  char *cur = decoded;
373  char *url = data;
374  while (*url)
375  {
376  if (*url == '%')
377  {
378  *(cur++) = (FROM_HEX(toupper(url[1])) << 4) + (FROM_HEX(toupper(url[2])));
379  url += 3;
380  }
381  else
382  {
383  *(cur++) = *url == '+' ? ' ' : *url;
384  url++;
385  }
386  }
387  *cur = '\0';
388  free(data);
389  len = (unsigned int) (cur - decoded);
390  data = decoded;
391 }
392 
393 unsigned int String::length()
394 {
395  return len;
396 }
397 
398 String & String::subStr(unsigned int pos, unsigned int len)
399 {
400  String *buf = new(std::nothrow) String();
401  if(!buf)
402  {
403  return *this;
404  }
405  if (pos >= this->len)
406  {
407  return *buf;
408  }
409  if (len + pos > this->len)
410  {
411  len = this->len - pos;
412  }
413  if (len)
414  {
415  buf->len = len;
416  free(buf->data); // fix!!!
417  buf->data = (char *) malloc(len + 1);
418  if(!buf->data)
419  {
420  buf->len = 0;
421  return *buf;
422  }
423  memcpy(buf->data, data+pos, len);
424  buf->data[len] = '\0';
425  }
426  return *buf;
427 }
428 
429 const char *String::c_str()
430 {
431  return data;
432 }
433 
434 String **String::split(const char *pattern)
435 {
436  unsigned int plen = strlen(pattern);
437  List < String * >res;
438  unsigned int start = 0;
439  if (plen > len)
440  return NULL;
441  for (unsigned int i = 0; i < len - plen;)
442  {
443  while (strncmp(data + i, pattern, plen) == 0 && i < len)
444  {
445  i += plen;
446  }
447  start = i;
448  while (strncmp(data + i, pattern, plen) && i < len)
449  {
450  i++;
451  }
452  if (i > start && i <= len)
453  {
454  res.pushDown(new(std::nothrow) String(data + start, i - start));
455  }
456  }
457  String **result = new(std::nothrow) String *[res.getCount() + 1];
458  if(result)
459  {
460  result[res.getCount()] = NULL;
461  for (unsigned int i = 0; i < res.getCount(); i++)
462  {
463  result[i] = res[i];
464  }
465  }
466  return result;
467 }
468 
469 void String::fromInt(int x)
470 {
471  char buf[15];
472  unsigned int count = 0;
473  if (data)
474  {
475  free(data);
476  data = (char *) malloc(15);
477  if(!data)
478  {
479  len = 0;
480  return;
481  }
482  }
483  len = 0;
484  char *numeric = data;
485  if (x < 0)
486  {
487  *numeric = '-';
488  numeric++;
489  x *= -1;
490  len = 1;
491  }
492  do
493  {
494  buf[count++] = (char) ((x % 10) + 0x30);
495  x /= 10;
496  }
497  while (x);
498  len += count;
499  while (count)
500  {
501  *numeric = buf[--count];
502  numeric++;
503  }
504  *numeric = '\0';
505 }
506 
507 void String::fromInt64(long long x)
508 {
509  char buf[21];
510  unsigned int count = 0;
511  if (data)
512  {
513  free(data);
514  data = (char *) malloc(21);
515  if(!data)
516  {
517  len = 0;
518  return;
519  }
520  }
521  len = 0;
522  char *numeric = data;
523  if (x < 0)
524  {
525  *numeric = '-';
526  numeric++;
527  x *= -1;
528  len = 1;
529  }
530  do
531  {
532  buf[count++] = (char) ((x % 10) + 0x30);
533  x /= 10;
534  }
535  while (x);
536  len += count;
537  while (count)
538  {
539  *numeric = buf[--count];
540  numeric++;
541  }
542  *numeric = '\0';
543 }
544 
545 void String::fromUInt(unsigned int x)
546 {
547  char buf[15];
548  unsigned int count = 0;
549  if (data)
550  {
551  free(data);
552  data = (char *) malloc(15);
553  if(!data)
554  {
555  len = 0;
556  return;
557  }
558  }
559  len = 0;
560  char *numeric = data;
561  do
562  {
563  buf[count++] = (char) ((x % 10) + 0x30);
564  x /= 10;
565  }
566  while (x);
567  len += count;
568  while (count)
569  {
570  *numeric = buf[--count];
571  numeric++;
572  }
573  *numeric = '\0';
574 }
575 
576 void String::fromUInt64(unsigned long long x)
577 {
578  char buf[21];
579  unsigned int count = 0;
580  if (data)
581  {
582  free(data);
583  data = (char *) malloc(21);
584  if(!data)
585  {
586  len = 0;
587  return;
588  }
589  }
590  len = 0;
591  char *numeric = data;
592  do
593  {
594  buf[count++] = (char) ((x % 10) + 0x30);
595  x /= 10;
596  }
597  while (x);
598  len += count;
599  while (count)
600  {
601  *numeric = buf[--count];
602  numeric++;
603  }
604  *numeric = '\0';
605 }
606 
607 
608 std::ostream & operator<<(std::ostream & out, String & str)
609 {
610  out << str.data;
611  return out;
612 }
613 
614 void String::implode(unsigned int count, const char *glue, ...)
615 {
616  va_list ap;
617  va_start(ap, glue);
618  char *str = NULL;
619  unsigned int slen = 0;
620  unsigned int glen = 0;
621  if (glue)
622  {
623  glen = strlen(glue);
624  }
625  if (len)
626  {
627  free(data);
628  len = 0;
629  data = (char *) malloc(1);
630  if(!data)
631  {
632  return;
633  }
634  }
635  while (count--)
636  {
637  str = va_arg(ap, char *);
638  slen = strlen(str);
639  if (count && glen)
640  {
641  data = (char *) realloc(data, len + slen + glen + 1);
642  if(!data)
643  {
644  len = 0;
645  return;
646  }
647  memcpy(data + len, str, slen);
648  memcpy(data + len + slen, glue, glen);
649  len += glen + slen;
650  }
651  else
652  {
653  data = (char *) realloc(data, len + slen + 1);
654  if(!data)
655  {
656  len = 0;
657  return;
658  }
659  memcpy(data + len, str, slen);
660  len += slen;
661  }
662  }
663  data[len] = '\0';
664  va_end(ap);
665 }
666 
667 void String::implode(const char *glue, char **str)
668 {
669  unsigned int slen = 0;
670  unsigned int glen = 0;
671  if (glue)
672  {
673  glen = strlen(glue);
674  }
675  if (len)
676  {
677  free(data);
678  len = 0;
679  data = (char *) malloc(1);
680  if(!data)
681  {
682  return;
683  }
684  }
685  while (str)
686  {
687  slen = strlen(*str);
688  if (str[1] && glen)
689  {
690  data = (char *) realloc(data, len + slen + glen + 1);
691  if(!data)
692  {
693  len = 0;
694  return;
695  }
696  memcpy(data + len, *str, slen);
697  memcpy(data + len + slen, glue, glen);
698  len += glen + slen;
699  }
700  else
701  {
702  data = (char *) realloc(data, len + slen + 1);
703  if(data)
704  {
705  len = 0;
706  return;
707  }
708  memcpy(data + len, *str, slen);
709  len += slen;
710  }
711  str++;
712  }
713  data[len] = '\0';
714 }
715 bool String::wildcmp(char *wild)
716 {
717  char *string = data;
718  char *cp, *mp;
719  while( (*string) && (*wild != '*'))
720  {
721  if( (*wild != *string) && (*wild != '?') )
722  {
723  return false;
724  }
725  wild++;
726  string++;
727  }
728  while(*string)
729  {
730  if(*wild == '*')
731  {
732  if(!*++wild)
733  {
734  return true;
735  }
736  mp = wild;
737  cp = string+1;
738  }
739  else
740  if( (*wild == *string) || (*wild == '?') )
741  {
742  wild++;
743  string++;
744  }
745  else
746  {
747  wild = mp;
748  string = cp++;
749  }
750  }
751  while( *wild == '*' )
752  {
753  wild++;
754  }
755  return *wild == '\0';
756 }
757 
758 bool String::wildcmp(String &pattern)
759 {
760  return this->wildcmp(pattern.data);
761 }
762 
763 unsigned int String::jsonEncode(const char *input, unsigned int len, char **result)
764 {
765  static char hexmap[] = "0123456789abcdef";
766  unsigned int outLen = 0;
767  u_int8_t *src = (u_int8_t*)input;
768  for(unsigned int i = 0; i < len; )
769  {
770  if(src[i] < 128)
771  {
772  switch(src[i])
773  {
774  case '"':
775  case '\\':
776  case '/':
777  case '\b':
778  case '\f':
779  case '\n':
780  case '\r':
781  case '\t':outLen += 2;break;
782  default: outLen++;
783  }
784  i++;
785  }
786  else
787  {
788  if((src[i] & 0xF0) == 0xF0) i += 4;
789  else if((src[i] & 0xE0) == 0xE0) i += 3;
790  else i += 2;
791  outLen += 6;
792  }
793  }
794  if(outLen)
795  {
796  char *dst = (char*)malloc(outLen + 1);
797  for(unsigned int i = 0, j = 0; i < len; )
798  {
799  if(src[i] < 128)
800  {
801  switch(src[i])
802  {
803  case '"':
804  dst[j++] = '\\';
805  dst[j++] = '"';
806  break;
807  case '\\':
808  dst[j++] = '\\';
809  dst[j++] = '\\';
810  break;
811  case '/':
812  dst[j++] = '\\';
813  dst[j++] = '/';
814  break;
815  case '\b':
816  dst[j++] = '\\';
817  dst[j++] = 'b';
818  break;
819  case '\f':
820  dst[j++] = '\\';
821  dst[j++] = 'f';
822  break;
823  case '\n':
824  dst[j++] = '\\';
825  dst[j++] = 'n';
826  break;
827  case '\r':
828  dst[j++] = '\\';
829  dst[j++] = 'r';
830  break;
831  case '\t':
832  dst[j++] = '\\';
833  dst[j++] = 't';
834  break;
835  default: dst[j++] = src[i];
836  }
837  i++;
838  }
839  else
840  {
841  if((src[i] & 0xF0) == 0xF0)
842  {//11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
843  i += 4;
844  }
845  else
846  {
847  u_int16_t symb = 0;
848  dst[j++] = '\\';
849  dst[j++] = 'u';
850  if((src[i] & 0xE0) == 0xE0)
851  {//1110xxxx 10xxxxxx 10xxxxxx
852  symb = ((src[i] & 0xF) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F);
853  i += 3;
854  }
855  else
856  {//110xxxxx 10xxxxxx
857  symb = ((src[i] & 0x1F) << 6) | (src[i + 1] & 0x3F);
858  i += 2;
859  }
860  dst[j++] = hexmap[(symb >> 12) & 0xf];
861  dst[j++] = hexmap[(symb >> 8) & 0xf];
862  dst[j++] = hexmap[(symb >> 4) & 0xf];
863  dst[j++] = hexmap[symb & 0xf];
864  }
865  }
866  }
867  dst[outLen] = '\0';
868  *result = dst;
869  }
870  return outLen;
871 }
873 {
874  if(len)
875  {
876  char *ret;
877  len = jsonEncode(data, len, &ret);
878  free(data);
879  data = ret;
880  }
881 }