E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gstr.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gstr.cpp
19 //
20
21 #include "gdef.h"
22 #include "gstr.h"
23 #include "gdebug.h"
24 #include <cmath>
25 #include <algorithm>
26 #include <iterator>
27 #include <functional>
28 #include <ctype.h>
29 #include <iomanip>
30 #include <climits>
31 #include <string>
32 #include <sstream>
33
34 std::string G::Str::escaped( const std::string & s_in )
35 {
36 std::string s( s_in ) ;
37 escape( s ) ;
38 return s ;
39 }
40
41 std::string G::Str::escaped( const std::string & s_in , char c_escape , const std::string & specials_in , const std::string & specials_out )
42 {
43 std::string s( s_in ) ;
44 escape( s , c_escape , specials_in , specials_out ) ;
45 return s ;
46 }
47
48 std::string G::Str::escaped( const std::string & s_in , char c_escape , const char * specials_in , const char * specials_out )
49 {
50 std::string s( s_in ) ;
51 escape( s , c_escape , specials_in , specials_out ) ;
52 return s ;
53 }
54
55 void G::Str::escape( std::string & s )
56 {
57 escapeImp( s , '\\' , "\\\r\n\t" , "\\rnt0" , true ) ;
58 }
59
60 void G::Str::escape( std::string & s , char c_escape , const char * specials_in , const char * specials_out )
61 {
62 bool with_nul = std::strlen(specials_in) != std::strlen(specials_out) ;
63 escapeImp( s , c_escape , specials_in , specials_out , with_nul ) ;
64 }
65
66 void G::Str::escape( std::string & s , char c_escape , const std::string & specials_in , const std::string & specials_out )
67 {
68 G_ASSERT( specials_in.length() == specials_out.length() ) ;
69 bool with_nul = !specials_in.empty() && specials_in.at(specials_in.length()-1U) == '\0' ;
70 escapeImp( s , c_escape , specials_in.c_str() , specials_out.c_str() , with_nul ) ;
71 }
72
73 void G::Str::escapeImp( std::string & s , char c_escape , const char * specials_in , const char * specials_out , bool with_nul )
74 {
75 G_ASSERT( specials_in != nullptr && specials_out != nullptr && (std::strlen(specials_out)-std::strlen(specials_in)) <= 1U ) ;
76 size_type pos = 0U ;
77 for(;;)
78 {
79 char c_in = '\0' ;
80 pos = s.find_first_of( specials_in , pos ) ;
81 if( pos != std::string::npos )
82 c_in = s.at( pos ) ;
83 else if( with_nul )
84 pos = s.find( '\0' , pos ) ;
85 if( pos == std::string::npos )
86 break ;
87
88 G_ASSERT( std::strchr(specials_in,c_in) != nullptr ) ;
89 const size_t special_index = std::strchr(specials_in,c_in) - specials_in ;
90 G_ASSERT( special_index < std::strlen(specials_out) ) ;
91
92 s.insert( pos , 1U , c_escape ) ;
93 pos++ ;
94 s.at(pos) = specials_out[special_index] ;
95 pos++ ;
96 }
97 }
98
99 std::string G::Str::dequote( const std::string & s , char qq , char esc , const std::string & ws )
100 {
101 std::string result ;
102 result.reserve( s.size() ) ;
103 bool in_quote = false ;
104 bool escaped = false ;
105 for( std::string::const_iterator p = s.begin() ; p != s.end() ; ++p )
106 {
107 if( *p == esc && !escaped )
108 {
109 escaped = true ;
110 }
111 else
112 {
113 bool is_space = ws.find(*p) != std::string::npos ;
114 if( *p == qq && !escaped && !in_quote )
115 {
116 in_quote = true ;
117 }
118 else if( *p == qq && !escaped )
119 {
120 in_quote = false ;
121 }
122 else if( ws.find(*p) != std::string::npos && in_quote )
123 {
124 result.append( 1U , esc ) ;
125 result.append( 1U , *p ) ;
126 }
127 else
128 {
129 result.append( 1U , *p ) ;
130 }
131 escaped = false ;
132 }
133 }
134 return result ;
135 }
136
137 void G::Str::unescape( std::string & s )
138 {
139 unescape( s , '\\' , "rnt0" , "\r\n\t" ) ;
140 }
141
142 void G::Str::unescape( std::string & s , char c_escape , const char * specials_in , const char * specials_out )
143 {
144 G_ASSERT( specials_in != nullptr && specials_out != nullptr && (std::strlen(specials_in)-std::strlen(specials_out)) <= 1U ) ;
145 bool escaped = false ;
146 std::string::iterator out = s.begin() ; // output in-place
147 for( std::string::iterator in = s.begin() ; in != s.end() ; ++in )
148 {
149 const char * specials_in_p = std::strchr( specials_in , *in ) ;
150 const char * specials_out_p = specials_in_p ? (specials_out+(specials_in_p-specials_in)) : nullptr ;
151 if( escaped && specials_out_p )
152 *out++ = *specials_out_p , escaped = false ;
153 else if( escaped && *in == c_escape )
154 *out++ = c_escape , escaped = false ;
155 else if( escaped )
156 *out++ = *in , escaped = false ;
157 else if( *in == c_escape )
158 escaped = true ;
159 else
160 *out++ = *in , escaped = false ;
161 }
162 if( out != s.end() ) s.erase( out , s.end() ) ;
163 }
164
165 std::string G::Str::unescaped( const std::string & s_in )
166 {
167 std::string s( s_in ) ;
168 unescape( s ) ;
169 return s ;
170 }
171
172 bool G::Str::replace( std::string & s , const std::string & from , const std::string & to , size_type * pos_p )
173 {
174 if( from.length() == 0 )
175 return false ;
176
177 size_type pos = pos_p == nullptr ? 0 : *pos_p ;
178 if( pos >= s.length() )
179 return false ;
180
181 pos = s.find( from , pos ) ;
182 if( pos == std::string::npos )
183 {
184 return false ;
185 }
186 else
187 {
188 s.replace( pos , from.length() , to ) ;
189 if( pos_p != nullptr )
190 *pos_p = pos + to.length() ;
191 return true ;
192 }
193 }
194
195 unsigned int G::Str::replaceAll( std::string & s , const std::string & from , const std::string & to )
196 {
197 unsigned int count = 0U ;
198 for( size_type pos = 0U ; replace(s,from,to,&pos) ; count++ )
199 ; // no-op
200 return count ;
201 }
202
203 unsigned int G::Str::replaceAll( std::string & s , const char * from , const char * to )
204 {
205 if( s.find(from) != std::string::npos )
206 {
207 unsigned int count = 0U ;
208 for( size_type pos = 0U ; replace(s,from,to,&pos) ; count++ )
209 ; // no-op
210 return count ;
211 }
212 else
213 {
214 return 0U ;
215 }
216 }
217
218 void G::Str::removeAll( std::string & s , char c )
219 {
220 const std::string::iterator end = s.end() ;
221 s.erase( std::remove_if( s.begin() , end , std::bind1st(std::equal_to<char>(),c) ) , end ) ;
222 }
223
224 void G::Str::trimLeft( std::string & s , const std::string & ws , size_type limit )
225 {
226 size_type n = s.find_first_not_of( ws ) ;
227 if( limit != 0U && ( n == std::string::npos || n > limit ) )
228 n = limit >= s.length() ? std::string::npos : limit ;
229 if( n == std::string::npos )
230 s = std::string() ;
231 else if( n != 0U )
232 s.erase( 0U , n ) ;
233 }
234
235 void G::Str::trimRight( std::string & s , const std::string & ws , size_type limit )
236 {
237 size_type n = s.find_last_not_of( ws ) ;
238 if( limit != 0U && ( n == std::string::npos || s.length() > (limit+n+1U) ) )
239 n = limit >= s.length() ? std::string::npos : (s.length()-limit-1U) ;
240 if( n == std::string::npos )
241 s = std::string() ;
242 else if( (n+1U) != s.length() )
243 s.resize( n + 1U ) ;
244 }
245
246 void G::Str::trim( std::string & s , const std::string & ws )
247 {
248 trimLeft(s,ws) ; trimRight(s,ws) ;
249 }
250
251 std::string G::Str::trimmed( const std::string & s_in , const std::string & ws )
252 {
253 std::string s( s_in ) ;
254 trim( s , ws ) ;
255 return s ;
256 }
257
258 namespace
259 {
260 struct IsDigit : std::unary_function<char,bool>
261 {
262 bool operator()( char c ) const { return !! isdigit( c ) ; }
263 } ;
264 }
265
266 bool G::Str::isNumeric( const std::string & s , bool allow_minus_sign )
267 {
268 const std::string::const_iterator end = s.end() ;
269 std::string::const_iterator p = s.begin() ;
270 if( allow_minus_sign && p != end && *p == '-' ) ++p ;
271 return std::find_if( p , end , std::not1(IsDigit()) ) == end ;
272 }
273
274 namespace
275 {
276 struct IsPrintableAscii : std::unary_function<char,bool>
277 {
278 bool operator()( char c ) const { return c >= 0x20 && c < 0x7f ; }
279 } ;
280 }
281
282 bool G::Str::isPrintableAscii( const std::string & s )
283 {
284 const std::string::const_iterator end = s.end() ;
285 return std::find_if( s.begin() , end , std::not1(IsPrintableAscii()) ) == end ;
286 }
287
288 bool G::Str::isInt( const std::string & s )
289 {
290 bool overflow = false ;
291 bool invalid = false ;
292 toIntImp( s , overflow , invalid ) ;
293 return !overflow && !invalid ;
294 }
295
296 bool G::Str::isUShort( const std::string & s )
297 {
298 bool overflow = false ;
299 bool invalid = false ;
300 toUShortImp( s , overflow , invalid ) ;
301 return !overflow && !invalid ;
302 }
303
304 bool G::Str::isUInt( const std::string & s )
305 {
306 bool overflow = false ;
307 bool invalid = false ;
308 toUIntImp( s , overflow , invalid ) ;
309 return !overflow && !invalid ;
310 }
311
312 bool G::Str::isULong( const std::string & s )
313 {
314 bool overflow = false ;
315 bool invalid = false ;
316 toULongImp( s , overflow , invalid ) ;
317 return !overflow && !invalid ;
318 }
319
320 std::string G::Str::fromBool( bool b )
321 {
322 return b ? "true" : "false" ;
323 }
324
325 std::string G::Str::fromDouble( double d )
326 {
327 std::ostringstream ss ;
328 ss << std::setprecision(16) << d ; // was "setprecision(DBL_DIG+1)"
329 return ss.str() ;
330 }
331
332 std::string G::Str::fromInt( int i )
333 {
334 std::ostringstream ss ;
335 ss << i ;
336 return ss.str() ;
337 }
338
339 std::string G::Str::fromLong( long l )
340 {
341 std::ostringstream ss ;
342 ss << l ;
343 return ss.str() ;
344 }
345
346 std::string G::Str::fromShort( short s )
347 {
348 std::ostringstream ss ;
349 ss << s ;
350 return ss.str() ;
351 }
352
353 std::string G::Str::fromUInt( unsigned int ui )
354 {
355 std::ostringstream ss ;
356 ss << ui ;
357 return ss.str() ;
358 }
359
360 std::string G::Str::fromULong( unsigned long ul )
361 {
362 std::ostringstream ss ;
363 ss << ul ;
364 return ss.str() ;
365 }
366
367 std::string G::Str::fromUShort( unsigned short us )
368 {
369 std::ostringstream ss ;
370 ss << us ;
371 return ss.str() ;
372 }
373
374 bool G::Str::toBool( const std::string & s )
375 {
376 std::string str = lower( s ) ;
377 if( str == "true" )
378 {
379 return true ;
380 }
381 else if( str == "false" )
382 {
383 return false ;
384 }
385 else
386 {
387 throw InvalidFormat( "expected true/false" , s ) ;
388 return false ; // never gets here -- the return pacifies some compilers
389 }
390 }
391
392 double G::Str::toDouble( const std::string & s )
393 {
394 char * end = nullptr ;
395 double result = ::strtod( s.c_str(), &end ) ;
396
397 if( end == 0 || end[0] != '\0' )
398 throw InvalidFormat( "expected floating point number" , s ) ;
399
400 if( result == HUGE_VAL || result == -(HUGE_VAL) )
401 throw Overflow( s ) ;
402
403 return result ;
404 }
405
406 int G::Str::toInt( const std::string & s )
407 {
408 bool overflow = false ;
409 bool invalid = false ;
410 int result = toIntImp( s , overflow , invalid ) ;
411 if( invalid )
412 throw InvalidFormat( "expected integer" , s ) ;
413 if( overflow )
414 throw Overflow( s ) ;
415 return result ;
416 }
417
418 int G::Str::toIntImp( const std::string & s , bool & overflow , bool & invalid )
419 {
420 long long_val = toLongImp( s , overflow , invalid ) ;
421 int result = static_cast<int>( long_val ) ;
422 if( result != long_val )
423 overflow = true ;
424 return result ;
425 }
426
427 long G::Str::toLong( const std::string & s )
428 {
429 bool overflow = false ;
430 bool invalid = false ;
431 long result = toLongImp( s , overflow , invalid ) ;
432 if( invalid )
433 throw InvalidFormat( "expected long integer" , s ) ;
434 if( overflow )
435 throw Overflow( s ) ;
436 return result ;
437 }
438
439 long G::Str::toLongImp( const std::string & s , bool & overflow , bool & invalid )
440 {
441 char * end = nullptr ;
442 long result = ::strtol( s.c_str(), &end, 10 ) ; // was radix 0
443 if( end == 0 || end[0] != '\0' )
444 invalid = true ;
445 if( result == LONG_MAX || result == LONG_MIN )
446 overflow = true ;
447 return result ;
448 }
449
450 short G::Str::toShort( const std::string & s )
451 {
452 bool overflow = false ;
453 bool invalid = false ;
454 short result = toShortImp( s , overflow , invalid ) ;
455 if( invalid )
456 throw InvalidFormat( "expected short integer" , s ) ;
457 if( overflow )
458 throw Overflow( s ) ;
459 return result ;
460 }
461
462 short G::Str::toShortImp( const std::string & s , bool & overflow , bool & invalid )
463 {
464 long long_val = toLongImp( s , overflow , invalid ) ;
465 short result = static_cast<short>( long_val ) ;
466 if( result != long_val )
467 overflow = true ;
468 return result ;
469 }
470
471 unsigned int G::Str::toUInt( const std::string & s1 , const std::string & s2 )
472 {
473 return !s1.empty() && isUInt(s1) ? toUInt(s1) : toUInt(s2) ;
474 }
475
476 unsigned int G::Str::toUInt( const std::string & s , Limited )
477 {
478 bool overflow = false ;
479 bool invalid = false ;
480 unsigned int result = toUIntImp( s , overflow , invalid ) ;
481 if( invalid )
482 throw InvalidFormat( "expected unsigned integer" , s ) ;
483 if( overflow )
484 result = UINT_MAX ;
485 return result ;
486 }
487
488 unsigned int G::Str::toUInt( const std::string & s )
489 {
490 bool overflow = false ;
491 bool invalid = false ;
492 unsigned int result = toUIntImp( s , overflow , invalid ) ;
493 if( invalid )
494 throw InvalidFormat( "expected unsigned integer" , s ) ;
495 if( overflow )
496 throw Overflow( s ) ;
497 return result ;
498 }
499
500 unsigned int G::Str::toUIntImp( const std::string & s , bool & overflow , bool & invalid )
501 {
502 unsigned long ulong_val = toULongImp( s , overflow , invalid ) ;
503 unsigned int result = static_cast<unsigned int>( ulong_val ) ;
504 if( result != ulong_val )
505 overflow = true ;
506 return result ;
507 }
508
509 unsigned long G::Str::toULong( const std::string & s , Limited )
510 {
511 bool overflow = false ;
512 bool invalid = false ;
513 unsigned long result = toULongImp( s , overflow , invalid ) ;
514 if( invalid )
515 throw InvalidFormat( "expected unsigned long integer" , s ) ;
516 if( overflow )
517 result = ULONG_MAX ;
518 return result ;
519 }
520
521 unsigned long G::Str::toULong( const std::string & s )
522 {
523 bool overflow = false ;
524 bool invalid = false ;
525 unsigned long result = toULongImp( s , overflow , invalid ) ;
526 if( invalid )
527 throw InvalidFormat( "expected unsigned long integer" , s ) ;
528 else if( overflow )
529 throw Overflow( s ) ;
530 return result ;
531 }
532
533 unsigned long G::Str::toULongImp( const std::string & s , bool & overflow , bool & invalid )
534 {
535 if( s.empty() ) // new
536 {
537 invalid = true ;
538 overflow = false ;
539 return 0UL ;
540 }
541 else
542 {
543 char * end = nullptr ;
544 unsigned long result = ::strtoul( s.c_str() , &end , 10 ) ;
545 if( end == 0 || end[0] != '\0' )
546 invalid = true ;
547 if( result == ULONG_MAX )
548 overflow = true ;
549 return result ;
550 }
551 }
552
553 unsigned short G::Str::toUShort( const std::string & s , Limited )
554 {
555 bool overflow = false ;
556 bool invalid = false ;
557 unsigned short result = toUShortImp( s , overflow , invalid ) ;
558 if( invalid )
559 throw InvalidFormat( "expected unsigned short integer" , s ) ;
560 if( overflow )
561 result = USHRT_MAX ;
562 return result ;
563 }
564
565 unsigned short G::Str::toUShort( const std::string & s )
566 {
567 bool overflow = false ;
568 bool invalid = false ;
569 unsigned short result = toUShortImp( s , overflow , invalid ) ;
570 if( invalid )
571 throw InvalidFormat( "expected unsigned short integer" , s ) ;
572 else if( overflow )
573 throw Overflow( s ) ;
574 return result ;
575 }
576
577 unsigned short G::Str::toUShortImp( const std::string & s , bool & overflow , bool & invalid )
578 {
579 unsigned long ulong_val = toULongImp( s , overflow , invalid ) ;
580 unsigned short result = static_cast<unsigned short>( ulong_val ) ;
581 if( result != ulong_val )
582 overflow = true ;
583 return result ;
584 }
585
586 namespace
587 {
588 struct ToLower : std::unary_function<char,char>
589 {
590 char operator()( char c ) { return static_cast<char>( tolower(c) ) ; }
591 } ;
592 }
593
594 void G::Str::toLower( std::string & s )
595 {
596 std::transform( s.begin() , s.end() , s.begin() , ToLower() ) ;
597 }
598
599 std::string G::Str::lower( const std::string & in )
600 {
601 std::string out = in ;
602 toLower( out ) ;
603 return out ;
604 }
605
606 namespace
607 {
608 struct ToUpper : std::unary_function<char,char>
609 {
610 char operator()( char c ) { return static_cast<char>( toupper(c) ) ; }
611 } ;
612 }
613
614 void G::Str::toUpper( std::string & s )
615 {
616 std::transform( s.begin() , s.end() , s.begin() , ToUpper() ) ;
617 }
618
619 std::string G::Str::upper( const std::string & in )
620 {
621 std::string out = in ;
622 toUpper( out ) ;
623 return out ;
624 }
625
626 namespace
627 {
628 template <typename Tchar = char , typename Tuchar = unsigned char>
629 struct PrintableAppender : std::unary_function<Tchar,void>
630 {
631 std::string & s ;
632 Tchar escape_in ;
633 char escape_out ;
634 bool eight_bit ;
635 PrintableAppender( std::string & s_ , Tchar escape_ , bool eight_bit_ ) :
636 s(s_) ,
637 escape_in(escape_) ,
638 escape_out(static_cast<char>(escape_)) ,
639 eight_bit(eight_bit_)
640 {
641 }
642 void operator()( Tchar c )
643 {
644 const Tuchar uc = static_cast<Tuchar>(c) ;
645 if( c == escape_in )
646 {
647 s.append( 2U , escape_out ) ;
648 }
649 else if( !eight_bit && uc >= 0x20U && uc < 0x7FU && uc != 0xFFU )
650 {
651 s.append( 1U , static_cast<char>(c) ) ;
652 }
653 else if( eight_bit && ( ( uc >= 0x20U && uc < 0x7FU ) || uc >= 0xA0 ) && uc != 0xFFU )
654 {
655 s.append( 1U , static_cast<char>(c) ) ;
656 }
657 else
658 {
659 s.append( 1U , escape_out ) ;
660 if( static_cast<char>(c) == '\n' )
661 {
662 s.append( 1U , 'n' ) ;
663 }
664 else if( static_cast<char>(c) == '\r' )
665 {
666 s.append( 1U , 'r' ) ;
667 }
668 else if( static_cast<char>(c) == '\t' )
669 {
670 s.append( 1U , 't' ) ;
671 }
672 else if( c == 0 )
673 {
674 s.append( 1U , '0' ) ;
675 }
676 else
677 {
678 s.append( 1U , 'x' ) ;
679 const char * const map = "0123456789abcdef" ;
680 unsigned long n = uc ;
681 if( sizeof(Tchar) == 1 )
682 {
683 n &= 0xFFUL ;
684 s.append( 1U , map[(n/16UL)%16UL] ) ;
685 s.append( 1U , map[n%16UL] ) ;
686 }
687 else
688 {
689 n &= 0xFFFFUL ;
690 s.append( 1U , map[(n/4096UL)%16UL] ) ;
691 s.append( 1U , map[(n/256UL)%16UL] ) ;
692 s.append( 1U , map[(n/16UL)%16UL] ) ;
693 s.append( 1U , map[n%16UL] ) ;
694 }
695 }
696 }
697 }
698 } ;
699 }
700
701 std::string G::Str::printable( const std::string & in , char escape )
702 {
703 std::string result ;
704 result.reserve( in.length() + 1U ) ;
705 std::for_each( in.begin() , in.end() , PrintableAppender<char,unsigned char>(result,escape,true) ) ;
706 return result ;
707 }
708
709 std::string G::Str::toPrintableAscii( const std::string & in , char escape )
710 {
711 std::string result ;
712 result.reserve( in.length() + 1U ) ;
713 std::for_each( in.begin() , in.end() , PrintableAppender<char,unsigned char>(result,escape,false) ) ;
714 return result ;
715 }
716
717 std::string G::Str::toPrintableAscii( char c , char escape )
718 {
719 std::string result ;
720 PrintableAppender<char,unsigned char> append_printable( result , escape , false ) ;
721 append_printable( c ) ;
722 return result ;
723 }
724
725 std::string G::Str::toPrintableAscii( const std::wstring & in , wchar_t escape )
726 {
727 std::string result ;
728 result.reserve( in.length() * 3U ) ;
729 std::for_each( in.begin() , in.end() , PrintableAppender<wchar_t,unsigned long>(result,escape,false) ) ;
730 return result ;
731 }
732
733 std::string G::Str::readLineFrom( std::istream & stream , const std::string & eol )
734 {
735 std::string result ;
736 readLineFrom( stream , eol.empty() ? std::string(1U,'\n') : eol , result , true ) ;
737 return result ;
738 }
739
740 void G::Str::readLineFrom( std::istream & stream , const std::string & eol , std::string & line , bool pre_erase )
741 {
742 G_ASSERT( eol.length() != 0U ) ;
743
744 if( pre_erase )
745 line.erase() ;
746
747 // this is a special speed optimisation for a two-character terminator with a one-character initial string ;-)
748 if( eol.length() == 2U && eol[0] != eol[1] && line.length() == 1U )
749 {
750 // save the initial character, use std::getline() for speed (terminating
751 // on the second character of the two-character terminator), check that the
752 // one-character terminator was actually part of the required two-character
753 // terminator, remove the first character of the two-character terminator,
754 // and finally re-insert the initial character
755 //
756 const char c = line[0] ;
757 line.erase() ; // since getline() doesnt erase it if already at eof
758 std::getline( stream , line , eol[1] ) ; // fast
759 const std::string::size_type line_length = line.length() ;
760 bool complete = line_length > 0U && line[line_length-1U] == eol[0] ;
761 if( complete )
762 {
763 line.resize( line_length - 1U ) ;
764 line.insert( 0U , &c , 1U ) ;
765 }
766 else
767 {
768 line.insert( 0U , &c , 1U ) ;
769 if( stream.good() )
770 {
771 line.append( 1U , eol[1] ) ;
772 readLineFromImp( stream , eol , line ) ;
773 }
774 }
775 }
776 else
777 {
778 readLineFromImp( stream , eol , line ) ;
779 }
780 }
781
782 void G::Str::readLineFromImp( std::istream & stream , const std::string & eol , std::string & line )
783 {
784 const size_type limit = line.max_size() ;
785 const size_type eol_length = eol.length() ;
786 const char eol_final = eol.at( eol_length - 1U ) ;
787 size_type line_length = line.length() ;
788
789 bool changed = false ;
790 char c ;
791 for(;;)
792 {
793 // (maybe optimise by hoisting the sentry and calling rdbuf() methods)
794 stream.get( c ) ;
795
796 if( stream.fail() ) // get(char) always sets the failbit at eof, not necessarily eofbit
797 {
798 // set eofbit, reset failbit -- cf. std::getline() in <string>
799 stream.clear( ( stream.rdstate() & ~std::ios_base::failbit ) | std::ios_base::eofbit ) ;
800 break ;
801 }
802
803 if( line_length == limit ) // pathological case -- see also std::getline()
804 {
805 stream.setstate( std::ios_base::failbit ) ;
806 break ;
807 }
808
809 line.append( 1U , c ) ;
810 changed = true ;
811 ++line_length ;
812
813 if( line_length >= eol_length && c == eol_final )
814 {
815 const size_type offset = line_length - eol_length ;
816 if( line.find(eol,offset) == offset )
817 {
818 line.erase(offset) ;
819 break ;
820 }
821 }
822 }
823 if( !changed )
824 stream.setstate( std::ios_base::failbit ) ;
825 }
826
827 std::string G::Str::wrap( std::string text , const std::string & prefix_1 ,
828 const std::string & prefix_2 , size_type width )
829 {
830 std::string ws( " \t\n" ) ;
831 std::ostringstream ss ;
832 for( bool first_line = true ; text.length() ; first_line = false )
833 {
834 const size_type prefix_length =
835 first_line ? prefix_1.length() : prefix_2.length() ;
836 size_type w = (width > prefix_length) ? (width-prefix_length) : width ;
837
838 const size_type pos_nl = text.find_first_of("\n") ;
839 if( pos_nl != std::string::npos && pos_nl != 0U && pos_nl < w )
840 {
841 w = pos_nl ;
842 }
843
844 std::string line = text ;
845 if( text.length() > w ) // (should use wcwidth() for utf-8 compatibility)
846 {
847 line = text.substr( 0U , w ) ;
848 if( text.find_first_of(ws,w) != w )
849 {
850 const size_type white_space = line.find_last_of( ws ) ;
851 const size_type black_space = line.find_first_not_of( ws ) ;
852 if( white_space != std::string::npos &&
853 black_space != std::string::npos &&
854 (white_space+1U) != black_space )
855 {
856 line = line.substr( 0U , white_space ) ;
857 }
858 }
859 }
860
861 if( line.length() != 0U )
862 {
863 ss << ( first_line ? prefix_1 : prefix_2 ) << line << std::endl ;
864 }
865
866 text = text.length() == line.length() ?
867 std::string() : text.substr(line.length()) ;
868
869 const size_type black_space = text.find_first_not_of( ws ) ;
870 if( black_space != 0U && black_space != std::string::npos )
871 {
872 unsigned int newlines = 0U ;
873 for( size_type pos = 0U ; pos < black_space ; ++pos )
874 {
875 if( text.at(pos) == '\n' )
876 {
877 newlines++ ;
878 if( newlines > 1U )
879 ss << prefix_2 << std::endl ;
880 }
881 }
882
883 text = text.substr( black_space ) ;
884 }
885 }
886 return ss.str() ;
887 }
888
889 namespace
890 {
891 template <typename T>
892 void splitIntoTokens_( const std::string & in , T & out , const std::string & ws )
893 {
894 typedef G::Str::size_type size_type ;
895 for( size_type p = 0U ; p != std::string::npos ; )
896 {
897 p = in.find_first_not_of( ws , p ) ;
898 if( p != std::string::npos )
899 {
900 size_type end = in.find_first_of( ws , p ) ;
901 size_type len = end == std::string::npos ? end : (end-p) ;
902 out.push_back( in.substr(p,len) ) ;
903 p = end ;
904 }
905 }
906 }
907 }
908 void G::Str::splitIntoTokens( const std::string & in , StringArray & out , const std::string & ws )
909 {
910 splitIntoTokens_( in , out , ws ) ;
911 }
912 G::StringArray G::Str::splitIntoTokens( const std::string & in , const std::string & ws )
913 {
914 StringArray out ;
915 splitIntoTokens_( in , out , ws ) ;
916 return out ;
917 }
918
919 namespace
920 {
921 template <typename T>
922 void splitIntoFields_( const std::string & in , T & out , const std::string & ws )
923 {
924 if( in.length() )
925 {
926 size_t start = 0U ;
927 size_t pos = 0U ;
928 for(;;)
929 {
930 if( pos >= in.length() ) break ;
931 pos = in.find_first_of( ws , pos ) ;
932 if( pos == std::string::npos ) break ;
933 out.push_back( in.substr(start,pos-start) ) ;
934 pos++ ;
935 start = pos ;
936 }
937 out.push_back( in.substr(start,pos-start) ) ;
938 }
939 }
940 template <typename T>
941 void splitIntoFields_( const std::string & in_in , T & out , const std::string & ws ,
942 char escape , bool remove_escapes )
943 {
944 std::string ews( ws ) ; // escape+whitespace
945 if( escape != '\0' ) ews.append( 1U , escape ) ;
946 if( in_in.length() )
947 {
948 std::string in = in_in ;
949 size_t start = 0U ;
950 size_t pos = 0U ;
951 for(;;)
952 {
953 if( pos >= in.length() ) break ;
954 pos = in.find_first_of( ews , pos ) ;
955 if( pos == std::string::npos ) break ;
956 if( in.at(pos) == escape )
957 {
958 if( remove_escapes )
959 in.erase( pos , 1U ) ;
960 else
961 pos++ ;
962 pos++ ;
963 }
964 else
965 {
966 out.push_back( in.substr(start,pos-start) ) ;
967 pos++ ;
968 start = pos ;
969 }
970 }
971 out.push_back( in.substr(start,pos-start) ) ;
972 }
973 }
974 }
975 void G::Str::splitIntoFields( const std::string & in , StringArray & out , const std::string & ws ,
976 char escape , bool remove_escapes )
977 {
978 splitIntoFields_( in , out , ws , escape , remove_escapes ) ;
979 }
980 G::StringArray G::Str::splitIntoFields( const std::string & in , const std::string & ws )
981 {
982 G::StringArray out ;
983 splitIntoFields_( in , out , ws ) ;
984 return out ;
985 }
986
987 namespace
988 {
989 template <typename T>
990 struct Joiner : std::unary_function<const T&,void>
991 {
992 T & result ;
993 const T & sep ;
994 bool & first ;
995 Joiner( T & result_ , const T & sep_ , bool & first_ ) :
996 result(result_) ,
997 sep(sep_) ,
998 first(first_)
999 {
1000 first = true ;
1001 }
1002 void operator()( const T & s )
1003 {
1004 if( !first ) result.append( sep ) ;
1005 result.append( s ) ;
1006 first = false ;
1007 }
1008 } ;
1009 }
1010
1011 std::string G::Str::join( const std::string & sep , const StringMap & map ,
1012 const std::string & pre_in , const std::string & post )
1013 {
1014 std::string pre = pre_in.empty() ? std::string("=") : pre_in ;
1015 std::string result ;
1016 bool first = true ;
1017 Joiner<std::string> joiner( result , sep , first ) ;
1018 for( StringMap::const_iterator p = map.begin() ; p != map.end() ; ++p )
1019 joiner( (*p).first + pre + (*p).second + post ) ;
1020 return result ;
1021 }
1022
1023 std::string G::Str::join( const std::string & sep , const StringArray & strings )
1024 {
1025 std::string result ;
1026 bool first = true ;
1027 std::for_each( strings.begin() , strings.end() , Joiner<std::string>(result,sep,first) ) ;
1028 return result ;
1029 }
1030
1031 std::string G::Str::join( const std::string & sep , const std::set<std::string> & strings )
1032 {
1033 std::string result ;
1034 bool first = true ;
1035 std::for_each( strings.begin() , strings.end() , Joiner<std::string>(result,sep,first) ) ;
1036 return result ;
1037 }
1038
1039 std::string G::Str::join( const std::string & sep , const std::string & s1 , const std::string & s2 ,
1040 const std::string & s3 , const std::string & s4 , const std::string & s5 , const std::string & s6 ,
1041 const std::string & s7 , const std::string & s8 , const std::string & s9 )
1042 {
1043 std::string result ;
1044 joinImp( sep , result , s1 ) ;
1045 joinImp( sep , result , s2 ) ;
1046 joinImp( sep , result , s3 ) ;
1047 joinImp( sep , result , s4 ) ;
1048 joinImp( sep , result , s5 ) ;
1049 joinImp( sep , result , s6 ) ;
1050 joinImp( sep , result , s7 ) ;
1051 joinImp( sep , result , s8 ) ;
1052 joinImp( sep , result , s9 ) ;
1053 return result ;
1054 }
1055
1056 void G::Str::joinImp( const std::string & sep , std::string & result , const std::string & s )
1057 {
1058 if( !result.empty() && !s.empty() )
1059 result.append( sep ) ;
1060 result.append( s ) ;
1061 }
1062
1063 namespace
1064 {
1065 template <typename T>
1066 struct Firster : std::unary_function<const T&,const typename T::first_type&>
1067 {
1068 const typename T::first_type & operator()( const T & pair ) { return pair.first ; }
1069 } ;
1070 }
1071 std::set<std::string> G::Str::keySet( const StringMap & map )
1072 {
1073 std::set<std::string> result ;
1074 std::transform( map.begin() , map.end() , std::inserter(result,result.end()) , Firster<StringMap::value_type>() ) ;
1075 return result ;
1076 }
1077
1078 std::string G::Str::ws()
1079 {
1080 return std::string(" \t\n\r") ;
1081 }
1082
1083 std::string G::Str::meta()
1084 {
1085 return std::string("~<>[]*$|?\\(){}\"`'&;=") ; // bash meta-characters plus "~"
1086 }
1087
1088 std::string G::Str::head( const std::string & in , std::string::size_type pos , const std::string & default_ )
1089 {
1090 return
1091 pos == std::string::npos ?
1092 default_ :
1093 ( pos == 0U ? std::string() : ( pos >= in.length() ? in : in.substr(0U,pos) ) ) ;
1094 }
1095
1096 std::string G::Str::head( const std::string & in , const std::string & sep , bool default_empty )
1097 {
1098 size_t pos = sep.empty() ? std::string::npos : in.find( sep ) ;
1099 return head( in , pos , default_empty ? std::string() : in ) ;
1100 }
1101
1102 std::string G::Str::tail( const std::string & in , std::string::size_type pos , const std::string & default_ )
1103 {
1104 return
1105 pos == std::string::npos ?
1106 default_ :
1107 ( (pos+1U) >= in.length() ? std::string() : in.substr(pos+1U) ) ;
1108 }
1109
1110 std::string G::Str::tail( const std::string & in , const std::string & sep , bool default_empty )
1111 {
1112 size_t pos = sep.empty() ? std::string::npos : in.find(sep) ;
1113 if( pos != std::string::npos ) pos += (sep.length()-1U) ;
1114 return tail( in , pos , default_empty ? std::string() : in ) ;
1115 }
1116
1117 bool G::Str::tailMatch( const std::string & in , const std::string & tail )
1118 {
1119 return
1120 tail.empty() ||
1121 ( in.length() >= tail.length() && 0 == in.compare(in.length()-tail.length(),tail.length(),tail) ) ;
1122 }
1123
1124 namespace
1125 {
1126 struct TailMatch
1127 {
1128 const std::string & m_tail ;
1129 TailMatch( const std::string & s ) : m_tail(s) {}
1130 bool operator()( const std::string & s ) const { return G::Str::tailMatch(s,m_tail) ; }
1131 } ;
1132 }
1133 bool G::Str::tailMatch( const StringArray & in , const std::string & tail )
1134 {
1135 TailMatch matcher( tail ) ;
1136 return std::find_if( in.begin() , in.end() , matcher ) != in.end() ;
1137 }
1138
1139 bool G::Str::headMatch( const std::string & in , const std::string & head )
1140 {
1141 return
1142 head.empty() ||
1143 ( in.length() >= head.length() && 0 == in.compare(0U,head.length(),head) ) ;
1144 }
1145
1146 namespace
1147 {
1148 struct HeadMatch
1149 {
1150 const std::string & m_head ;
1151 HeadMatch( const std::string & s ) : m_head(s) {}
1152 bool operator()( const std::string & s ) const { return G::Str::headMatch(s,m_head) ; }
1153 } ;
1154 }
1155 bool G::Str::headMatch( const StringArray & in , const std::string & head )
1156 {
1157 HeadMatch matcher( head ) ;
1158 return std::find_if( in.begin() , in.end() , matcher ) != in.end() ;
1159 }
1160
1161 std::string G::Str::headMatchResidue( const StringArray & in , const std::string & head )
1162 {
1163 G::StringArray::const_iterator const end = in.end() ;
1164 for( G::StringArray::const_iterator p = in.begin() ; p != end ; ++p )
1165 {
1166 if( headMatch( *p , head ) )
1167 return (*p).substr( head.length() ) ;
1168 }
1169 return std::string() ;
1170 }
1171
1172 std::string G::Str::positive()
1173 {
1174 return "yes" ;
1175 }
1176
1177 std::string G::Str::negative()
1178 {
1179 return "no" ;
1180 }
1181
1182 bool G::Str::isPositive( const std::string & s_in )
1183 {
1184 std::string s = trimmed( lower(s_in) , ws() ) ;
1185 return !s.empty() && ( s == "y" || s == "yes" || s == "t" || s == "true" || s == "1" || s == "on" ) ;
1186 }
1187
1188 bool G::Str::isNegative( const std::string & s_in )
1189 {
1190 std::string s = trimmed( lower(s_in) , ws() ) ;
1191 return !s.empty() && ( s == "n" || s == "no" || s == "f" || s == "false" || s == "0" || s == "off" ) ;
1192 }
1193
1194 bool G::Str::match( const std::string & a , const std::string & b )
1195 {
1196 return a == b ;
1197 }
1198
1199 bool G::Str::match( const StringArray & a , const std::string & b )
1200 {
1201 StringArray::const_iterator const end = a.end() ;
1202 for( StringArray::const_iterator p = a.begin() ; p != end ; ++p )
1203 {
1204 if( match(*p,b) )
1205 return true ;
1206 }
1207 return false ;
1208 }
1209
1210 namespace
1211 {
1212 bool icompare( char c1 , char c2 )
1213 {
1214 if( c1 >= 'A' && c1 <= 'Z' ) c1 += '\x20' ;
1215 if( c2 >= 'A' && c2 <= 'Z' ) c2 += '\x20' ;
1216 return c1 == c2 ;
1217 }
1218 }
1219
1220 bool G::Str::imatch( const std::string & a , const std::string & b )
1221 {
1222 return a.size() == b.size() && std::equal( a.begin() , a.end() , b.begin() , icompare ) ;
1223 }
1224
1225 bool G::Str::imatch( const StringArray & a , const std::string & b )
1226 {
1227 StringArray::const_iterator const end = a.end() ;
1228 for( StringArray::const_iterator p = a.begin() ; p != end ; ++p )
1229 {
1230 if( imatch(*p,b) )
1231 return true ;
1232 }
1233 return false ;
1234 }
1235
1236 std::string::size_type G::Str::ifind( const std::string & s , const std::string & key , std::string::size_type pos )
1237 {
1238 if( s.empty() || key.empty() || pos > s.length() ) return std::string::npos ;
1239 std::string::const_iterator p = std::search( s.begin()+pos , s.end() , key.begin() , key.end() , icompare ) ;
1240 return p == s.end() ? std::string::npos : std::distance(s.begin(),p) ;
1241 }
1242
1243 namespace
1244 {
1245 template <typename T, typename V>
1246 T unique_imp( T in , T end , V repeat , V replacement )
1247 {
1248 // replace repeated repeat-s with a single replacement
1249 T out = in ;
1250 while( in != end )
1251 {
1252 T in_next = in ; ++in_next ;
1253 if( *in == repeat && *in_next == repeat )
1254 {
1255 while( *in == repeat )
1256 ++in ;
1257 *out++ = replacement ;
1258 }
1259 else
1260 {
1261 *out++ = *in++ ;
1262 }
1263 }
1264 return out ; // new end
1265 }
1266 }
1267
1268 std::string G::Str::unique( std::string s , char c , char r )
1269 {
1270 s.erase( unique_imp( s.begin() , s.end() , c , r ) , s.end() ) ;
1271 return s ;
1272 }
1273
1274 /// \file gstr.cpp
G::Str::toULong
static unsigned long toULong(const std::string &s, Limited)
Converts string 's' to an unsigned long.
Definition: gstr.cpp:509
G::Str::positive
static std::string positive()
Returns a default positive string. See isPositive().
Definition: gstr.cpp:1172
G::Str::fromBool
static std::string fromBool(bool b)
Converts boolean 'b' to a string.
Definition: gstr.cpp:320
G::Str::ifind
static size_type ifind(const std::string &s, const std::string &key, size_type pos=0U)
Returns the position of the key in 's' using a Latin-1 case-insensitive search.
Definition: gstr.cpp:1236
G::Str::printable
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:701
G::Str::toBool
static bool toBool(const std::string &s)
Converts string 's' to a bool.
Definition: gstr.cpp:374
G::Str::tail
static std::string tail(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:1102
G::Str::toInt
static int toInt(const std::string &s)
Converts string 's' to an int.
Definition: gstr.cpp:406
G::Str::wrap
static std::string wrap(std::string text, const std::string &prefix_first_line, const std::string &prefix_subsequent_lines, size_type width=70U)
Does word-wrapping.
Definition: gstr.cpp:827
G::Str::tailMatch
static bool tailMatch(const std::string &in, const std::string &ending)
Returns true if the string has the given ending (or ending is empty).
Definition: gstr.cpp:1117
G::Str::head
static std::string head(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:1088
G::Str::isPositive
static bool isPositive(const std::string &)
Returns true if the string has a positive meaning, such as "1", "true", "yes".
Definition: gstr.cpp:1182
G::Str::fromDouble
static std::string fromDouble(double d)
Converts double 'd' to a string.
Definition: gstr.cpp:325
G::Str::dequote
static std::string dequote(const std::string &, char qq= '\"' , char esc = '\\' , const std::string & ws = Str::ws() )
Dequotes a string by removing unescaped quotes and escaping quoted whitespace, so "qq-aaa-esc-qq-bbb-...
Definition: gstr.cpp:99
G::Str::imatch
static bool imatch(const std::string &, const std::string &)
Returns true if the two strings are the same, ignoring Latin-1 case.
Definition: gstr.cpp:1220
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
G::Str::replace
static bool replace(std::string &s, const std::string &from, const std::string &to, size_type *pos_p=nullptr)
Replaces 'from' with 'to', starting at offset '*pos_p'.
Definition: gstr.cpp:172
G::Str::splitIntoTokens
static void splitIntoTokens(const std::string &in, StringArray &out, const std::string &ws)
Splits the string into 'ws'-delimited tokens.
Definition: gstr.cpp:908
std
STL namespace.
G::Str::toShort
static short toShort(const std::string &s)
Converts string 's' to a short.
Definition: gstr.cpp:450
G::Str::headMatch
static bool headMatch(const std::string &in, const std::string &head)
Returns true if the string has the given start (or head is empty).
Definition: gstr.cpp:1139
G::Str::isNumeric
static bool isNumeric(const std::string &s, bool allow_minus_sign=false)
Returns true if every character is a decimal digit.
Definition: gstr.cpp:266
G::Str::escape
static void escape(std::string &s, char c_escape, const std::string &specials_in, const std::string &specials_out)
Prefixes each occurrence of one of the special-in characters with the escape character and its corres...
Definition: gstr.cpp:66
G::Str::fromInt
static std::string fromInt(int i)
Converts int 'i' to a string.
Definition: gstr.cpp:332
G::Str::trim
static void trim(std::string &s, const std::string &ws)
Trims both ends of s, taking off any of the 'ws' characters.
Definition: gstr.cpp:246
G::Str::trimLeft
static void trimLeft(std::string &s, const std::string &ws, size_type limit=0U)
Trims the lhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:224
G::Str::fromLong
static std::string fromLong(long l)
Converts long 'l' to a string.
Definition: gstr.cpp:339
G::Str::lower
static std::string lower(const std::string &s)
Returns a copy of 's' in which all Latin-1 uppercase characters have been replaced by lowercase chara...
Definition: gstr.cpp:599
G::Str::toUInt
static unsigned int toUInt(const std::string &s)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:488
G::Str::escaped
static std::string escaped(const std::string &, char c_escape, const std::string &specials_in, const std::string &specials_out)
Returns the escape()d string.
Definition: gstr.cpp:41
G::Str::toLower
static void toLower(std::string &s)
Replaces all Latin-1 uppercase characters in string 's' by lowercase characters.
Definition: gstr.cpp:594
G::Str::fromUInt
static std::string fromUInt(unsigned int ui)
Converts unsigned int 'ui' to a string.
Definition: gstr.cpp:353
gstr.h
G::Str::replaceAll
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurances of sub-string 'from' with 'to'...
Definition: gstr.cpp:195
G::Str::trimRight
static void trimRight(std::string &s, const std::string &ws, size_type limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:235
G::Str::isInt
static bool isInt(const std::string &s)
Returns true if the string can be converted into an integer without throwing an exception.
Definition: gstr.cpp:288
G::Str::unique
static std::string unique(std::string s, char c= ' ', char r= ' ')
Returns a string with repeated 'c' characters replaced by one 'r' character.
Definition: gstr.cpp:1268
G::Str::toDouble
static double toDouble(const std::string &s)
Converts string 's' to a double.
Definition: gstr.cpp:392
G::Str::headMatchResidue
static std::string headMatchResidue(const StringArray &in, const std::string &head)
Returns the unmatched part of the first string in the array that has the given start.
Definition: gstr.cpp:1161
G::Str::fromShort
static std::string fromShort(short s)
Converts short 's' to a string.
Definition: gstr.cpp:346
G::Str::isUShort
static bool isUShort(const std::string &s)
Returns true if the string can be converted into an unsigned short without throwing an exception...
Definition: gstr.cpp:296
G::Str::upper
static std::string upper(const std::string &s)
Returns a copy of 's' in which all Latin-1 lowercase characters have been replaced by uppercase chara...
Definition: gstr.cpp:619
G::Str::fromUShort
static std::string fromUShort(unsigned short us)
Converts unsigned short 'us' to a string.
Definition: gstr.cpp:367
G::Str::match
static bool match(const std::string &, const std::string &)
Returns true if the two strings are the same.
Definition: gstr.cpp:1194
G::Str::trimmed
static std::string trimmed(const std::string &s, const std::string &ws)
Returns a trim()med version of s.
Definition: gstr.cpp:251
G::Str::readLineFrom
static std::string readLineFrom(std::istream &stream, const std::string &eol=std::string())
Reads a line from the stream using the given line terminator.
Definition: gstr.cpp:733
G::Str::Limited
Overload discrimiator for G::Str::toUWhatever()
Definition: gstr.h:50
G::Str::isNegative
static bool isNegative(const std::string &)
Returns true if the string has a negative meaning, such as "0", "false", "no".
Definition: gstr.cpp:1188
G::Str::unescape
static void unescape(std::string &s, char c_escape, const char *specials_in, const char *specials_out)
Unescapes the string by replacing e-e with e, e-special-in with special-out, and e-other with other...
Definition: gstr.cpp:142
G::Str::isPrintableAscii
static bool isPrintableAscii(const std::string &s)
Returns true if every character is a 7-bit, non-control character (ie.
Definition: gstr.cpp:282
G::StringMap
std::map< std::string, std::string > StringMap
A std::map of std::strings.
Definition: gstrings.h:34
G::Str::join
static std::string join(const std::string &sep, const StringArray &strings)
Concatenates an array of strings with separators.
Definition: gstr.cpp:1023
G::Str::toLong
static long toLong(const std::string &s)
Converts string 's' to a long.
Definition: gstr.cpp:427
G::Str::toUShort
static unsigned short toUShort(const std::string &s, Limited)
Converts string 's' to an unsigned short.
Definition: gstr.cpp:553
G::Str::negative
static std::string negative()
Returns a default negative string. See isNegative().
Definition: gstr.cpp:1177
G::Str::isUInt
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
Definition: gstr.cpp:304
G::Str::removeAll
static void removeAll(std::string &, char)
Removes all occurrences of the character from the string.
Definition: gstr.cpp:218
G::Str::keySet
static std::set< std::string > keySet(const StringMap &string_map)
Extracts the keys from a map of strings.
Definition: gstr.cpp:1071
G::Str::splitIntoFields
static void splitIntoFields(const std::string &in, StringArray &out, const std::string &separators, char escape= '\0', bool remove_escapes=true)
Splits the string into fields.
Definition: gstr.cpp:975
G::Str::isULong
static bool isULong(const std::string &s)
Returns true if the string can be converted into an unsigned long without throwing an exception...
Definition: gstr.cpp:312
G::Str::fromULong
static std::string fromULong(unsigned long ul)
Converts unsigned long 'ul' to a string.
Definition: gstr.cpp:360
G::Str::unescaped
static std::string unescaped(const std::string &s)
Returns the unescape()d version of s.
Definition: gstr.cpp:165
G::Str::meta
static std::string meta()
Returns a list of shell meta-characters with a tilde as the first character.
Definition: gstr.cpp:1083
G::Str::ws
static std::string ws()
Returns a string of standard whitespace characters.
Definition: gstr.cpp:1078
G::Str::toPrintableAscii
static std::string toPrintableAscii(char c, char escape= '\\')
Returns a 7-bit printable representation of the given input character.
Definition: gstr.cpp:717
gdebug.h
G::Str::toUpper
static void toUpper(std::string &s)
Replaces all Latin-1 lowercase characters in string 's' by uppercase characters.
Definition: gstr.cpp:614