1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
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, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef __UTIL_BASESTRING_HPP_INCLUDED__
26 #define __UTIL_BASESTRING_HPP_INCLUDED__
27
28 #include <ndb_global.h>
29 #include <util/Vector.hpp>
30 #include "Bitmask.hpp"
31
32 /**
33 * @class BaseString
34 * @brief Null terminated strings
35 */
36 class BaseString {
37 public:
38 /** @brief Constructs an empty string */
39 BaseString();
40
41 /** @brief Constructs a copy of a char * */
42 BaseString(const char* s);
43
44 /** @brief Constructs a copy of a char * with length */
45 BaseString(const char* s, size_t len);
46
47 /** @brief Constructs a copy of another BaseString */
48 BaseString(const BaseString& str);
49
50 /** @brief Destructor */
51 ~BaseString();
52
53 /** @brief Returns a C-style string */
54 const char* c_str() const;
55
56 /** @brief Returns the length of the string */
57 unsigned length() const;
58
59 /** @brief Checks if the string is empty */
60 bool empty() const;
61
62 /** @brief Clear a string */
63 void clear();
64
65 /** @brief Convert to uppercase */
66 BaseString& ndb_toupper();
67
68 /** @brief Convert to lowercase */
69 BaseString& ndb_tolower();
70
71 /** @brief Assigns from a char * */
72 BaseString& assign(const char* s);
73
74 /** @brief Assigns from another BaseString */
75 BaseString& assign(const BaseString& str);
76
77 /** @brief Assigns from char *s, with maximum length n */
78 BaseString& assign(const char* s, size_t n);
79
80 /** @brief Assigns from another BaseString, with maximum length n */
81 BaseString& assign(const BaseString& str, size_t n);
82
83 /**
84 * Assings from a Vector of BaseStrings, each Vector entry
85 * separated by separator.
86 *
87 * @param vector Vector of BaseStrings to append
88 * @param separator Separation between appended strings
89 */
90 BaseString& assign(const Vector<BaseString> &vector,
91 const BaseString &separator = BaseString(" "));
92
93 /** @brief Appends a char * to the end */
94 BaseString& append(const char* s);
95
96 /** @brief Appends a char to the end */
97 BaseString& append(char c);
98
99 /** @brief Appends another BaseString to the end */
100 BaseString& append(const BaseString& str);
101
102 /**
103 * Appends a Vector of BaseStrings to the end, each Vector entry
104 * separated by separator.
105 *
106 * @param vector Vector of BaseStrings to append
107 * @param separator Separation between appended strings
108 */
109 BaseString& append(const Vector<BaseString> &vector,
110 const BaseString &separator = BaseString(" "));
111
112 /** @brief Assigns from a format string a la printf() */
113 BaseString& assfmt(const char* ftm, ...)
114 ATTRIBUTE_FORMAT(printf, 2, 3);
115
116 /** @brief Appends a format string a la printf() to the end */
117 BaseString& appfmt(const char* ftm, ...)
118 ATTRIBUTE_FORMAT(printf, 2, 3);
119
120 /**
121 * Split a string into a vector of strings. Separate the string where
122 * any character included in separator exists.
123 * Maximally maxSize entries are added to the vector, if more separators
124 * exist in the string, the remainder of the string will be appended
125 * to the last entry in the vector.
126 * The vector will not be cleared, so any existing strings in the
127 * vector will remain.
128 *
129 * @param separator characters separating the entries
130 * @param vector where the separated strings will be stored
131 * @param maximum number of strings extracted
132 *
133 * @returns the number of string added to the vector
134 */
135 int split(Vector<BaseString> &vector,
136 const BaseString &separator = BaseString(" "),
137 int maxSize = -1) const;
138
139 /**
140 * Returns the index of the first occurance of the character c.
141 *
142 * @params c character to look for
143 * @returns index of character, of -1 if no character found
144 */
145 ssize_t indexOf(char c) const;
146
147 /**
148 * Returns the index of the last occurance of the character c.
149 *
150 * @params c character to look for
151 * @returns index of character, of -1 if no character found
152 */
153 ssize_t lastIndexOf(char c) const;
154
155 /**
156 * Returns a subset of a string
157 *
158 * @param start index of first character
159 * @param stop index of last character
160 * @return a new string
161 */
162 BaseString substr(ssize_t start, ssize_t stop = -1) const;
163
164 /**
165 * @brief Assignment operator
166 */
167 BaseString& operator=(const BaseString& str);
168
169 /** @brief Compare two strings */
170 bool operator<(const BaseString& str) const;
171 /** @brief Are two strings equal? */
172 bool operator==(const BaseString& str) const;
173 /** @brief Are two strings equal? */
174 bool operator==(const char *str) const;
175 /** @brief Are two strings not equal? */
176 bool operator!=(const BaseString& str) const;
177 /** @brief Are two strings not equal? */
178 bool operator!=(const char *str) const;
179
180 /**
181 * Trim string from <i>delim</i>
182 */
183 BaseString& trim(const char * delim = " \t");
184
185 /**
186 * Return c-array with strings suitable for execve
187 * When whitespace is detected, the characters '"' and '\' are honored,
188 * to make it possible to give arguments containing whitespace.
189 * The semantics of '"' and '\' match that of most Unix shells.
190 */
191 static char** argify(const char *argv0, const char *src);
192
193 /**
194 * Trim string from <i>delim</i>
195 */
196 static char* trim(char * src, const char * delim);
197
198 /**
199 * snprintf on some platforms need special treatment
200 */
201 static int snprintf(char *str, size_t size, const char *format, ...)
202 ATTRIBUTE_FORMAT(printf, 3, 4);
203 static int vsnprintf(char *str, size_t size, const char *format, va_list ap);
204
205 template<unsigned size>
getText(const Bitmask<size> & mask)206 static BaseString getText(const Bitmask<size>& mask) {
207 return BaseString::getText(size, mask.rep.data);
208 }
209
210 template<unsigned size>
getPrettyText(const Bitmask<size> & mask)211 static BaseString getPrettyText(const Bitmask<size>& mask) {
212 return BaseString::getPrettyText(size, mask.rep.data);
213 }
214 template<unsigned size>
getPrettyTextShort(const Bitmask<size> & mask)215 static BaseString getPrettyTextShort(const Bitmask<size>& mask) {
216 return BaseString::getPrettyTextShort(size, mask.rep.data);
217 }
218
219 template<unsigned size>
getText(const BitmaskPOD<size> & mask)220 static BaseString getText(const BitmaskPOD<size>& mask) {
221 return BaseString::getText(size, mask.rep.data);
222 }
223
224 template<unsigned size>
getPrettyText(const BitmaskPOD<size> & mask)225 static BaseString getPrettyText(const BitmaskPOD<size>& mask) {
226 return BaseString::getPrettyText(size, mask.rep.data);
227 }
228 template<unsigned size>
getPrettyTextShort(const BitmaskPOD<size> & mask)229 static BaseString getPrettyTextShort(const BitmaskPOD<size>& mask) {
230 return BaseString::getPrettyTextShort(size, mask.rep.data);
231 }
232
233 static BaseString getText(unsigned size, const Uint32 data[]);
234 static BaseString getPrettyText(unsigned size, const Uint32 data[]);
235 static BaseString getPrettyTextShort(unsigned size, const Uint32 data[]);
236
237 private:
238 char* m_chr;
239 unsigned m_len;
240 friend bool operator!(const BaseString& str);
241 };
242
243 inline const char*
c_str() const244 BaseString::c_str() const
245 {
246 return m_chr;
247 }
248
249 inline unsigned
length() const250 BaseString::length() const
251 {
252 return m_len;
253 }
254
255 inline bool
empty() const256 BaseString::empty() const
257 {
258 return m_len == 0;
259 }
260
261 inline void
clear()262 BaseString::clear()
263 {
264 delete[] m_chr;
265 m_chr = new char[1];
266 m_chr[0] = 0;
267 m_len = 0;
268 }
269
270 inline BaseString&
ndb_toupper()271 BaseString::ndb_toupper() {
272 for(unsigned i = 0; i < length(); i++)
273 m_chr[i] = toupper(m_chr[i]);
274 return *this;
275 }
276
277 inline BaseString&
ndb_tolower()278 BaseString::ndb_tolower() {
279 for(unsigned i = 0; i < length(); i++)
280 m_chr[i] = tolower(m_chr[i]);
281 return *this;
282 }
283
284 inline bool
operator <(const BaseString & str) const285 BaseString::operator<(const BaseString& str) const
286 {
287 return strcmp(m_chr, str.m_chr) < 0;
288 }
289
290 inline bool
operator ==(const BaseString & str) const291 BaseString::operator==(const BaseString& str) const
292 {
293 return strcmp(m_chr, str.m_chr) == 0;
294 }
295
296 inline bool
operator ==(const char * str) const297 BaseString::operator==(const char *str) const
298 {
299 return strcmp(m_chr, str) == 0;
300 }
301
302 inline bool
operator !=(const BaseString & str) const303 BaseString::operator!=(const BaseString& str) const
304 {
305 return strcmp(m_chr, str.m_chr) != 0;
306 }
307
308 inline bool
operator !=(const char * str) const309 BaseString::operator!=(const char *str) const
310 {
311 return strcmp(m_chr, str) != 0;
312 }
313
314 inline bool
operator !(const BaseString & str)315 operator!(const BaseString& str)
316 {
317 return str.m_chr == NULL;
318 }
319
320 inline BaseString&
assign(const BaseString & str)321 BaseString::assign(const BaseString& str)
322 {
323 return assign(str.m_chr);
324 }
325
326 inline BaseString&
assign(const Vector<BaseString> & vector,const BaseString & separator)327 BaseString::assign(const Vector<BaseString> &vector,
328 const BaseString &separator) {
329 assign("");
330 return append(vector, separator);
331 }
332
333 /**
334 * Return pointer and length for key to use when BaseString is
335 * used as Key in HashMap
336 */
337 const void * BaseString_get_key(const void* key, size_t* key_length);
338
339 #endif /* !__UTIL_BASESTRING_HPP_INCLUDED__ */
340