MongoDB  2.7.0
str.h
1 // @file str.h
2 
3 /* Copyright 2010 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 /* Things in the mongoutils namespace
21  (1) are not database specific, rather, true utilities
22  (2) are cross platform
23  (3) may require boost headers, but not libs
24  (4) are clean and easy to use in any c++ project without pulling in lots of other stuff
25 
26  Note: within this module, we use int for all offsets -- there are no unsigned offsets
27  and no size_t's. If you need 3 gigabyte long strings, don't use this module.
28 */
29 
30 #include <string>
31 #include <sstream>
32 
33 // this violates the README rules for mongoutils:
34 #include "mongo/bson/util/builder.h"
35 
36 namespace mongoutils {
37 
38  namespace str {
39 
48  class stream {
49  public:
51  template<class T>
52  stream& operator<<(const T& v) {
53  ss << v;
54  return *this;
55  }
56  operator std::string () const { return ss.str(); }
57  };
58 
59  inline bool startsWith(const char *str, const char *prefix) {
60  const char *s = str;
61  const char *p = prefix;
62  while( *p ) {
63  if( *p != *s ) return false;
64  p++; s++;
65  }
66  return true;
67  }
68  inline bool startsWith(const std::string& s, const std::string& p) {
69  return startsWith(s.c_str(), p.c_str());
70  }
71 
72  // while these are trivial today use in case we do different wide char things later
73  inline bool startsWith(const char *p, char ch) { return *p == ch; }
74  inline bool startsWith(const std::string& s, char ch) { return startsWith(s.c_str(), ch); }
75 
76  inline bool endsWith(const std::string& s, const std::string& p) {
77  int l = p.size();
78  int x = s.size();
79  if( x < l ) return false;
80  return strncmp(s.c_str()+x-l, p.c_str(), l) == 0;
81  }
82  inline bool endsWith(const char *s, char p) {
83  size_t len = strlen(s);
84  return len && s[len-1] == p;
85  }
86 
87  inline bool equals( const char * a , const char * b ) { return strcmp( a , b ) == 0; }
88 
90  inline const char * after(const char *s, char x) {
91  const char *p = strchr(s, x);
92  return (p != 0) ? p+1 : "";
93  }
94  inline std::string after(const std::string& s, char x) {
95  const char *p = strchr(s.c_str(), x);
96  return (p != 0) ? std::string(p+1) : "";
97  }
98 
100  inline const char * after(const char *s, const char *x) {
101  const char *p = strstr(s, x);
102  return (p != 0) ? p+strlen(x) : "";
103  }
104  inline std::string after(const std::string& s, const std::string& x) {
105  const char *p = strstr(s.c_str(), x.c_str());
106  return (p != 0) ? std::string(p+x.size()) : "";
107  }
108 
112  inline bool contains(const std::string& s, const std::string& x) {
113  return strstr(s.c_str(), x.c_str()) != 0;
114  }
115  inline bool contains(const std::string& s, char x) {
116  verify(x != '\0'); // this expects c-strings so don't use when looking for NUL bytes
117  return strchr(s.c_str(), x) != 0;
118  }
119 
121  inline std::string before(const std::string& s, char x) {
122  const char *p = strchr(s.c_str(), x);
123  return (p != 0) ? s.substr(0, p-s.c_str()) : s;
124  }
125 
127  inline std::string before(const std::string& s, const std::string& x) {
128  const char *p = strstr(s.c_str(), x.c_str());
129  return (p != 0) ? s.substr(0, p-s.c_str()) : s;
130  }
131 
134  inline int shareCommonPrefix(const char *p, const char *q) {
135  int ofs = 0;
136  while( 1 ) {
137  if( *p == 0 || *q == 0 )
138  break;
139  if( *p != *q )
140  break;
141  p++; q++; ofs++;
142  }
143  return ofs;
144  }
145  inline int shareCommonPrefix(const std::string &a, const std::string &b)
146  { return shareCommonPrefix(a.c_str(), b.c_str()); }
147 
149  inline unsigned toUnsigned(const std::string& a) {
150  unsigned x = 0;
151  const char *p = a.c_str();
152  while( 1 ) {
153  if( !isdigit(*p) )
154  break;
155  x = x * 10 + (*p - '0');
156  p++;
157  }
158  return x;
159  }
160 
166  inline bool splitOn(const std::string &s, char c, std::string& L, std::string& R) {
167  const char *start = s.c_str();
168  const char *p = strchr(start, c);
169  if( p == 0 ) {
170  L = s; R.clear();
171  return false;
172  }
173  L = std::string(start, p-start);
174  R = std::string(p+1);
175  return true;
176  }
178  inline bool rSplitOn(const std::string &s, char c, std::string& L, std::string& R) {
179  const char *start = s.c_str();
180  const char *p = strrchr(start, c);
181  if( p == 0 ) {
182  L = s; R.clear();
183  return false;
184  }
185  L = std::string(start, p-start);
186  R = std::string(p+1);
187  return true;
188  }
189 
191  inline unsigned count( const std::string& s , char c ) {
192  unsigned n=0;
193  for ( unsigned i=0; i<s.size(); i++ )
194  if ( s[i] == c )
195  n++;
196  return n;
197  }
198 
200  inline std::string ltrim(const std::string& s) {
201  const char *p = s.c_str();
202  while( *p == ' ' ) p++;
203  return p;
204  }
205 
207  inline void stripTrailing(std::string& s, const char *chars) {
208  std::string::iterator i = s.end();
209  while( s.begin() != i ) {
210  i--;
211  if( contains(chars, *i) ) {
212  s.erase(i);
213  }
214  }
215  }
216 
217  }
218 
219 }
the idea here is to make one liners easy.
Definition: str.h:48
stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 ...
Definition: builder.h:61