1 /**
2 * String.cpp
3 * This file is part of the YATE Project http://YATE.null.ro
4 *
5 * Yet Another Telephony Engine - a fully featured software PBX and IVR
6 * Copyright (C) 2004-2014 Null Team
7 *
8 * This software is distributed under multiple licenses;
9 * see the COPYING file in the main directory for licensing
10 * information for this specific distribution.
11 *
12 * This use of this software may be subject to additional restrictions.
13 * See the LEGAL file in the main directory for details.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 #include "yateclass.h"
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <regex.h>
27
28 #if (defined(WORDS_BIGENDIAN) || defined(BIGENDIAN))
29 #define ENDIANNESS_NATIVE (UChar::BE)
30 #define ENDIANNESS_OPPOSITE (UChar::LE)
31 #else
32 #define ENDIANNESS_NATIVE (UChar::LE)
33 #define ENDIANNESS_OPPOSITE (UChar::BE)
34 #endif
35
36
37 namespace TelEngine {
38
39 // String to regular integer conversion, takes into account overflows
strtoi(const char * nptr,char ** endptr,int base)40 static int strtoi(const char* nptr, char** endptr, int base)
41 {
42 errno = 0;
43 long int val = ::strtol(nptr,endptr,base);
44 #if INT_MAX != LONG_MAX
45 if (val >= INT_MAX) {
46 errno = ERANGE;
47 val = INT_MAX;
48 }
49 else if (val <= INT_MIN) {
50 errno = ERANGE;
51 val = INT_MIN;
52 }
53 #endif
54 // on overflow/underflow mark the entire string as unreadable
55 if ((errno == ERANGE) && endptr)
56 *endptr = (char*) nptr;
57 return (int) val;
58 }
59
operator +(const String & s1,const String & s2)60 String operator+(const String& s1, const String& s2)
61 {
62 String s(s1.c_str());
63 s += s2.c_str();
64 return s;
65 }
66
operator +(const String & s1,const char * s2)67 String operator+(const String& s1, const char* s2)
68 {
69 String s(s1.c_str());
70 s += s2;
71 return s;
72 }
73
operator +(const char * s1,const String & s2)74 String operator+(const char* s1, const String& s2)
75 {
76 String s(s1);
77 s += s2;
78 return s;
79 }
80
lookup(const char * str,const TokenDict * tokens,int defvalue,int base)81 int lookup(const char* str, const TokenDict* tokens, int defvalue, int base)
82 {
83 if (!str)
84 return defvalue;
85 if (tokens) {
86 for (; tokens->token; tokens++)
87 if (!::strcmp(str,tokens->token))
88 return tokens->value;
89 }
90 char *eptr = 0;
91 int val = strtoi(str,&eptr,base);
92 if (!eptr || *eptr)
93 return defvalue;
94 return val;
95 }
96
lookup(int value,const TokenDict * tokens,const char * defvalue)97 const char* lookup(int value, const TokenDict* tokens, const char* defvalue)
98 {
99 if (tokens) {
100 for (; tokens->token; tokens++)
101 if (value == tokens->value)
102 return tokens->token;
103 }
104 return defvalue;
105 }
106
lookup(const char * str,const TokenDict64 * tokens,int64_t defvalue,int base)107 int64_t lookup(const char* str, const TokenDict64* tokens, int64_t defvalue, int base)
108 {
109 if (!str)
110 return defvalue;
111 if (tokens) {
112 for (; tokens->token; tokens++)
113 if (!::strcmp(str,tokens->token))
114 return tokens->value;
115 }
116 char* eptr = 0;
117 int64_t val = ::strtoll(str,&eptr,base);
118 if (!eptr || *eptr)
119 return defvalue;
120 return val;
121 }
122
lookup(int64_t value,const TokenDict64 * tokens,const char * defvalue)123 const char* lookup(int64_t value, const TokenDict64* tokens, const char* defvalue)
124 {
125 if (tokens) {
126 for (; tokens->token; tokens++)
127 if (value == tokens->value)
128 return tokens->token;
129 }
130 return defvalue;
131 }
132
133 #define MAX_MATCH 9
134
135 class StringMatchPrivate
136 {
137 public:
138 StringMatchPrivate();
139 void fixup();
140 void clear();
141 int count;
142 regmatch_t rmatch[MAX_MATCH+1];
143 };
144
145 };
146
147 using namespace TelEngine;
148
isWordBreak(char c,bool nullOk=false)149 static bool isWordBreak(char c, bool nullOk = false)
150 {
151 return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || (nullOk && !c));
152 }
153
154 // Decode a single nibble, return -1 on error
hexDecode(char c)155 static int hexDecode(char c)
156 {
157 if (('0' <= c) && (c <= '9'))
158 return c - '0';
159 if (('A' <= c) && (c <= 'F'))
160 return c - 'A' + 10;
161 if (('a' <= c) && (c <= 'f'))
162 return c - 'a' + 10;
163 return -1;
164 }
165
166 // Encode a single nibble
hexEncode(char nib)167 static inline char hexEncode(char nib)
168 {
169 static const char hex[] = "0123456789abcdef";
170 return hex[nib & 0x0f];
171 }
172
173
encode()174 void UChar::encode()
175 {
176 if (m_chr < 0x80) {
177 m_str[0] = (char)m_chr;
178 m_str[1] = '\0';
179 }
180 else if (m_chr < 0x800) {
181 m_str[0] = (char)(0xc0 | ((m_chr >> 6) & 0x1f));
182 m_str[1] = (char)(0x80 | (m_chr & 0x3f));
183 m_str[2] = '\0';
184 }
185 else if (m_chr < 0xffff) {
186 m_str[0] = (char)(0xe0 | ((m_chr >> 12) & 0x0f));
187 m_str[1] = (char)(0x80 | ((m_chr >> 6) & 0x3f));
188 m_str[2] = (char)(0x80 | (m_chr & 0x3f));
189 m_str[3] = '\0';
190 }
191 else if (m_chr < 0x1fffff) {
192 m_str[0] = (char)(0xf0 | ((m_chr >> 18) & 0x07));
193 m_str[1] = (char)(0x80 | ((m_chr >> 12) & 0x3f));
194 m_str[2] = (char)(0x80 | ((m_chr >> 6) & 0x3f));
195 m_str[3] = (char)(0x80 | (m_chr & 0x3f));
196 m_str[4] = '\0';
197 }
198 else if (m_chr < 0x3ffffff) {
199 m_str[0] = (char)(0xf8 | ((m_chr >> 24) & 0x03));
200 m_str[1] = (char)(0x80 | ((m_chr >> 18) & 0x3f));
201 m_str[2] = (char)(0x80 | ((m_chr >> 12) & 0x3f));
202 m_str[3] = (char)(0x80 | ((m_chr >> 6) & 0x3f));
203 m_str[4] = (char)(0x80 | (m_chr & 0x3f));
204 m_str[5] = '\0';
205 }
206 else if (m_chr < 0x7fffffff) {
207 m_str[0] = (char)(0xfc | ((m_chr >> 30) & 0x01));
208 m_str[1] = (char)(0x80 | ((m_chr >> 24) & 0x3f));
209 m_str[2] = (char)(0x80 | ((m_chr >> 18) & 0x3f));
210 m_str[3] = (char)(0x80 | ((m_chr >> 12) & 0x3f));
211 m_str[4] = (char)(0x80 | ((m_chr >> 6) & 0x3f));
212 m_str[5] = (char)(0x80 | (m_chr & 0x3f));
213 m_str[6] = '\0';
214 }
215 else
216 m_str[0] = '\0';
217 }
218
decode(const char * & str,uint32_t maxChar,bool overlong)219 bool UChar::decode(const char*& str, uint32_t maxChar, bool overlong)
220 {
221 operator=('\0');
222 if (!str)
223 return false;
224 if (maxChar < 128)
225 maxChar = 0x10ffff; // RFC 3629 default limit
226
227 unsigned int more = 0;
228 uint32_t min = 0;
229 uint32_t val = 0;
230
231 unsigned char c = (unsigned char)*str++;
232 // from 1st byte we find out how many are supposed to follow
233 if (!c) // don't advance past NUL
234 --str;
235 else if (c < 0x80) // 1 byte, 0...0x7F, ASCII characters
236 val = c & 0x7f;
237 else if (c < 0xc0) // invalid as first UFT-8 byte
238 return false;
239 else if (c < 0xe0) {
240 // 2 bytes, 0x80...0x7FF
241 min = 0x80;
242 val = c & 0x1f;
243 more = 1;
244 }
245 else if (c < 0xf0) {
246 // 3 bytes, 0x800...0xFFFF, Basic Multilingual Plane
247 min = 0x800;
248 val = c & 0x0f;
249 more = 2;
250 }
251 else if (c < 0xf8) {
252 // 4 bytes, 0x10000...0x1FFFFF, RFC 3629 limit (10FFFF)
253 min = 0x10000;
254 val = c & 0x07;
255 more = 3;
256 }
257 else if (c < 0xfc) {
258 // 5 bytes, 0x200000...0x3FFFFFF
259 min = 0x200000;
260 val = c & 0x03;
261 more = 4;
262 }
263 else if (c < 0xfe) {
264 // 6 bytes, 0x4000000...0x7FFFFFFF
265 min = 0x4000000;
266 val = c & 0x01;
267 more = 5;
268 }
269 else
270 return false;
271
272 while (more--) {
273 c = (unsigned char)*str;
274 // all continuation bytes are in range [128..191]
275 if ((c & 0xc0) != 0x80)
276 return false;
277 val = (val << 6) | (c & 0x3f);
278 ++str;
279 }
280 operator=(val);
281 // got full value, check for overlongs and out of range
282 if (val > maxChar)
283 return false;
284 if (val < min && !overlong)
285 return false;
286 return true;
287 }
288
swap_u16(uint16_t val,UChar::Endianness order)289 static inline uint16_t swap_u16(uint16_t val, UChar::Endianness order)
290 {
291 if (order < UChar::Native && ENDIANNESS_OPPOSITE == order)
292 val = ((val & 0xff00) >> 8) | ((val & 0x00ff) << 8);
293 return val;
294 }
295
decode(uint16_t * & buff,unsigned int & len,Endianness order,uint32_t maxChar)296 bool UChar::decode(uint16_t*& buff, unsigned int& len, Endianness order, uint32_t maxChar)
297 {
298 operator=('\0');
299 if (!(buff && len))
300 return false;
301 if (maxChar < 128)
302 maxChar = 0x10ffff; // RFC 3629 default limit
303 uint32_t val = swap_u16(*buff,order);
304 buff++;
305 len--;
306 if (val >= 0xD800 && val < 0xDC00 && len) { // High surrogate
307 uint16_t low = swap_u16(*buff,order);
308 if (low >= 0xDC00 && low <= 0xDFFF) {
309 buff++;
310 len--;
311 val = (low - 0xDC00) + (val - 0xD800) * 0x400 + 0x10000;
312 }
313 }
314 operator=(val);
315 if (code() > maxChar)
316 return false;
317 return true;
318 }
319
decode(DataBlock & buff,Endianness order,uint32_t maxChar)320 bool UChar::decode(DataBlock& buff, Endianness order, uint32_t maxChar)
321 {
322 operator=('\0');
323 unsigned int len = buff.length();
324 uint16_t* in = (uint16_t*) buff.data();
325 if (!len || (len & 1))
326 return false;
327 len = len >> 1;
328 if (!decode(in,len,order,maxChar))
329 return false;
330 buff.cut(-(int)(buff.length() - len * 2));
331 return true;
332 }
333
encode(uint16_t * & buff,unsigned int & len,Endianness order)334 bool UChar::encode(uint16_t*& buff, unsigned int& len, Endianness order)
335 {
336 if (!(buff && len && code() <= 0x10ffff))
337 return false;
338 XDebug(DebugAll,"UChar::encode() UTF-16, char=%s (%x), order=%u",c_str(),m_chr,order);
339 if (m_chr >= 0x10000) { // encode to surrogate pairs
340 if (len < 2)
341 return false; // not enough space to encode
342 *buff = swap_u16(((m_chr - 0x10000) >> 10) + 0xD800,order);
343 *(buff + 1) = swap_u16(((m_chr - 0x10000) & 0x3ff) + 0xDC00,order);
344 buff += 2;
345 len -=2;
346 }
347 else {
348 *buff = swap_u16(m_chr,order);
349 buff++;
350 len--;
351 }
352 return true;
353 }
354
encode(DataBlock & buff,Endianness order)355 bool UChar::encode(DataBlock& buff, Endianness order)
356 {
357 uint16_t b[2] = {0};
358 uint16_t* out = b;
359 unsigned int len = 2;
360 if (!encode(out,len,order))
361 return false;
362 buff.append(b,sizeof(uint16_t) * (2 - len));
363 return true;
364 }
365
decode(String & out,uint16_t * & buff,unsigned int & len,Endianness order,bool checkBOM,uint32_t maxChar)366 bool UChar::decode(String& out, uint16_t*& buff, unsigned int& len, Endianness order, bool checkBOM, uint32_t maxChar)
367 {
368 if (!(buff && len))
369 return false;
370 XDebug(DebugAll,"UChar::decode() UTF-16, out=%s, buff=%p, len=%u, order=%u, maxChar=%x",
371 out.c_str(),buff,len,order,maxChar);
372 if (checkBOM && (*buff == 0xfeff || *buff == 0xfffe)) {
373 if (*buff == 0xfeff) // same endianness
374 order = ENDIANNESS_NATIVE;
375 else
376 order = ENDIANNESS_OPPOSITE;
377 buff++;
378 len--;
379 }
380 while (buff && len) {
381 UChar c;
382 if (!c.decode(buff,len,(Endianness)order,maxChar))
383 return false;
384 out << c;
385 }
386 return true;
387 }
388
encode(DataBlock & out,const char * & str,Endianness order,bool addBOM)389 bool UChar::encode(DataBlock& out, const char*& str, Endianness order, bool addBOM)
390 {
391 XDebug(DebugAll,"UChar::encode() UTF-16, str=%s, order=%u, addBOM=%s",str,order,String::boolText(addBOM));
392 if (TelEngine::null(str))
393 return false;
394 if (addBOM) {
395 uint16_t bom = swap_u16(0xfeff,order);
396 out.append(&bom,2);
397 }
398 UChar c;
399 while (*str && c.decode(str)) {
400 if (!c.encode(out,order))
401 return false;
402 }
403 return true;
404 }
405
encode(uint16_t * & buff,unsigned int & len,const char * & str,Endianness order,bool addBOM)406 bool UChar::encode(uint16_t*& buff, unsigned int& len, const char*& str, Endianness order, bool addBOM)
407 {
408 if (TelEngine::null(str))
409 return false;
410 if (!(buff && len))
411 return false;
412 XDebug(DebugAll,"UChar::encode() UTF-16, buff=%p, len=%u, str=%s, order=%u, addBOM=%s",
413 buff,len,str,order,String::boolText(addBOM));
414 if (addBOM) {
415 uint16_t bom = swap_u16(0xfeff,order);
416 *buff = bom;
417 ++buff;
418 len--;
419 }
420 UChar c;
421 while (*str && c.decode(str)) {
422 if (!c.encode(buff,len,order))
423 return false;
424 }
425 return true;
426 }
427
428
StringMatchPrivate()429 StringMatchPrivate::StringMatchPrivate()
430 {
431 XDebug(DebugAll,"StringMatchPrivate::StringMatchPrivate() [%p]",this);
432 clear();
433 }
434
clear()435 void StringMatchPrivate::clear()
436 {
437 count = 0;
438 for (int i = 0; i <= MAX_MATCH; i++) {
439 rmatch[i].rm_so = -1;
440 rmatch[i].rm_eo = 0;
441 }
442 }
443
fixup()444 void StringMatchPrivate::fixup()
445 {
446 count = 0;
447 rmatch[0].rm_so = rmatch[1].rm_so;
448 rmatch[0].rm_eo = 0;
449 int i, c = 0;
450 for (i = 1; i <= MAX_MATCH; i++) {
451 if (rmatch[i].rm_so != -1) {
452 rmatch[0].rm_eo = rmatch[i].rm_eo - rmatch[0].rm_so;
453 rmatch[i].rm_eo -= rmatch[i].rm_so;
454 c = i;
455 }
456 else
457 rmatch[i].rm_eo = 0;
458 }
459 // Cope with the regexp stupidity.
460 if (c > 1) {
461 for (i = 0; i < c; i++)
462 rmatch[i] = rmatch[i+1];
463 rmatch[c].rm_so = -1;
464 c--;
465 }
466 count = c;
467 }
468
469
470 static const String s_empty;
471 static ObjList s_atoms;
472 static Mutex s_mutex(false,"Atom");
473
empty()474 const String& String::empty()
475 {
476 return s_empty;
477 }
478
String()479 String::String()
480 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
481 {
482 XDebug(DebugAll,"String::String() [%p]",this);
483 }
484
String(const char * value,int len)485 String::String(const char* value, int len)
486 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
487 {
488 XDebug(DebugAll,"String::String(\"%s\",%d) [%p]",value,len,this);
489 assign(value,len);
490 }
491
String(const String & value)492 String::String(const String& value)
493 : GenObject(),
494 m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
495 {
496 XDebug(DebugAll,"String::String(%p) [%p]",&value,this);
497 if (!value.null()) {
498 m_string = ::strdup(value.c_str());
499 if (!m_string)
500 Debug("String",DebugFail,"strdup() returned NULL!");
501 else
502 m_length = value.length();
503 changed();
504 }
505 }
506
String(char value,unsigned int repeat)507 String::String(char value, unsigned int repeat)
508 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
509 {
510 XDebug(DebugAll,"String::String('%c',%d) [%p]",value,repeat,this);
511 if (value && repeat) {
512 m_string = (char *) ::malloc(repeat+1);
513 if (m_string) {
514 ::memset(m_string,value,repeat);
515 m_string[repeat] = 0;
516 m_length = repeat;
517 }
518 else
519 Debug("String",DebugFail,"malloc(%d) returned NULL!",repeat+1);
520 changed();
521 }
522 }
523
String(int32_t value)524 String::String(int32_t value)
525 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
526 {
527 XDebug(DebugAll,"String::String(%d) [%p]",value,this);
528 char buf[16];
529 ::sprintf(buf,"%d",value);
530 m_string = ::strdup(buf);
531 if (!m_string)
532 Debug("String",DebugFail,"strdup() returned NULL!");
533 changed();
534 }
535
String(int64_t value)536 String::String(int64_t value)
537 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
538 {
539 XDebug(DebugAll,"String::String(" FMT64 ") [%p]",value,this);
540 char buf[24];
541 ::sprintf(buf,FMT64,value);
542 m_string = ::strdup(buf);
543 if (!m_string)
544 Debug("String",DebugFail,"strdup() returned NULL!");
545 changed();
546 }
547
String(uint32_t value)548 String::String(uint32_t value)
549 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
550 {
551 XDebug(DebugAll,"String::String(%u) [%p]",value,this);
552 char buf[16];
553 ::sprintf(buf,"%u",value);
554 m_string = ::strdup(buf);
555 if (!m_string)
556 Debug("String",DebugFail,"strdup() returned NULL!");
557 changed();
558 }
559
String(uint64_t value)560 String::String(uint64_t value)
561 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
562 {
563 XDebug(DebugAll,"String::String(" FMT64U ") [%p]",value,this);
564 char buf[24];
565 ::sprintf(buf,FMT64U,value);
566 m_string = ::strdup(buf);
567 if (!m_string)
568 Debug("String",DebugFail,"strdup() returned NULL!");
569 changed();
570 }
571
String(bool value)572 String::String(bool value)
573 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
574 {
575 XDebug(DebugAll,"String::String(%u) [%p]",value,this);
576 m_string = ::strdup(boolText(value));
577 if (!m_string)
578 Debug("String",DebugFail,"strdup() returned NULL!");
579 changed();
580 }
581
String(double value)582 String::String(double value)
583 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
584 {
585 XDebug(DebugAll,"String::String(%g) [%p]",value,this);
586 char buf[80];
587 ::sprintf(buf,"%g",value);
588 m_string = ::strdup(buf);
589 if (!m_string)
590 Debug("String",DebugFail,"strdup() returned NULL!");
591 changed();
592 }
593
String(const String * value)594 String::String(const String* value)
595 : m_string(0), m_length(0), m_hash(YSTRING_INIT_HASH), m_matches(0)
596 {
597 XDebug(DebugAll,"String::String(%p) [%p]",&value,this);
598 if (value && !value->null()) {
599 m_string = ::strdup(value->c_str());
600 if (!m_string)
601 Debug("String",DebugFail,"strdup() returned NULL!");
602 else
603 m_length = value->length();
604 changed();
605 }
606 }
607
~String()608 String::~String()
609 {
610 XDebug(DebugAll,"String::~String() [%p] (\"%s\")",this,m_string);
611 if (m_matches) {
612 StringMatchPrivate *odata = m_matches;
613 m_matches = 0;
614 delete odata;
615 }
616 if (m_string) {
617 char *odata = m_string;
618 m_length = 0;
619 m_string = 0;
620 ::free(odata);
621 }
622 }
623
assign(const char * value,int len)624 String& String::assign(const char* value, int len)
625 {
626 if (len && value && *value) {
627 if (len < 0)
628 len = ::strlen(value);
629 else {
630 int l = 0;
631 for (const char* p = value; l < len; l++)
632 if (!*p++)
633 break;
634 len = l;
635 }
636 if (value != m_string || len != (int)m_length) {
637 char* data = (char*) ::malloc(len+1);
638 if (data) {
639 ::memcpy(data,value,len);
640 data[len] = 0;
641 char* odata = m_string;
642 m_string = data;
643 m_length = len;
644 changed();
645 if (odata)
646 ::free(odata);
647 }
648 else
649 Debug("String",DebugFail,"malloc(%d) returned NULL!",len+1);
650 }
651 }
652 else
653 clear();
654 return *this;
655 }
656
assign(char value,unsigned int repeat)657 String& String::assign(char value, unsigned int repeat)
658 {
659 if (repeat && value) {
660 char* data = (char*) ::malloc(repeat+1);
661 if (data) {
662 ::memset(data,value,repeat);
663 data[repeat] = 0;
664 char* odata = m_string;
665 m_string = data;
666 m_length = repeat;
667 changed();
668 if (odata)
669 ::free(odata);
670 }
671 else
672 Debug("String",DebugFail,"malloc(%d) returned NULL!",repeat+1);
673 }
674 else
675 clear();
676 return *this;
677 }
678
hexify(void * data,unsigned int len,char sep,bool upCase)679 String& String::hexify(void* data, unsigned int len, char sep, bool upCase)
680 {
681 const char* hex = upCase ? "0123456789ABCDEF" : "0123456789abcdef";
682 if (data && len) {
683 const unsigned char* s = (const unsigned char*) data;
684 unsigned int repeat = sep ? 3*len-1 : 2*len;
685 // I know it's ugly to reuse but... copy/paste...
686 char* data = (char*) ::malloc(repeat+1);
687 if (data) {
688 char* d = data;
689 while (len--) {
690 unsigned char c = *s++;
691 *d++ = hex[(c >> 4) & 0x0f];
692 *d++ = hex[c & 0x0f];
693 if (sep)
694 *d++ = sep;
695 }
696 // wrote one too many - go back...
697 if (sep)
698 d--;
699 *d = '\0';
700 char* odata = m_string;
701 m_string = data;
702 m_length = repeat;
703 changed();
704 if (odata)
705 ::free(odata);
706 }
707 else
708 Debug("String",DebugFail,"malloc(%d) returned NULL!",repeat+1);
709 }
710 else
711 clear();
712 return *this;
713 }
714
changed()715 void String::changed()
716 {
717 clearMatches();
718 m_hash = YSTRING_INIT_HASH;
719 if (!m_string)
720 m_length = 0;
721 else if (!m_length)
722 m_length = ::strlen(m_string);
723 }
724
clear()725 void String::clear()
726 {
727 if (m_string) {
728 char *odata = m_string;
729 m_string = 0;
730 changed();
731 ::free(odata);
732 }
733 }
734
at(int index) const735 char String::at(int index) const
736 {
737 if ((index < 0) || ((unsigned)index >= m_length) || !m_string)
738 return 0;
739 return m_string[index];
740 }
741
substr(int offs,int len) const742 String String::substr(int offs, int len) const
743 {
744 if (offs < 0) {
745 offs += m_length;
746 if (offs < 0)
747 offs = 0;
748 }
749 if ((unsigned int)offs >= m_length)
750 return String();
751 return String(c_str()+offs,len);
752 }
753
toInteger(int defvalue,int base,int minvalue,int maxvalue,bool clamp) const754 int String::toInteger(int defvalue, int base, int minvalue, int maxvalue,
755 bool clamp) const
756 {
757 if (!m_string)
758 return defvalue;
759 char *eptr = 0;
760 int val = strtoi(m_string,&eptr,base);
761 if (!eptr || *eptr)
762 return defvalue;
763 if (val >= minvalue && val <= maxvalue)
764 return val;
765 if (clamp)
766 return (val < minvalue) ? minvalue : maxvalue;
767 return defvalue;
768 }
769
toInteger(const TokenDict * tokens,int defvalue,int base) const770 int String::toInteger(const TokenDict* tokens, int defvalue, int base) const
771 {
772 if (!m_string)
773 return defvalue;
774 if (tokens) {
775 for (; tokens->token; tokens++)
776 if (operator==(tokens->token))
777 return tokens->value;
778 }
779 return toInteger(defvalue,base);
780 }
781
toLong(long int defvalue,int base,long int minvalue,long int maxvalue,bool clamp) const782 long int String::toLong(long int defvalue, int base, long int minvalue, long int maxvalue,
783 bool clamp) const
784 {
785 if (!m_string)
786 return defvalue;
787 char *eptr = 0;
788
789 errno = 0;
790 long int val = ::strtol(m_string,&eptr,base);
791 // on overflow/underflow mark the entire string as unreadable
792 if ((errno == ERANGE) && eptr)
793 eptr = m_string;
794 if (!eptr || *eptr)
795 return defvalue;
796 if (val >= minvalue && val <= maxvalue)
797 return val;
798 if (clamp)
799 return (val < minvalue) ? minvalue : maxvalue;
800 return defvalue;
801 }
802
toInt64(int64_t defvalue,int base,int64_t minvalue,int64_t maxvalue,bool clamp) const803 int64_t String::toInt64(int64_t defvalue, int base, int64_t minvalue, int64_t maxvalue,
804 bool clamp) const
805 {
806 if (!m_string)
807 return defvalue;
808 char *eptr = 0;
809
810 errno = 0;
811 int64_t val = ::strtoll(m_string,&eptr,base);
812 // on overflow/underflow mark the entire string as unreadable
813 if ((errno == ERANGE) && eptr)
814 eptr = m_string;
815 if (!eptr || *eptr)
816 return defvalue;
817 if (val >= minvalue && val <= maxvalue)
818 return val;
819 if (clamp)
820 return (val < minvalue) ? minvalue : maxvalue;
821 return defvalue;
822 }
823
toUInt64(uint64_t defvalue,int base,uint64_t minvalue,uint64_t maxvalue,bool clamp) const824 uint64_t String::toUInt64(uint64_t defvalue, int base, uint64_t minvalue, uint64_t maxvalue,
825 bool clamp) const
826 {
827 if (!m_string)
828 return defvalue;
829 char *eptr = 0;
830
831 errno = 0;
832 uint64_t val = ::strtoull(m_string,&eptr,base);
833 // on overflow/underflow mark the entire string as unreadable
834 if ((errno == ERANGE) && eptr)
835 eptr = m_string;
836 if (!eptr || *eptr)
837 return defvalue;
838 if (val >= minvalue && val <= maxvalue)
839 return val;
840 if (clamp)
841 return (val < minvalue) ? minvalue : maxvalue;
842 return defvalue;
843 }
844
toDouble(double defvalue) const845 double String::toDouble(double defvalue) const
846 {
847 if (!m_string)
848 return defvalue;
849 char *eptr = 0;
850 double val= ::strtod(m_string,&eptr);
851 if (!eptr || *eptr)
852 return defvalue;
853 return val;
854 }
855
856 static const char* str_false[] = { "false", "no", "off", "disable", "f", 0 };
857 static const char* str_true[] = { "true", "yes", "on", "enable", "t", 0 };
858
toBoolean(bool defvalue) const859 bool String::toBoolean(bool defvalue) const
860 {
861 if (!m_string)
862 return defvalue;
863 const char **test;
864 for (test=str_false; *test; test++)
865 if (!::strcmp(m_string,*test))
866 return false;
867 for (test=str_true; *test; test++)
868 if (!::strcmp(m_string,*test))
869 return true;
870 return defvalue;
871 }
872
isBoolean() const873 bool String::isBoolean() const
874 {
875 if (!m_string)
876 return false;
877 const char **test;
878 for (test=str_false; *test; test++)
879 if (!::strcmp(m_string,*test))
880 return true;
881 for (test=str_true; *test; test++)
882 if (!::strcmp(m_string,*test))
883 return true;
884 return false;
885 }
886
toUpper()887 String& String::toUpper()
888 {
889 if (m_string) {
890 char c;
891 for (char *s = m_string; (c = *s); s++) {
892 if (('a' <= c) && (c <= 'z'))
893 *s = c + 'A' - 'a';
894 }
895 }
896 return *this;
897 }
898
toLower()899 String& String::toLower()
900 {
901 if (m_string) {
902 char c;
903 for (char *s = m_string; (c = *s); s++) {
904 if (('A' <= c) && (c <= 'Z'))
905 *s = c + 'a' - 'A';
906 }
907 }
908 return *this;
909 }
910
trimBlanks()911 String& String::trimBlanks()
912 {
913 if (m_string) {
914 const char *s = m_string;
915 while (*s == ' ' || *s == '\t')
916 s++;
917 const char *e = s;
918 for (const char *p = e; *p; p++)
919 if (*p != ' ' && *p != '\t')
920 e = p+1;
921 assign(s,e-s);
922 }
923 return *this;
924 }
925
trimSpaces()926 String& String::trimSpaces()
927 {
928 if (m_string) {
929 const char *s = m_string;
930 while (*s == ' ' || *s == '\t' || *s == '\v' || *s == '\f' || *s == '\r' || *s == '\n')
931 s++;
932 const char *e = s;
933 for (const char *p = e; *p; p++)
934 if (*p != ' ' && *p != '\t' && *p != '\v' && *p != '\f' && *p != '\r' && *p != '\n')
935 e = p+1;
936 assign(s,e-s);
937 }
938 return *this;
939 }
940
operator =(const char * value)941 String& String::operator=(const char* value)
942 {
943 if (value && !*value)
944 value = 0;
945 if (value != c_str()) {
946 char *tmp = m_string;
947 m_string = value ? ::strdup(value) : 0;
948 m_length = 0;
949 if (value && !m_string)
950 Debug("String",DebugFail,"strdup() returned NULL!");
951 changed();
952 if (tmp)
953 ::free(tmp);
954 }
955 return *this;
956 }
957
operator =(char value)958 String& String::operator=(char value)
959 {
960 char buf[2] = {value,0};
961 return operator=(buf);
962 }
963
operator =(int32_t value)964 String& String::operator=(int32_t value)
965 {
966 char buf[16];
967 ::sprintf(buf,"%d",value);
968 return operator=(buf);
969 }
970
operator =(uint32_t value)971 String& String::operator=(uint32_t value)
972 {
973 char buf[16];
974 ::sprintf(buf,"%u",value);
975 return operator=(buf);
976 }
977
operator =(int64_t value)978 String& String::operator=(int64_t value)
979 {
980 char buf[24];
981 ::sprintf(buf,FMT64,value);
982 return operator=(buf);
983 }
984
operator =(uint64_t value)985 String& String::operator=(uint64_t value)
986 {
987 char buf[24];
988 ::sprintf(buf,FMT64U,value);
989 return operator=(buf);
990 }
991
operator =(double value)992 String& String::operator=(double value)
993 {
994 char buf[80];
995 ::sprintf(buf,"%g",value);
996 return operator=(buf);
997 }
998
operator +=(char value)999 String& String::operator+=(char value)
1000 {
1001 char buf[2] = {value,0};
1002 return operator+=(buf);
1003 }
1004
operator +=(int32_t value)1005 String& String::operator+=(int32_t value)
1006 {
1007 char buf[16];
1008 ::sprintf(buf,"%d",value);
1009 return operator+=(buf);
1010 }
1011
operator +=(uint32_t value)1012 String& String::operator+=(uint32_t value)
1013 {
1014 char buf[16];
1015 ::sprintf(buf,"%u",value);
1016 return operator+=(buf);
1017 }
1018
operator +=(int64_t value)1019 String& String::operator+=(int64_t value)
1020 {
1021 char buf[24];
1022 ::sprintf(buf,FMT64,value);
1023 return operator+=(buf);
1024 }
1025
operator +=(uint64_t value)1026 String& String::operator+=(uint64_t value)
1027 {
1028 char buf[24];
1029 ::sprintf(buf,FMT64U,value);
1030 return operator+=(buf);
1031 }
1032
operator +=(double value)1033 String& String::operator+=(double value)
1034 {
1035 char buf[80];
1036 ::sprintf(buf,"%g",value);
1037 return operator+=(buf);
1038 }
1039
operator >>(const char * skip)1040 String& String::operator>>(const char* skip)
1041 {
1042 if (m_string && skip && *skip) {
1043 const char *loc = ::strstr(m_string,skip);
1044 if (loc)
1045 assign(loc+::strlen(skip));
1046 }
1047 return *this;
1048 }
1049
operator >>(char & store)1050 String& String::operator>>(char& store)
1051 {
1052 if (m_string) {
1053 store = m_string[0];
1054 assign(m_string+1);
1055 }
1056 return *this;
1057 }
1058
operator >>(UChar & store)1059 String& String::operator>>(UChar& store)
1060 {
1061 const char* str = m_string;
1062 store.decode(str);
1063 assign(str);
1064 return *this;
1065 }
1066
operator >>(int & store)1067 String& String::operator>>(int& store)
1068 {
1069 if (m_string) {
1070 char *end = 0;
1071 int l = strtoi(m_string,&end,0);
1072 if (end && (m_string != end)) {
1073 store = l;
1074 assign(end);
1075 }
1076 }
1077 return *this;
1078 }
1079
operator >>(unsigned int & store)1080 String& String::operator>>(unsigned int& store)
1081 {
1082 if (m_string) {
1083 char *end = 0;
1084 errno = 0;
1085 unsigned long int l = ::strtoul(m_string,&end,0);
1086 #if UINT_MAX != ULONG_MAX
1087 if (l > UINT_MAX) {
1088 l = UINT_MAX;
1089 errno = ERANGE;
1090 }
1091 #endif
1092 if (!errno && end && (m_string != end)) {
1093 store = l;
1094 assign(end);
1095 }
1096 }
1097 return *this;
1098 }
1099
operator >>(bool & store)1100 String& String::operator>>(bool& store)
1101 {
1102 if (m_string) {
1103 const char *s = m_string;
1104 while (*s == ' ' || *s == '\t')
1105 s++;
1106 const char **test;
1107 for (test=str_false; *test; test++) {
1108 int l = ::strlen(*test);
1109 if (!::strncmp(s,*test,l) && isWordBreak(s[l],true)) {
1110 store = false;
1111 assign(s+l);
1112 return *this;
1113 }
1114 }
1115 for (test=str_true; *test; test++) {
1116 int l = ::strlen(*test);
1117 if (!::strncmp(s,*test,l) && isWordBreak(s[l],true)) {
1118 store = true;
1119 assign(s+l);
1120 return *this;
1121 }
1122 }
1123 }
1124 return *this;
1125 }
1126
append(const char * value,int len)1127 String& String::append(const char* value, int len)
1128 {
1129 if (len && value && *value) {
1130 if (len < 0) {
1131 if (!m_string) {
1132 m_string = ::strdup(value);
1133 m_length = 0;
1134 if (!m_string)
1135 Debug("String",DebugFail,"strdup() returned NULL!");
1136 changed();
1137 return *this;
1138 }
1139 len = ::strlen(value);
1140 }
1141 int olen = length();
1142 len += olen;
1143 char *tmp1 = m_string;
1144 char *tmp2 = (char *) ::malloc(len+1);
1145 if (tmp2) {
1146 if (m_string)
1147 ::strncpy(tmp2,m_string,olen);
1148 ::strncpy(tmp2+olen,value,len-olen);
1149 tmp2[len] = 0;
1150 m_string = tmp2;
1151 m_length = len;
1152 ::free(tmp1);
1153 }
1154 else
1155 Debug("String",DebugFail,"malloc(%d) returned NULL!",len+1);
1156 changed();
1157 }
1158 return *this;
1159 }
1160
append(const char * value,const char * separator,bool force)1161 String& String::append(const char* value, const char* separator, bool force)
1162 {
1163 if (value || force) {
1164 if (!null())
1165 operator+=(separator);
1166 operator+=(value);
1167 }
1168 return *this;
1169 }
1170
append(const ObjList * list,const char * separator,bool force)1171 String& String::append(const ObjList* list, const char* separator, bool force)
1172 {
1173 if (!list)
1174 return *this;
1175 int olen = length();
1176 int sepLen = 0;
1177 if (!TelEngine::null(separator))
1178 sepLen = ::strlen(separator);
1179 int len = 0;
1180 for (ObjList* o = list->skipNull(); o; o = o->skipNext()) {
1181 const String& src = o->get()->toString();
1182 if (sepLen && (len || olen) && (src.length() || force))
1183 len += sepLen;
1184 len += src.length();
1185 }
1186 if (!len)
1187 return *this;
1188 char* oldStr = m_string;
1189 char* newStr = (char*)::malloc(olen + len + 1);
1190 if (!newStr) {
1191 Debug("String",DebugFail,"malloc(%d) returned NULL!",olen + len + 1);
1192 return *this;
1193 }
1194 if (m_string)
1195 ::memcpy(newStr,m_string,olen);
1196 for (list = list->skipNull(); list; list = list->skipNext()) {
1197 const String& src = list->get()->toString();
1198 if (sepLen && olen && (src.length() || force)) {
1199 ::memcpy(newStr + olen,separator,sepLen);
1200 olen += sepLen;
1201 }
1202 ::memcpy(newStr + olen,src.c_str(),src.length());
1203 olen += src.length();
1204 }
1205 newStr[olen] = 0;
1206 m_string = newStr;
1207 m_length = olen;
1208 ::free(oldStr);
1209 changed();
1210 return *this;
1211 }
1212
append(double value,unsigned int decimals)1213 String& String::append(double value, unsigned int decimals)
1214 {
1215 if (decimals > 12)
1216 decimals = 12;
1217 char buf[80];
1218 ::sprintf(buf,"%0.*f",decimals,value);
1219 return operator+=(buf);
1220 }
1221
string_printf(unsigned int & length,const char * format,va_list & va)1222 static char* string_printf(unsigned int& length, const char* format, va_list& va)
1223 {
1224 if (TelEngine::null(format) || !length)
1225 return 0;
1226 char* buf = (char*)::malloc(length + 1);
1227 if (!buf) {
1228 Debug("String",DebugFail,"malloc(%d) returned NULL!",length);
1229 return 0;
1230 }
1231 // Remember vsnprintf:
1232 // standard:
1233 // - buffer size and returned value include the terminating NULL char
1234 // - returns -1 on error
1235 // Windows:
1236 // - it doesn't write terminating NULL if there is no space
1237 // - returns -1 on error or buffer length is less than number of bytes to write
1238 // - returned value doesn't include the terminating NULL char (even if it was written to output)
1239 buf[length] = 0;
1240 #ifdef _WINDOWS
1241 errno = 0;
1242 int len = ::vsnprintf(buf,length,format,va);
1243 #else
1244 int len = ::vsnprintf(buf,length + 1,format,va);
1245 #endif
1246 if (len < 0) {
1247 #ifdef _WINDOWS
1248 if (errno == ERANGE) {
1249 XDebug("String",DebugCrit,"string_printf() incomplete write");
1250 buf[length] = 0;
1251 length = 0;
1252 return buf;
1253 }
1254 #endif
1255 ::free(buf);
1256 Debug("String",DebugCrit,"string_printf(): vsnprintf() failed!");
1257 return 0;
1258 }
1259 if (len < (int)length)
1260 length = len;
1261 #ifdef XDEBUG
1262 else if (len > (int)length || buf[len])
1263 Debug("String",DebugCrit,"string_printf() incomplete write");
1264 #endif
1265 buf[length] = 0;
1266 return buf;
1267 }
1268
printf(unsigned int length,const char * format,...)1269 String& String::printf(unsigned int length, const char* format, ...)
1270 {
1271 va_list va;
1272 va_start(va,format);
1273 char* buf = string_printf(length,format,va);
1274 va_end(va);
1275 if (!buf) {
1276 clear();
1277 return *this;
1278 }
1279 char* old = m_string;
1280 m_string = buf;
1281 m_length = length;
1282 ::free(old);
1283 changed();
1284 return *this;
1285 }
1286
printf(const char * format,...)1287 String& String::printf(const char* format, ...)
1288 {
1289 va_list va;
1290 va_start(va,format);
1291 unsigned int len = TelEngine::null(format) ? 0 : (128 + ::strlen(format));
1292 char* buf = string_printf(len,format,va);
1293 va_end(va);
1294 if (!buf) {
1295 clear();
1296 return *this;
1297 }
1298 char* old = m_string;
1299 m_string = buf;
1300 m_length = len;
1301 ::free(old);
1302 changed();
1303 return *this;
1304 }
1305
appendFixed(unsigned int fixedLength,const char * str,unsigned int len,char fill,int align)1306 String& String::appendFixed(unsigned int fixedLength, const char* str, unsigned int len, char fill, int align)
1307 {
1308 if (len == (unsigned int)-1)
1309 len = ::strlen(str);
1310 if (!str || len == 0)
1311 return *this;
1312 int alignPos = 0;
1313 if (len < fixedLength) {
1314 if (align == Center)
1315 alignPos = fixedLength / 2 - len / 2;
1316 else if (align == Right)
1317 alignPos = fixedLength - len;
1318 } else
1319 len = fixedLength;
1320 char* buf = (char*)::malloc(fixedLength + 1);
1321 if (!buf) {
1322 Debug("String",DebugFail,"malloc(%d) returned NULL!",fixedLength + 1);
1323 return *this;
1324 }
1325 ::memset(buf,fill,fixedLength);
1326 ::memcpy(buf + alignPos,str,len);
1327 buf[fixedLength] = 0;
1328 operator+=(buf);
1329 ::free(buf);
1330 return *this;
1331 }
1332
operator ==(const char * value) const1333 bool String::operator==(const char* value) const
1334 {
1335 if (!m_string)
1336 return !(value && *value);
1337 return value && !::strcmp(m_string,value);
1338 }
1339
operator !=(const char * value) const1340 bool String::operator!=(const char* value) const
1341 {
1342 if (!m_string)
1343 return value && *value;
1344 return (!value) || ::strcmp(m_string,value);
1345 }
1346
operator &=(const char * value) const1347 bool String::operator&=(const char* value) const
1348 {
1349 if (!m_string)
1350 return !(value && *value);
1351 return value && !::strcasecmp(m_string,value);
1352 }
1353
operator |=(const char * value) const1354 bool String::operator|=(const char* value) const
1355 {
1356 if (!m_string)
1357 return value && *value;
1358 return (!value) || ::strcasecmp(m_string,value);
1359 }
1360
find(char what,unsigned int offs) const1361 int String::find(char what, unsigned int offs) const
1362 {
1363 if (!m_string || (offs > m_length))
1364 return -1;
1365 const char *s = ::strchr(m_string+offs,what);
1366 return s ? s-m_string : -1;
1367 }
1368
find(const char * what,unsigned int offs) const1369 int String::find(const char* what, unsigned int offs) const
1370 {
1371 if (!(m_string && what && *what) || (offs > m_length))
1372 return -1;
1373 const char *s = ::strstr(m_string+offs,what);
1374 return s ? s-m_string : -1;
1375 }
1376
rfind(char what) const1377 int String::rfind(char what) const
1378 {
1379 if (!m_string)
1380 return -1;
1381 const char *s = ::strrchr(m_string,what);
1382 return s ? s-m_string : -1;
1383 }
1384
rfind(const char * what) const1385 int String::rfind(const char* what) const
1386 {
1387 int ret = -1;
1388 for (int pos = -1; (pos = find(what,pos + 1)) >= 0;)
1389 ret = pos;
1390 return ret;
1391 }
1392
startsWith(const char * what,bool wordBreak,bool caseInsensitive) const1393 bool String::startsWith(const char* what, bool wordBreak, bool caseInsensitive) const
1394 {
1395 if (!(m_string && what && *what))
1396 return false;
1397 unsigned int l = ::strlen(what);
1398 if (m_length < l)
1399 return false;
1400 else if (wordBreak && (m_length > l) && !isWordBreak(m_string[l]))
1401 return false;
1402
1403 if (caseInsensitive)
1404 return (::strncasecmp(m_string,what,l) == 0);
1405 return (::strncmp(m_string,what,l) == 0);
1406 }
1407
startSkip(const char * what,bool wordBreak,bool caseInsensitive)1408 bool String::startSkip(const char* what, bool wordBreak, bool caseInsensitive)
1409 {
1410 if (startsWith(what,wordBreak,caseInsensitive)) {
1411 const char *p = m_string + ::strlen(what);
1412 if (wordBreak)
1413 while (isWordBreak(*p))
1414 p++;
1415 assign(p);
1416 return true;
1417 }
1418 return false;
1419 }
1420
endsWith(const char * what,bool wordBreak,bool caseInsensitive) const1421 bool String::endsWith(const char* what, bool wordBreak, bool caseInsensitive) const
1422 {
1423 if (!(m_string && what && *what))
1424 return false;
1425 unsigned int l = ::strlen(what);
1426 if (m_length < l)
1427 return false;
1428 else if (wordBreak && (m_length > l) && !isWordBreak(m_string[m_length-l-1]))
1429 return false;
1430 if (caseInsensitive)
1431 return (::strncasecmp(m_string+m_length-l,what,l) == 0);
1432 return (::strncmp(m_string+m_length-l,what,l) == 0);
1433 }
1434
extractTo(const char * sep,String & str)1435 String& String::extractTo(const char* sep, String& str)
1436 {
1437 int pos = find(sep);
1438 if (pos >= 0) {
1439 str = substr(0,pos);
1440 assign(m_string+pos+::strlen(sep));
1441 }
1442 else {
1443 str = *this;
1444 clear();
1445 }
1446 return *this;
1447 }
1448
extractTo(const char * sep,bool & store)1449 String& String::extractTo(const char* sep, bool& store)
1450 {
1451 String str;
1452 extractTo(sep,str);
1453 store = str.toBoolean(store);
1454 return *this;
1455 }
1456
extractTo(const char * sep,int & store,int base)1457 String& String::extractTo(const char* sep, int& store, int base)
1458 {
1459 String str;
1460 extractTo(sep,str);
1461 store = str.toInteger(store,base);
1462 return *this;
1463 }
1464
extractTo(const char * sep,int & store,const TokenDict * tokens,int base)1465 String& String::extractTo(const char* sep, int& store, const TokenDict* tokens, int base)
1466 {
1467 String str;
1468 extractTo(sep,str);
1469 store = str.toInteger(tokens,store,base);
1470 return *this;
1471 }
1472
extractTo(const char * sep,double & store)1473 String& String::extractTo(const char* sep, double& store)
1474 {
1475 String str;
1476 extractTo(sep,str);
1477 store = str.toDouble(store);
1478 return *this;
1479 }
1480
matches(const Regexp & rexp)1481 bool String::matches(const Regexp& rexp)
1482 {
1483 if (m_matches)
1484 clearMatches();
1485 else
1486 m_matches = new StringMatchPrivate;
1487 if (rexp.matches(c_str(),m_matches)) {
1488 m_matches->fixup();
1489 return true;
1490 }
1491 return false;
1492 }
1493
matchOffset(int index) const1494 int String::matchOffset(int index) const
1495 {
1496 if ((!m_matches) || (index < 0) || (index > m_matches->count))
1497 return -1;
1498 return m_matches->rmatch[index].rm_so;
1499 }
1500
matchLength(int index) const1501 int String::matchLength(int index) const
1502 {
1503 if ((!m_matches) || (index < 0) || (index > m_matches->count))
1504 return 0;
1505 return m_matches->rmatch[index].rm_eo;
1506 }
1507
matchCount() const1508 int String::matchCount() const
1509 {
1510 if (!m_matches)
1511 return 0;
1512 return m_matches->count;
1513 }
1514
replaceMatches(const String & templ) const1515 String String::replaceMatches(const String& templ) const
1516 {
1517 String s;
1518 int pos, ofs = 0;
1519 for (;;) {
1520 pos = templ.find('\\',ofs);
1521 if (pos < 0) {
1522 s << templ.substr(ofs);
1523 break;
1524 }
1525 s << templ.substr(ofs,pos-ofs);
1526 pos++;
1527 char c = templ[pos];
1528 if (c == '\\') {
1529 pos++;
1530 s << "\\";
1531 }
1532 else if ('0' <= c && c <= '9') {
1533 pos++;
1534 s << matchString(c - '0');
1535 }
1536 else {
1537 pos++;
1538 s << "\\" << c;
1539 }
1540 ofs = pos;
1541 }
1542 return s;
1543 }
1544
clearMatches()1545 void String::clearMatches()
1546 {
1547 if (m_matches)
1548 m_matches->clear();
1549 }
1550
split(char separator,bool emptyOK) const1551 ObjList* String::split(char separator, bool emptyOK) const
1552 {
1553 ObjList* list = new ObjList;
1554 ObjList* dest = list;
1555 int p = 0;
1556 int s;
1557 while ((s = find(separator,p)) >= 0) {
1558 if (emptyOK || (s > p))
1559 dest = dest->append(new String(m_string+p,s-p));
1560 p = s + 1;
1561 }
1562 if (emptyOK || (m_string && m_string[p]))
1563 dest->append(new String(m_string+p));
1564 return list;
1565 }
1566
split(const Regexp & reg,bool emptyOK) const1567 ObjList* String::split(const Regexp& reg, bool emptyOK) const
1568 {
1569 String s = *this;
1570 ObjList* list = new ObjList;
1571 ObjList* dest = list;
1572 while (true) {
1573 if (!(s && s.matches(reg))) {
1574 if (s || emptyOK)
1575 dest = dest->append(new String(s));
1576 break;
1577 }
1578 int pos = s.matchOffset(0);
1579 if (emptyOK || pos > 0)
1580 dest = dest->append(new String(s.c_str(),pos));
1581 s = s.substr(pos + s.matchLength(0));
1582 }
1583 return list;
1584 }
1585
msgEscape(const char * str,char extraEsc)1586 String String::msgEscape(const char* str, char extraEsc)
1587 {
1588 String s;
1589 if (TelEngine::null(str))
1590 return s;
1591 char c;
1592 const char* pos = str;
1593 char buff[3] = {'%', '%', '\0'};
1594 while ((c=*pos++)) {
1595 if ((unsigned char)c < ' ' || c == ':' || c == extraEsc)
1596 c += '@';
1597 else if (c != '%')
1598 continue;
1599 buff[1] = c;
1600 s.append(str,pos - str - 1);
1601 s += buff;
1602 str = pos;
1603 }
1604 s += str;
1605 return s;
1606 }
1607
msgUnescape(const char * str,int * errptr,char extraEsc)1608 String String::msgUnescape(const char* str, int* errptr, char extraEsc)
1609 {
1610 String s;
1611 if (TelEngine::null(str))
1612 return s;
1613 if (extraEsc)
1614 extraEsc += '@';
1615 const char *pos = str;
1616 char c;
1617 while ((c=*pos++)) {
1618 if ((unsigned char)c < ' ') {
1619 if (errptr)
1620 *errptr = (pos-str) - 1;
1621 s.append(str,pos - str - 1);
1622 return s;
1623 }
1624 else if (c == '%') {
1625 c=*pos++;
1626 if ((c > '@' && c <= '_') || c == 'z' || c == extraEsc)
1627 c -= '@';
1628 else if (c != '%') {
1629 if (errptr)
1630 *errptr = (pos-str) - 1;
1631 s.append(str,pos - str - 1);
1632 return s;
1633 }
1634 s.append(str,pos - str - 2);
1635 s += c;
1636 str = pos;
1637 }
1638 }
1639 s += str;
1640 if (errptr)
1641 *errptr = -1;
1642 return s;
1643 }
1644
sqlEscape(const char * str,char extraEsc)1645 String String::sqlEscape(const char* str, char extraEsc)
1646 {
1647 String s;
1648 if (TelEngine::null(str))
1649 return s;
1650 char c;
1651 while ((c=*str++)) {
1652 if (c == '\'')
1653 s += "'";
1654 else if (c == '\\' || c == extraEsc)
1655 s += "\\";
1656 s += c;
1657 }
1658 return s;
1659 }
1660
uriEscape(const char * str,char extraEsc,const char * noEsc)1661 String String::uriEscape(const char* str, char extraEsc, const char* noEsc)
1662 {
1663 String s;
1664 if (TelEngine::null(str))
1665 return s;
1666 char c;
1667 while ((c=*str++)) {
1668 if ((unsigned char)c < ' ' || c == '%' || c == extraEsc ||
1669 ((c == ' ' || c == '+' || c == '?' || c == '&') && !(noEsc && ::strchr(noEsc,c))))
1670 s << '%' << hexEncode(c >> 4) << hexEncode(c);
1671 else
1672 s += c;
1673 }
1674 return s;
1675 }
1676
uriEscape(const char * str,const char * extraEsc,const char * noEsc)1677 String String::uriEscape(const char* str, const char* extraEsc, const char* noEsc)
1678 {
1679 String s;
1680 if (TelEngine::null(str))
1681 return s;
1682 char c;
1683 while ((c=*str++)) {
1684 if ((unsigned char)c < ' ' || c == '%' || (extraEsc && ::strchr(extraEsc,c)) ||
1685 ((c == ' ' || c == '+' || c == '?' || c == '&') && !(noEsc && ::strchr(noEsc,c))))
1686 s << '%' << hexEncode(c >> 4) << hexEncode(c);
1687 else
1688 s += c;
1689 }
1690 return s;
1691 }
1692
uriUnescape(const char * str,int * errptr)1693 String String::uriUnescape(const char* str, int* errptr)
1694 {
1695 String s;
1696 if (TelEngine::null(str))
1697 return s;
1698 const char *pos = str;
1699 char c;
1700 while ((c=*pos++)) {
1701 if ((unsigned char)c < ' ') {
1702 if (errptr)
1703 *errptr = (pos-str) - 1;
1704 return s;
1705 }
1706 else if (c == '%') {
1707 int hiNibble = hexDecode(*pos++);
1708 if (hiNibble < 0) {
1709 if (errptr)
1710 *errptr = (pos-str) - 1;
1711 return s;
1712 }
1713 int loNibble = hexDecode(*pos++);
1714 if (loNibble < 0) {
1715 if (errptr)
1716 *errptr = (pos-str) - 1;
1717 return s;
1718 }
1719 c = ((hiNibble << 4) | loNibble) & 0xff;
1720 }
1721 s += c;
1722 }
1723 if (errptr)
1724 *errptr = -1;
1725 return s;
1726 }
1727
hash(const char * value,unsigned int h)1728 unsigned int String::hash(const char* value, unsigned int h)
1729 {
1730 if (!value)
1731 return 0;
1732
1733 // sdbm hash algorithm, hash(i) = hash(i-1) * 65599 + str[i]
1734 while (unsigned char c = (unsigned char) *value++)
1735 h = (h << 6) + (h << 16) - h + c;
1736 return h;
1737 }
1738
lenUtf8(const char * value,uint32_t maxChar,bool overlong)1739 int String::lenUtf8(const char* value, uint32_t maxChar, bool overlong)
1740 {
1741 if (!value)
1742 return 0;
1743 if (maxChar < 128)
1744 maxChar = 0x10ffff; // RFC 3629 default limit
1745
1746 int count = 0;
1747 unsigned int more = 0;
1748 uint32_t min = 0;
1749 uint32_t val = 0;
1750
1751 while (unsigned char c = (unsigned char) *value++) {
1752 if (more) {
1753 // all continuation bytes are in range [128..191]
1754 if ((c & 0xc0) != 0x80)
1755 return -1;
1756 val = (val << 6) | (c & 0x3f);
1757 if (!--more) {
1758 // got full value, check for overlongs and out of range
1759 if (val > maxChar)
1760 return -1;
1761 if (overlong)
1762 continue;
1763 if (val < min)
1764 return -1;
1765 }
1766 continue;
1767 }
1768 count++;
1769 // from 1st byte we find out how many are supposed to follow
1770 if (c < 0x80) // 1 byte, 0...0x7F, ASCII characters, no check
1771 ;
1772 else if (c < 0xc0) // invalid as first UFT-8 byte
1773 return -1;
1774 else if (c < 0xe0) {
1775 // 2 bytes, 0x80...0x7FF
1776 min = 0x80;
1777 val = c & 0x1f;
1778 more = 1;
1779 }
1780 else if (c < 0xf0) {
1781 // 3 bytes, 0x800...0xFFFF, Basic Multilingual Plane
1782 min = 0x800;
1783 val = c & 0x0f;
1784 more = 2;
1785 }
1786 else if (c < 0xf8) {
1787 // 4 bytes, 0x10000...0x1FFFFF, RFC 3629 limit (10FFFF)
1788 min = 0x10000;
1789 val = c & 0x07;
1790 more = 3;
1791 }
1792 else if (c < 0xfc) {
1793 // 5 bytes, 0x200000...0x3FFFFFF
1794 min = 0x200000;
1795 val = c & 0x03;
1796 more = 4;
1797 }
1798 else if (c < 0xfe) {
1799 // 6 bytes, 0x4000000...0x7FFFFFFF
1800 min = 0x4000000;
1801 val = c & 0x01;
1802 more = 5;
1803 }
1804 else
1805 return -1;
1806 }
1807 if (more)
1808 return -1;
1809 return count;
1810 }
1811
fixUtf8(const char * replace,uint32_t maxChar,bool overlong)1812 int String::fixUtf8(const char* replace, uint32_t maxChar, bool overlong)
1813 {
1814 if (null())
1815 return 0;
1816 if (maxChar < 128)
1817 maxChar = 0x10ffff; // RFC 3629 default limit
1818 if (!replace)
1819 replace = "\xEF\xBF\xBD";
1820
1821 int count = 0;
1822 unsigned int more = 0;
1823 uint32_t min = 0;
1824 uint32_t val = 0;
1825 unsigned int pos = 0;
1826 bool bad = false;
1827 String tmp;
1828
1829 for (unsigned int i = 0; i < m_length; i++) {
1830 unsigned char c = (unsigned char) at(i);
1831 if (more) {
1832 // all continuation bytes are in range [128..191]
1833 if ((c & 0xc0) != 0x80) {
1834 // truncated sequence, must search for 1st byte again
1835 more = 0;
1836 count++;
1837 tmp += replace;
1838 }
1839 else {
1840 val = (val << 6) | (c & 0x3f);
1841 if (!--more) {
1842 // got full value, check for overlongs and out of range
1843 if ((val > maxChar) || ((val < min) && !overlong))
1844 bad = true;
1845 // finished multibyte, add it to temporary
1846 if (bad) {
1847 count++;
1848 tmp += replace;
1849 }
1850 else
1851 tmp += substr(pos,(int)(i+1-pos));
1852 }
1853 continue;
1854 }
1855 }
1856 pos = i;
1857 bad = false;
1858 // from 1st byte we find out how many are supposed to follow
1859 if (c < 0x80) // 1 byte, 0...0x7F, ASCII characters, good
1860 ;
1861 else if (c < 0xc0) // invalid as first UFT-8 byte
1862 bad = true;
1863 else if (c < 0xe0) {
1864 // 2 bytes, 0x80...0x7FF
1865 min = 0x80;
1866 val = c & 0x1f;
1867 more = 1;
1868 }
1869 else if (c < 0xf0) {
1870 // 3 bytes, 0x800...0xFFFF, Basic Multilingual Plane
1871 min = 0x800;
1872 val = c & 0x0f;
1873 more = 2;
1874 }
1875 else if (c < 0xf8) {
1876 // 4 bytes, 0x10000...0x1FFFFF, RFC 3629 limit (10FFFF)
1877 min = 0x10000;
1878 val = c & 0x07;
1879 more = 3;
1880 }
1881 else if (c < 0xfc) {
1882 // 5 bytes, 0x200000...0x3FFFFFF
1883 min = 0x200000;
1884 val = c & 0x03;
1885 more = 4;
1886 }
1887 else if (c < 0xfe) {
1888 // 6 bytes, 0x4000000...0x7FFFFFFF
1889 min = 0x4000000;
1890 val = c & 0x01;
1891 more = 5;
1892 }
1893 else
1894 bad = true;
1895 if (!more) {
1896 if (bad) {
1897 count++;
1898 tmp += replace;
1899 }
1900 else
1901 tmp += (char)c;
1902 }
1903 }
1904 if (more) {
1905 // UTF-8 truncated at end of string
1906 count++;
1907 tmp += replace;
1908 }
1909
1910 if (count)
1911 operator=(tmp);
1912 return count;
1913 }
1914
getObject(const String & name) const1915 void* String::getObject(const String& name) const
1916 {
1917 if (name == YATOM("String"))
1918 return const_cast<String*>(this);
1919 return GenObject::getObject(name);
1920 }
1921
toString() const1922 const String& String::toString() const
1923 {
1924 return *this;
1925 }
1926
atom(const String * & str,const char * val)1927 const String* String::atom(const String*& str, const char* val)
1928 {
1929 if (!str) {
1930 s_mutex.lock();
1931 if (!str) {
1932 if (TelEngine::null(val))
1933 str = &s_empty;
1934 else {
1935 str = static_cast<const String*>(s_atoms[val]);
1936 if (!str) {
1937 str = new String(val);
1938 s_atoms.insert(str);
1939 }
1940 }
1941 }
1942 s_mutex.unlock();
1943 }
1944 return str;
1945 }
1946
1947
Regexp()1948 Regexp::Regexp()
1949 : m_regexp(0), m_compile(true), m_flags(0)
1950 {
1951 XDebug(DebugAll,"Regexp::Regexp() [%p]",this);
1952 }
1953
Regexp(const char * value,bool extended,bool insensitive)1954 Regexp::Regexp(const char* value, bool extended, bool insensitive)
1955 : String(value), m_regexp(0), m_compile(true), m_flags(0)
1956 {
1957 XDebug(DebugAll,"Regexp::Regexp(\"%s\",%d,%d) [%p]",
1958 value,extended,insensitive,this);
1959 setFlags(extended,insensitive);
1960 compile();
1961 }
1962
Regexp(const Regexp & value)1963 Regexp::Regexp(const Regexp& value)
1964 : String(value.c_str()), m_regexp(0), m_compile(true), m_flags(value.m_flags)
1965 {
1966 XDebug(DebugAll,"Regexp::Regexp(%p) [%p]",&value,this);
1967 }
1968
~Regexp()1969 Regexp::~Regexp()
1970 {
1971 cleanup();
1972 }
1973
matches(const char * value,StringMatchPrivate * matchlist) const1974 bool Regexp::matches(const char* value, StringMatchPrivate* matchlist) const
1975 {
1976 XDebug(DebugInfo,"Regexp::matches(\"%s\",%p)",value,matchlist);
1977 if (!value)
1978 value = "";
1979 if (!compile())
1980 return false;
1981 int mm = matchlist ? MAX_MATCH : 0;
1982 regmatch_t *mt = matchlist ? (matchlist->rmatch)+1 : 0;
1983 return !::regexec((regex_t *)m_regexp,value,mm,mt,0);
1984 }
1985
matches(const char * value) const1986 bool Regexp::matches(const char* value) const
1987 {
1988 return matches(value,0);
1989 }
1990
changed()1991 void Regexp::changed()
1992 {
1993 cleanup();
1994 String::changed();
1995 }
1996
doCompile() const1997 bool Regexp::doCompile() const
1998 {
1999 XDebug(DebugInfo,"Regexp::compile()");
2000 m_compile = false;
2001 if (c_str() && !m_regexp) {
2002 regex_t *data = (regex_t *) ::malloc(sizeof(regex_t));
2003 if (!data) {
2004 Debug("Regexp",DebugFail,"malloc(%d) returned NULL!",(int)sizeof(regex_t));
2005 return false;
2006 }
2007 if (::regcomp(data,c_str(),m_flags)) {
2008 Debug(DebugWarn,"Regexp::compile() \"%s\" failed",c_str());
2009 ::regfree(data);
2010 ::free(data);
2011 }
2012 else
2013 m_regexp = (void *)data;
2014 }
2015 return (m_regexp != 0);
2016 }
2017
cleanup()2018 void Regexp::cleanup()
2019 {
2020 XDebug(DebugInfo,"Regexp::cleanup()");
2021 if (m_regexp) {
2022 regex_t *data = (regex_t *)m_regexp;
2023 m_regexp = 0;
2024 ::regfree(data);
2025 ::free(data);
2026 }
2027 m_compile = true;
2028 }
2029
setFlags(bool extended,bool insensitive)2030 void Regexp::setFlags(bool extended, bool insensitive)
2031 {
2032 int f = (extended ? REG_EXTENDED : 0) | (insensitive ? REG_ICASE : 0);
2033 if (m_flags != f) {
2034 cleanup();
2035 m_flags = f;
2036 }
2037 }
2038
isExtended() const2039 bool Regexp::isExtended() const
2040 {
2041 return (m_flags & REG_EXTENDED) != 0;
2042 }
2043
isCaseInsensitive() const2044 bool Regexp::isCaseInsensitive() const
2045 {
2046 return (m_flags & REG_ICASE) != 0;
2047 }
2048
2049
NamedString(const char * name,const char * value)2050 NamedString::NamedString(const char* name, const char* value)
2051 : String(value), m_name(name)
2052 {
2053 XDebug(DebugAll,"NamedString::NamedString(\"%s\",\"%s\") [%p]",name,value,this);
2054 }
2055
toString() const2056 const String& NamedString::toString() const
2057 {
2058 return m_name;
2059 }
2060
getObject(const String & name) const2061 void* NamedString::getObject(const String& name) const
2062 {
2063 if (name == YATOM("NamedString"))
2064 return (void*)this;
2065 return String::getObject(name);
2066 }
2067
2068
NamedPointer(const char * name,GenObject * data,const char * value)2069 NamedPointer::NamedPointer(const char* name, GenObject* data, const char* value)
2070 : NamedString(name,value),
2071 m_data(0)
2072 {
2073 userData(data);
2074 }
2075
~NamedPointer()2076 NamedPointer::~NamedPointer()
2077 {
2078 userData(0);
2079 }
2080
2081 // Set obscure data carried by this object.
userData(GenObject * data)2082 void NamedPointer::userData(GenObject* data)
2083 {
2084 TelEngine::destruct(m_data);
2085 m_data = data;
2086 }
2087
2088 // Retrieve the pointer carried by this object and release ownership
takeData()2089 GenObject* NamedPointer::takeData()
2090 {
2091 GenObject* tmp = m_data;
2092 m_data = 0;
2093 return tmp;
2094 }
2095
getObject(const String & name) const2096 void* NamedPointer::getObject(const String& name) const
2097 {
2098 if (name == YATOM("NamedPointer"))
2099 return (void*)this;
2100 void* p = NamedString::getObject(name);
2101 if (p)
2102 return p;
2103 if (m_data)
2104 return m_data->getObject(name);
2105 return 0;
2106 }
2107
2108 // Called whenever the string value changed. Release the pointer
changed()2109 void NamedPointer::changed()
2110 {
2111 userData(0);
2112 NamedString::changed();
2113 }
2114
2115
getObject(const String & name) const2116 void* GenObject::getObject(const String& name) const
2117 {
2118 return 0;
2119 }
2120
toString() const2121 const String& GenObject::toString() const
2122 {
2123 return String::empty();
2124 }
2125
traceId() const2126 const String& GenObject::traceId() const
2127 {
2128 return String::empty();
2129 }
2130
encodeFlags(const TokenDict * tokens) const2131 unsigned int String::encodeFlags(const TokenDict* tokens) const
2132 {
2133 unsigned int flags = 0;
2134 ObjList* list = split(',',false);
2135 for (ObjList* o = list->skipNull(); o; o = o->skipNext()) {
2136 flags |= (unsigned int)(lookup(*static_cast<String*>(o->get()),tokens));
2137 }
2138 TelEngine::destruct(list);
2139 return flags;
2140 }
2141
encodeFlags(const TokenDict64 * tokens) const2142 uint64_t String::encodeFlags(const TokenDict64* tokens) const
2143 {
2144 uint64_t flags = 0;
2145 ObjList* list = split(',',false);
2146 for (ObjList* o = list->skipNull(); o; o = o->skipNext()) {
2147 flags |= (uint64_t)(lookup(*static_cast<String*>(o->get()),tokens));
2148 }
2149 TelEngine::destruct(list);
2150 return flags;
2151 }
2152
decodeFlags(unsigned int flags,const TokenDict * tokens,bool unknownflag)2153 const String& String::decodeFlags(unsigned int flags, const TokenDict* tokens, bool unknownflag)
2154 {
2155 if (tokens) {
2156 for(; tokens->token && flags; tokens++) {
2157 if ((tokens->value & flags) == (unsigned int)tokens->value) {
2158 append(tokens->token,",");
2159 flags &= ~tokens->value;
2160 }
2161 }
2162 }
2163 if (flags && unknownflag)
2164 append(String(flags),",");
2165 return *this;
2166 }
2167
decodeFlags(uint64_t flags,const TokenDict64 * tokens,bool unknownflag)2168 const String& String::decodeFlags(uint64_t flags, const TokenDict64* tokens, bool unknownflag)
2169 {
2170 if (tokens) {
2171 for (; tokens->token && flags; tokens++) {
2172 if ((tokens->value & flags) == (uint64_t)tokens->value ) {
2173 append(tokens->token,",");
2174 flags &= ~tokens->value;
2175 }
2176 }
2177 }
2178 if (flags && unknownflag)
2179 append(String(flags),",");
2180 return *this;
2181 }
2182
2183 /* vi: set ts=8 sw=4 sts=4 noet: */
2184