1 /*
2 * Copyright (C) 2010 Regents of the University of Michigan
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 as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef __BASICSTRING_H__
19 #define __BASICSTRING_H__
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <vector>
25 #include <iostream>
26
27 using std::vector;
28
29 #define READBUF 128
30 #define READBUFSTR "128"
31
32 #ifdef __PREFIX_STRING__
33 #define String BasicString
34 #endif
35
36 #include "InputFile.h"
37
38 class String
39 {
40 private:
41 void NewString(int startsize);
42
43 protected:
44 char * buffer;
45 int len, size;
46
47 public:
48 static int alloc;
49 static bool caseSensitive;
50
51 explicit String(int startsize = 0)
52 {
53 NewString(startsize);
54 }
55 String(const char * s);
56 String(const String & s);
57 explicit String(char ch, int count = 1);
58
~String()59 ~String()
60 {
61 if(buffer != NULL)
62 delete [] buffer;
63 }
64
Clear()65 String & Clear()
66 {
67 len = buffer[0] = 0;
68 return *this;
69 }
70
71 String & Copy(const String & s);
72 String & Copy(const String & s, int start, int count);
73 String & Copy(const char * s);
74
IsEmpty()75 bool IsEmpty() const
76 {
77 return len == 0;
78 }
79 String & ToUpper();
80 String & ToLower();
81 String AsUpper();
82 String AsLower();
83 String Capitalize();
84 String & Reverse();
85
86 String & LeftClip(int clipAmount);
87 String & RightClip(int clipAmount);
88
89 String & operator = (char ch);
90 String operator + (char ch) const;
91 String & operator += (char ch);
92
93 String & operator = (const String & rhs);
94 String operator + (const String & rhs) const;
95 String & operator += (const String & rhs);
96
97 String & operator = (const char * rhs);
98 String operator + (const char * rhs) const;
99 String & operator += (const char * rhs);
100
101 String & operator = (int rhs);
102 String operator + (int rhs) const;
103 String & operator += (int rhs);
104
105 String & operator = (double rhs);
106 String operator + (double rhs) const;
107 String & operator += (double rhs);
108
109 void appendFullFloat(float rhs);
110
111 String & operator = (unsigned int rhs);
112 String operator + (unsigned int rhs) const;
113 String & operator += (unsigned int rhs);
114 String operator *(unsigned int rhs) const;
115 String & operator *= (unsigned int rhs);
116
117 int Compare(const String & rhs) const;
118 int FastCompare(const String & rhs) const;
119 int SlowCompare(const String & rhs) const;
120
121 int Compare(const char * rhs) const;
122 int FastCompare(const char * rhs) const;
123 int SlowCompare(const char * rhs) const;
124
125 int CompareToStem(const String & stem) const;
126 int FastCompareToStem(const String & stem) const;
127 int SlowCompareToStem(const String & stem) const;
128
129 int CompareToStem(const char * stem) const;
130 int FastCompareToStem(const char * stem) const;
131 int SlowCompareToStem(const char * stem) const;
132
133 int MatchesBeginningOf(const String & stem) const;
134 int FastMatchesBeginningOf(const String & stem) const;
135 int SlowMatchesBeginningOf(const String & stem) const;
136
137 int MatchesBeginningOf(const char * stem) const;
138 int FastMatchesBeginningOf(const char * stem) const;
139 int SlowMatchesBeginningOf(const char * stem) const;
140
141 int operator == (const String & rhs) const
142 {
143 return Compare(rhs) == 0;
144 }
145 int operator != (const String & rhs) const
146 {
147 return Compare(rhs) != 0;
148 }
149 int operator < (const String & rhs) const
150 {
151 return Compare(rhs) < 0;
152 }
153 int operator > (const String & rhs) const
154 {
155 return Compare(rhs) > 0;
156 }
157 int operator >= (const String & rhs) const
158 {
159 return Compare(rhs) >= 0;
160 }
161 int operator <= (const String & rhs) const
162 {
163 return Compare(rhs) <= 0;
164 }
165
166 int operator == (const char * rhs) const
167 {
168 return Compare(rhs) == 0;
169 }
170 int operator != (const char * rhs) const
171 {
172 return Compare(rhs) != 0;
173 }
174 int operator < (const char * rhs) const
175 {
176 return Compare(rhs) < 0;
177 }
178 int operator > (const char * rhs) const
179 {
180 return Compare(rhs) > 0;
181 }
182 int operator <= (const char * rhs) const
183 {
184 return Compare(rhs) <= 0;
185 }
186 int operator >= (const char * rhs) const
187 {
188 return Compare(rhs) >= 0;
189 }
190
191 operator const char *() const
192 {
193 return buffer;
194 }
c_str()195 const char *c_str() const
196 {
197 return (const char *) buffer;
198 }
199 operator char *()
200 {
201 return buffer;
202 }
203
204 operator int () const
205 {
206 return atoi(buffer);
207 }
208 operator double() const
209 {
210 return atof(buffer);
211 }
212 operator long double() const;
213
214 char operator [](int i) const
215 {
216 return buffer[i];
217 }
218 char & operator [](int i)
219 {
220 return buffer[i];
221 }
222
Last()223 char & Last()
224 {
225 return buffer[len - 1];
226 }
First()227 char & First()
228 {
229 return buffer[0];
230 }
231
232 void Grow(int newSize);
233 void Swap(String & s);
234
235 char * LockBuffer(int size = -1);
236 String & UnlockBuffer();
237
238 String & Read();
239 // Return the status. A negative number indicates an error/EOF.
240 int ReadLine();
241 void WriteLine();
242 void Write();
243
244 String & Read(FILE * f);
245 // Return the status. A negative number indicates an error/EOF.
246 int ReadLine(FILE * f);
247 void WriteLine(FILE * f);
248 void Write(FILE * f);
249
250 String & Read(IFILE & f);
251
252 // Read a line using getc
253 // Return the status. A negative number indicates an error/EOF.
254 int ReadLine(IFILE & f);
255
256 String Left(int count) const;
257 String Right(int count) const;
258 String Mid(int start, int end) const;
259 String SubStr(int start, int count) const;
260 String SubStr(int start) const;
261
262 int FindChar(char ch, int start = 0) const;
263 int FastFindChar(char ch, int start = 0) const;
264 int SlowFindChar(char ch, int start = 0) const;
265
266 int FindLastChar(char ch) const;
267 int FastFindLastChar(char ch) const;
268 int SlowFindLastChar(char ch) const;
269
270 // Since there is no longer implicit conversion
271 // from char to String, declare this method that
272 // takes a character rather than a String reference.
273 int Find(char ch, int start = 0) const
274 {
275 return(FindChar(ch, start));
276 }
277 int Find(const String & str, int start = 0) const;
278 int FastFind(const String & str, int start = 0) const;
279 int SlowFind(const String & str, int start = 0) const;
280
281 String & Filter(const String & s);
282 String & Filter(const char * s);
283
284 String & ExcludeCharacters(const String & s);
285 String & ExcludeCharacters(const char * s);
286
Length()287 int Length() const
288 {
289 return len;
290 }
BufferSize()291 int BufferSize() const
292 {
293 return size;
294 }
295
296 int SetLength(int newlen);
Dimension(int newlen)297 int Dimension(int newlen)
298 {
299 return SetLength(newlen);
300 }
301
Add(const String & s)302 String & Add(const String & s)
303 {
304 return *this += s;
305 }
Add(char ch)306 String & Add(char ch)
307 {
308 return *this += ch;
309 }
310
311 String RightToLeft();
312 String & Invert();
313 String & Invert(const String & s);
314
315 String & Trim();
316 String & Trim(char character);
317 vector<String> *Split(char splitChar);
318
319 long AsInteger() const;
320 bool AsInteger(long& intValue) const;
321 bool AsInteger(int& intValue) const;
AsDouble()322 double AsDouble() const
323 {
324 return (double) *this;
325 }
AsLongDouble()326 long double AsLongDouble() const
327 {
328 return (long double) *this;
329 }
330
331 int printf(const char * format, ...);
332 int vprintf(const char * format, va_list arglist);
333
334 int catprintf(const char * format, ...);
335 int vcatprintf(const char * format, va_list arglist);
336
337 // Replacement vsnprintf and snprint functions for
338 // problematic architectures...
339
340 static int my_snprintf(char * buffer, int bufsize, const char * format, ...);
341 static int my_vsnprintf(char * buffer, int bufsize, const char * format, va_list args);
342 static void my_vsnprintf_close_file();
343 static void check_vsnprintf();
344
345 // Check string contents
346 bool IsNumber();
347
348 // Explicit conversions
uchar()349 const unsigned char * uchar() const
350 {
351 return (unsigned char *) buffer;
352 }
schar()353 const signed char * schar() const
354 {
355 return (signed char *) buffer;
356 }
357
358 static FILE * my_vsnprintf_file;
359
360 // Utility functions
361 void Fill(char ch, int length = -1);
362
363 private:
364
365 static int vsnprintfChecked;
366 };
367
Compare(const String & s1,const String & s2)368 inline int Compare(const String & s1, const String & s2)
369 {
370 return s1.Compare(s2);
371 }
372
Compare(const String & s1,const char * s2)373 inline int Compare(const String & s1, const char * s2)
374 {
375 return s1.Compare(s2);
376 }
377
Compare(const char * s1,const String & s2)378 inline int Compare(const char * s1, const String & s2)
379 {
380 return -s2.Compare(s1);
381 }
382
FastCompare(const String & s1,const String & s2)383 inline int FastCompare(const String & s1, const String & s2)
384 {
385 return s1.FastCompare(s2);
386 }
387
FastCompare(const String & s1,const char * s2)388 inline int FastCompare(const String & s1, const char * s2)
389 {
390 return s1.FastCompare(s2);
391 }
392
FastCompare(const char * s1,const String & s2)393 inline int FastCompare(const char * s1, const String & s2)
394 {
395 return -s2.FastCompare(s1);
396 }
397
SlowCompare(const String & s1,const String & s2)398 inline int SlowCompare(const String & s1, const String & s2)
399 {
400 return s1.SlowCompare(s2);
401 }
402
SlowCompare(const String & s1,const char * s2)403 inline int SlowCompare(const String & s1, const char * s2)
404 {
405 return s1.SlowCompare(s2);
406 }
407
SlowCompare(const char * s1,const String & s2)408 inline int SlowCompare(const char * s1, const String & s2)
409 {
410 return -s2.SlowCompare(s1);
411 }
412
413 String operator + (char lhs, const String & rhs);
414 String operator + (const char * lhs, const String & rhs);
415 String operator + (int lhs, const String & rhs);
416 String operator + (unsigned int lhs, const String & rhs);
417
418 std::ostream& operator << (std::ostream& os, const String& s);
419
420 /// Write to a file using streaming.
421 /// \param stream file to write to - IFILE is a pointer to an InputFile object
422 /// \param str string containing what should be written to the file.
423 inline InputFile& operator << (InputFile& stream, const String& str)
424 {
425 unsigned int numExpected = str.Length();
426 unsigned int numWritten =
427 stream.ifwrite(str.c_str(), numExpected);
428 if(numExpected != numWritten)
429 {
430 std::cerr << "Failed to stream to IFILE, expected "
431 << numExpected << " but only wrote "
432 << numWritten << std::endl;
433 }
434 return(stream);
435 }
436
437
438 #endif
439
440
441
442