X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmisc%2Fstrutils.cxx;h=8bd33b7f507686233140ce7e68ab8a17cf52767b;hb=e4e31be7d43569a92a5d9fa7e784381b66cbd95a;hp=17e39c95eaf4ca29a027f0ad0836ee42f918ad52;hpb=5173d709e090b953eaf800cbcd1bf897de332a12;p=simgear.git diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index 17e39c95..8bd33b7f 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -1,71 +1,264 @@ // String utilities. // -// Written by Bernie Bright, 1998 +// Written by Bernie Bright, started 1998 // -// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// Copyright (C) 1998 Bernie Bright - bbright@bigpond.net.au // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. // -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. +// Library General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ -#ifdef HAVE_CONFIG_H -# include -#endif +#include +#include +#include #include "strutils.hxx" -const string whitespace = " \n\r\t"; +using std::string; +using std::vector; +using std::stringstream; -// -string -trimleft( const string& s, const string& trimmings ) -{ - string result; - string::size_type pos = s.find_first_not_of( trimmings ); - if ( pos != string::npos ) - { - result.assign( s.substr( pos ) ); - } +namespace simgear { + namespace strutils { - return result; -} + /** + * + */ + static vector + split_whitespace( const string& str, int maxsplit ) + { + vector result; + string::size_type len = str.length(); + string::size_type i = 0; + string::size_type j; + int countsplit = 0; -// -string -trimright( const string& s, const string& trimmings ) -{ - string result; + while (i < len) + { + while (i < len && isspace((unsigned char)str[i])) + { + ++i; + } + + j = i; + + while (i < len && !isspace((unsigned char)str[i])) + { + ++i; + } + + if (j < i) + { + result.push_back( str.substr(j, i-j) ); + ++countsplit; + while (i < len && isspace((unsigned char)str[i])) + { + ++i; + } + + if (maxsplit && (countsplit >= maxsplit) && i < len) + { + result.push_back( str.substr( i, len-i ) ); + i = len; + } + } + } + + return result; + } + + /** + * + */ + vector + split( const string& str, const char* sep, int maxsplit ) + { + if (sep == 0) + return split_whitespace( str, maxsplit ); + + vector result; + int n = std::strlen( sep ); + if (n == 0) + { + // Error: empty separator string + return result; + } + const char* s = str.c_str(); + string::size_type len = str.length(); + string::size_type i = 0; + string::size_type j = 0; + int splitcount = 0; + + while (i+n <= len) + { + if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0)) + { + result.push_back( str.substr(j,i-j) ); + i = j = i + n; + ++splitcount; + if (maxsplit && (splitcount >= maxsplit)) + break; + } + else + { + ++i; + } + } + + result.push_back( str.substr(j,len-j) ); + return result; + } + + /** + * The lstrip(), rstrip() and strip() functions are implemented + * in do_strip() which uses an additional parameter to indicate what + * type of strip should occur. + */ + const int LEFTSTRIP = 0; + const int RIGHTSTRIP = 1; + const int BOTHSTRIP = 2; - string::size_type pos = s.find_last_not_of( trimmings ); - if ( pos == string::npos ) + static string + do_strip( const string& s, int striptype ) + { + string::size_type len = s.length(); + if( len == 0 ) // empty string is trivial + return s; + string::size_type i = 0; + if (striptype != RIGHTSTRIP) + { + while (i < len && isspace(s[i])) + { + ++i; + } + } + + string::size_type j = len; + if (striptype != LEFTSTRIP) + { + do + { + --j; + } + while (j >= 1 && isspace(s[j])); + ++j; + } + + if (i == 0 && j == len) + { + return s; + } + else + { + return s.substr( i, j - i ); + } + } + + string + lstrip( const string& s ) + { + return do_strip( s, LEFTSTRIP ); + } + + string + rstrip( const string& s ) + { + return do_strip( s, RIGHTSTRIP ); + } + + string + strip( const string& s ) + { + return do_strip( s, BOTHSTRIP ); + } + + string + rpad( const string & s, string::size_type length, char c ) + { + string::size_type l = s.length(); + if( l >= length ) return s; + string reply = s; + return reply.append( length-l, c ); + } + + string + lpad( const string & s, size_t length, char c ) + { + string::size_type l = s.length(); + if( l >= length ) return s; + string reply = s; + return reply.insert( 0, length-l, c ); + } + + bool + starts_with( const string & s, const string & substr ) + { + return s.find( substr ) == 0; + } + + bool + ends_with( const string & s, const string & substr ) + { + size_t n = s.rfind( substr ); + return (n != string::npos) && (n == s.length() - substr.length()); + } + + string simplify(const string& s) { - // Not found, return the original string. - result = s; + string result; // reserve size of 's'? + string::const_iterator it = s.begin(), + end = s.end(); + + // advance to first non-space char - simplifes logic in main loop, + // since we can always prepend a single space when we see a + // space -> non-space transition + for (; (it != end) && isspace(*it); ++it) { /* nothing */ } + + bool lastWasSpace = false; + for (; it != end; ++it) { + char c = *it; + if (isspace(c)) { + lastWasSpace = true; + continue; + } + + if (lastWasSpace) { + result.push_back(' '); + } + + lastWasSpace = false; + result.push_back(c); + } + + return result; } - else + + int to_int(const std::string& s, int base) { - result.assign( s.substr( 0, pos+1 ) ); + stringstream ss(s); + switch (base) { + case 8: ss >> std::oct; break; + case 16: ss >> std::hex; break; + default: break; + } + + int result; + ss >> result; + return result; } - - return result; -} - -// -string -trim( const string& s, const string& trimmings ) -{ - return trimright( trimleft( s, trimmings ), trimmings ); -} - + + } // end namespace strutils + +} // end namespace simgear