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