MongoDB C++ Driver legacy-1.0.1
Loading...
Searching...
No Matches
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
27#include <string>
28#include <sstream>
29
30#include "mongo/bson/util/builder.h"
31
32namespace mongoutils {
33
34 namespace str {
35
44 class stream {
45 public:
47 template<class T>
48 stream& operator<<(const T& v) {
49 ss << v;
50 return *this;
51 }
52 operator std::string () const { return ss.str(); }
53 };
54
55 inline bool startsWith(const char *str, const char *prefix) {
56 const char *s = str;
57 const char *p = prefix;
58 while( *p ) {
59 if( *p != *s ) return false;
60 p++; s++;
61 }
62 return true;
63 }
64 inline bool startsWith(const std::string& s, const std::string& p) {
65 return startsWith(s.c_str(), p.c_str());
66 }
67
68 // while these are trivial today use in case we do different wide char things later
69 inline bool startsWith(const char *p, char ch) { return *p == ch; }
70 inline bool startsWith(const std::string& s, char ch) { return startsWith(s.c_str(), ch); }
71
72 inline bool endsWith(const std::string& s, const std::string& p) {
73 int l = p.size();
74 int x = s.size();
75 if( x < l ) return false;
76 return strncmp(s.c_str()+x-l, p.c_str(), l) == 0;
77 }
78 inline bool endsWith(const char *s, char p) {
79 size_t len = strlen(s);
80 return len && s[len-1] == p;
81 }
82 inline bool endsWith(const char *p, const char *suffix) {
83 size_t a = strlen(p);
84 size_t b = strlen(suffix);
85 if ( b > a ) return false;
86 return strcmp(p + a - b, suffix) == 0;
87 }
88
89 inline bool equals( const char * a , const char * b ) { return strcmp( a , b ) == 0; }
90
92 inline const char * after(const char *s, char x) {
93 const char *p = strchr(s, x);
94 return (p != 0) ? p+1 : "";
95 }
96 inline std::string after(const std::string& s, char x) {
97 const char *p = strchr(s.c_str(), x);
98 return (p != 0) ? std::string(p+1) : "";
99 }
100
102 inline const char * after(const char *s, const char *x) {
103 const char *p = strstr(s, x);
104 return (p != 0) ? p+strlen(x) : "";
105 }
106 inline std::string after(const std::string& s, const std::string& x) {
107 const char *p = strstr(s.c_str(), x.c_str());
108 return (p != 0) ? std::string(p+x.size()) : "";
109 }
110
114 inline bool contains(const std::string& s, const std::string& x) {
115 return strstr(s.c_str(), x.c_str()) != 0;
116 }
117 inline bool contains(const std::string& s, char x) {
118 verify(x != '\0'); // this expects c-strings so don't use when looking for NUL bytes
119 return strchr(s.c_str(), x) != 0;
120 }
121
123 inline std::string before(const std::string& s, char x) {
124 const char *p = strchr(s.c_str(), x);
125 return (p != 0) ? s.substr(0, p-s.c_str()) : s;
126 }
127
129 inline std::string before(const std::string& s, const std::string& x) {
130 const char *p = strstr(s.c_str(), x.c_str());
131 return (p != 0) ? s.substr(0, p-s.c_str()) : s;
132 }
133
136 inline int shareCommonPrefix(const char *p, const char *q) {
137 int ofs = 0;
138 while( 1 ) {
139 if( *p == 0 || *q == 0 )
140 break;
141 if( *p != *q )
142 break;
143 p++; q++; ofs++;
144 }
145 return ofs;
146 }
147 inline int shareCommonPrefix(const std::string &a, const std::string &b)
148 { return shareCommonPrefix(a.c_str(), b.c_str()); }
149
151 inline unsigned toUnsigned(const std::string& a) {
152 unsigned x = 0;
153 const char *p = a.c_str();
154 while( 1 ) {
155 if( !isdigit(*p) )
156 break;
157 x = x * 10 + (*p - '0');
158 p++;
159 }
160 return x;
161 }
162
168 inline bool splitOn(const std::string &s, char c, std::string& L, std::string& R) {
169 const char *start = s.c_str();
170 const char *p = strchr(start, c);
171 if( p == 0 ) {
172 L = s; R.clear();
173 return false;
174 }
175 L = std::string(start, p-start);
176 R = std::string(p+1);
177 return true;
178 }
180 inline bool rSplitOn(const std::string &s, char c, std::string& L, std::string& R) {
181 const char *start = s.c_str();
182 const char *p = strrchr(start, c);
183 if( p == 0 ) {
184 L = s; R.clear();
185 return false;
186 }
187 L = std::string(start, p-start);
188 R = std::string(p+1);
189 return true;
190 }
191
193 inline unsigned count( const std::string& s , char c ) {
194 unsigned n=0;
195 for ( unsigned i=0; i<s.size(); i++ )
196 if ( s[i] == c )
197 n++;
198 return n;
199 }
200
202 inline std::string ltrim(const std::string& s) {
203 const char *p = s.c_str();
204 while( *p == ' ' ) p++;
205 return p;
206 }
207
209 inline void stripTrailing(std::string& s, const char *chars) {
210 std::string::iterator to = s.begin();
211 for ( std::string::iterator i = s.begin(); i != s.end(); i++ ) {
212 // During each iteration if i finds a non-"chars" character it writes it to the
213 // position of t. So the part of the string left from the "to" iterator is already
214 // "cleared" string.
215 if ( !contains(chars, *i) ) {
216 if ( i != to )
217 s.replace(to, to + 1, 1, *i);
218 to++;
219 }
220 }
221 s.erase(to, s.end());
222 }
223
224 } // namespace str
225
226} // namespace mongoutils
227
228namespace mongo {
229 using namespace mongoutils;
230
231#if defined(_WIN32)
232 inline int strcasecmp(const char* s1, const char* s2) {return _stricmp(s1, s2);}
233#endif
234
235} // namespace mongo
std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8
Definition builder.h:299
the idea here is to make one liners easy.
Definition str.h:44
the main MongoDB namespace
Definition bulk_operation_builder.h:24
String utilities.
Definition str.h:32