MongoDB  2.0.3
str.h
00001 // @file str.h
00002 
00003 /*    Copyright 2010 10gen Inc.
00004  *
00005  *    Licensed under the Apache License, Version 2.0 (the "License");
00006  *    you may not use this file except in compliance with the License.
00007  *    You may obtain a copy of the License at
00008  *
00009  *    http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  *    Unless required by applicable law or agreed to in writing, software
00012  *    distributed under the License is distributed on an "AS IS" BASIS,
00013  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *    See the License for the specific language governing permissions and
00015  *    limitations under the License.
00016  */
00017 
00018 #pragma once
00019 
00020 /* Things in the mongoutils namespace
00021    (1) are not database specific, rather, true utilities
00022    (2) are cross platform
00023    (3) may require boost headers, but not libs
00024    (4) are clean and easy to use in any c++ project without pulling in lots of other stuff
00025 
00026    Note: within this module, we use int for all offsets -- there are no unsigned offsets
00027    and no size_t's.  If you need 3 gigabyte long strings, don't use this module.
00028 */
00029 
00030 #include <string>
00031 #include <sstream>
00032 
00033 // this violates the README rules for mongoutils:
00034 #include "../../bson/util/builder.h"
00035 
00036 namespace mongoutils {
00037 
00038     namespace str {
00039 
00040         typedef std::string string;
00041 
00050         class stream {
00051         public:
00052             mongo::StringBuilder ss;
00053             template<class T>
00054             stream& operator<<(const T& v) {
00055                 ss << v;
00056                 return *this;
00057             }
00058             operator std::string () const { return ss.str(); }
00059         };
00060 
00061         inline bool startsWith(const char *str, const char *prefix) {
00062             const char *s = str;
00063             const char *p = prefix;
00064             while( *p ) {
00065                 if( *p != *s ) return false;
00066                 p++; s++;
00067             }
00068             return true;
00069         }
00070         inline bool startsWith(string s, string p) { return startsWith(s.c_str(), p.c_str()); }
00071 
00072         inline bool endsWith(string s, string p) {
00073             int l = p.size();
00074             int x = s.size();
00075             if( x < l ) return false;
00076             return strncmp(s.c_str()+x-l, p.c_str(), l) == 0;
00077         }
00078 
00079         inline bool equals( const char * a , const char * b ) { return strcmp( a , b ) == 0; }
00080 
00082         inline const char * after(const char *s, char x) {
00083             const char *p = strchr(s, x);
00084             return (p != 0) ? p+1 : "";
00085         }
00086         inline string after(const string& s, char x) {
00087             const char *p = strchr(s.c_str(), x);
00088             return (p != 0) ? string(p+1) : "";
00089         }
00090 
00092         inline const char * after(const char *s, const char *x) {
00093             const char *p = strstr(s, x);
00094             return (p != 0) ? p+strlen(x) : "";
00095         }
00096         inline string after(string s, string x) {
00097             const char *p = strstr(s.c_str(), x.c_str());
00098             return (p != 0) ? string(p+x.size()) : "";
00099         }
00100 
00102         inline bool contains(string s, string x) {
00103             return strstr(s.c_str(), x.c_str()) != 0;
00104         }
00105         inline bool contains(string s, char x) {
00106             return strchr(s.c_str(), x) != 0;
00107         }
00108 
00110         inline string before(const string& s, char x) {
00111             const char *p = strchr(s.c_str(), x);
00112             return (p != 0) ? s.substr(0, p-s.c_str()) : s;
00113         }
00114 
00116         inline string before(const string& s, const string& x) {
00117             const char *p = strstr(s.c_str(), x.c_str());
00118             return (p != 0) ? s.substr(0, p-s.c_str()) : s;
00119         }
00120 
00123         inline int shareCommonPrefix(const char *p, const char *q) {
00124             int ofs = 0;
00125             while( 1 ) {
00126                 if( *p == 0 || *q == 0 )
00127                     break;
00128                 if( *p != *q )
00129                     break;
00130                 p++; q++; ofs++;
00131             }
00132             return ofs;
00133         }
00134         inline int shareCommonPrefix(const string &a, const string &b)
00135         { return shareCommonPrefix(a.c_str(), b.c_str()); }
00136 
00138         inline unsigned toUnsigned(const string& a) {
00139             unsigned x = 0;
00140             const char *p = a.c_str();
00141             while( 1 ) {
00142                 if( !isdigit(*p) )
00143                     break;
00144                 x = x * 10 + (*p - '0');
00145                 p++;
00146             }
00147             return x;
00148         }
00149 
00155         inline bool splitOn(const string &s, char c, string& L, string& R) {
00156             const char *start = s.c_str();
00157             const char *p = strchr(start, c);
00158             if( p == 0 ) {
00159                 L = s; R.clear();
00160                 return false;
00161             }
00162             L = string(start, p-start);
00163             R = string(p+1);
00164             return true;
00165         }
00167         inline bool rSplitOn(const string &s, char c, string& L, string& R) {
00168             const char *start = s.c_str();
00169             const char *p = strrchr(start, c);
00170             if( p == 0 ) {
00171                 L = s; R.clear();
00172                 return false;
00173             }
00174             L = string(start, p-start);
00175             R = string(p+1);
00176             return true;
00177         }
00178 
00180         inline unsigned count( const string& s , char c ) {
00181             unsigned n=0;
00182             for ( unsigned i=0; i<s.size(); i++ )
00183                 if ( s[i] == c )
00184                     n++;
00185             return n;
00186         }
00187 
00189         inline string ltrim(const string& s) {
00190             const char *p = s.c_str();
00191             while( *p == ' ' ) p++;
00192             return p;
00193         }
00194 
00196         inline void stripTrailing(string& s, const char *chars) {
00197             string::iterator i = s.end();
00198             while( s.begin() != i ) {
00199                 i--;
00200                 if( contains(chars, *i) ) {
00201                     s.erase(i);
00202                 }
00203             }
00204         }
00205 
00206     }
00207 
00208 }