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