1c40f29afe9c5dfcbf9225ede098f7a4b475d2cf
[libacl.git] / src / String.h
1 /**************************************************************************
2 **  (c) Copyright 1997, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : String.h
7 **      SYSTEM NAME    : Andromeda X-Windows Encapsulation
8 **      VERSION NUMBER : $Revision: 1.4 $
9 **
10 **  DESCRIPTION      :  Character String class definition
11 **
12 **  EXPORTED OBJECTS : class String
13 **  LOCAL    OBJECTS : class substring
14 **  MODULES  USED    :
15 ***************************************************************************
16 **  ADMINISTRATIVE INFORMATION *
17 ********************************
18 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 **      CREATION DATE   : Nov 17, 1995
20 **      LAST UPDATE     : Mar 31, 2010
21 **      MODIFICATIONS   : 
22 **************************************************************************/
23
24 /*****************************
25    $Log: String.h,v $
26    Revision 1.4  2007/05/04 13:56:05  arjen
27    Added a copy contructor to the regex class. This prevents multiple frees in the destructor.
28
29    Revision 1.3  2002/11/03 13:18:57  arjen
30    New functions - String::escape() and String::unescape()
31
32    Revision 1.2  2002/09/28 06:45:51  arjen
33    New feature: subtring selection by regular expression.
34    Bugfix: use the std: namespace for STL classes istream and ostream
35
36    Revision 1.1  2002/07/25 08:01:26  arjen
37    First checkin, AXE release 0.2
38
39 *****************************/
40
41 // static const char RCSID[] = "$Id: String.h,v 1.4 2007/05/04 13:56:05 arjen Exp $";
42
43 #ifndef STRING_H
44 #define STRING_H
45
46 #include <stdlib.h>
47 #include <iostream>
48 #include <vector>
49 #include <string>
50 #include <string.h>
51
52 #include <regex.h>
53
54 //  Forward declarations.
55 class substring;
56 class regex;
57 class SuperString;
58
59 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60 **  NAME           : String - Character String class.
61 **  MEMBERS        : p -> s : Pointer to the actual String data.
62 **                   p -> n : Number of references to this String.
63 **  OPERATORS      : =      : Assign a String, char *, char to a String.
64 **                   +, +=  : concatenate Strings
65 **                   ~      : Length of a String
66 **                   []     : Individual character access.
67 **                   !      : Empty String test.
68 **                   ()     : Substring selection.
69 **                   ostream << : String to output stream.
70 **                   istream << : String from input stream.
71 **                   ==, !=, <,
72 **                   >, <=, >= : String comparison.
73 **  METHODS        :
74 **
75 **  DESCRIPTION    : The String class counts the references to a String to
76 **                   minimize copying and uses standard C++ character strings
77 **                   as constants.
78 **
79 **  RELATIONS      : substring
80 **  SEE ALSO       :
81 **  LAST MODIFIED  : Aug 27, 1999
82 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
83 */
84
85 class String
86 {
87    friend class substring;
88    friend class regex;
89
90    struct srep
91    {
92       char  *s;    // pointer to data;
93       int    n;    // reference count
94    } *p;
95
96 public:
97
98    String(const char *);      // String x = "abc"
99    String(char);              // String x = 'a'
100    String();                  // String x;
101    String(const String &);    // String x = String ...
102    String(const substring &); // String x = String(s, l)
103    String(const std::string &); // String x = std::string("abc")
104
105    String& operator=(const char);
106    String& operator=(const char *);
107    String& operator=(const String &);
108    String& operator=(const std::string &);
109    ~String();
110
111    /*  Numerical conversion */
112
113    String(int);              //  String x(12);  x = "12"
114    String(long);             //  String x(12);  x = "12"
115    String(unsigned long);    //  String x(12);  x = "12"
116
117    operator int()
118    {
119       return strtol(p->s, 0, 0);
120    }
121
122    operator long()
123    {
124       return strtol(p->s, 0, 0);
125    }
126
127    operator unsigned long()
128    {
129       return strtoul(p->s, 0, 0);
130    }
131
132    long dec(void)
133    {
134       return strtol(p->s, 0, 10);
135    }
136
137    long oct(void)
138    {
139       return strtol(p->s, 0, 8);
140    }
141
142    long hex(void) 
143    {
144       return strtol(p->s, 0, 16);
145    }
146
147    String(double);
148    operator double()
149    {
150       return strtod(p->s, 0);
151    }
152
153
154    char& operator[](size_t i);    //  Individual character access
155
156    int operator~() const      //  Length of the String
157    {
158       return p->s ? strlen(p->s) : 0;
159    }
160
161    int size() const      //  Length of the String
162    {
163       return p->s ? strlen(p->s) : 0;
164    }
165
166    operator char*()
167    {
168       if (p->s && p->s[0])
169          return p->s;
170       else
171          return 0;
172    }
173    operator const char*() const
174    {
175       if (p->s && p->s[0])
176          return p->s;
177       else
178          return 0;
179    }
180
181    std::string std_string()
182    {
183       if (p->s && p->s[0])
184          return std::string(p->s);
185       else
186          return std::string("");
187    }
188
189    operator bool()   //  Test for empty String
190    {
191       return p->s != 0 && p->s[0] != '\0';
192    }
193
194    /*
195     *   String concatenation.
196     *   char and char* are handled by constructors.
197     */
198
199    String& operator+=(const String&);
200    String& operator+=(const char *);
201    friend String operator+(const String&, const String&);
202    friend String operator+(const String&, const char *);
203    friend String operator+(const char *,  const String&);
204
205    /*
206     *  Shifting characters out
207     *            "abcdefgh" <<= 3  = "defgh"
208     *            "abcdefgh" >>= 3  = "abcde"
209     */
210
211    friend String operator<<(const String &x, int n);
212    String & operator<<=(int n);
213
214    friend String operator>>(const String &x, int n);
215    String & operator>>=(int n);
216
217    /*
218     *   Substring selection
219     *
220     *   A substring can be selected by a start index and a length or
221     *   by matching a regular expression.
222     *
223     *   Selecting a substring by regular expression, combined with
224     *   the lvalue semantics of the substring class is a particularly
225     *   powerful concept. Possible uses are for example:
226     *
227     *   (assuming String S, M; regex R;)
228     *   M = S(R);             ->  Returns matching part of S into M.
229     *   S(R) = "replacement"; -> replace matching part of S.
230     *   S(R) = "";            -> Removes matching part from S.
231     *   S(R) == S;            -> true if and only if all of S matches R exactly.
232     */
233
234    substring operator()(int start, int len);
235    substring operator()(const regex &r);
236
237    /*
238     *   Input and output
239     */
240
241    friend std::ostream& operator<<(std::ostream &, const String &);
242    // Read one line and remove the trailing line feed.
243    friend std::istream& operator>>(std::istream &, String &);
244
245    /*
246     *   String comparison tests
247     */
248
249    friend int operator==(const String& x, const String& y)
250    {
251       return strcmp(x.p->s, y.p->s) == 0;
252    }
253
254    friend int operator!=(const String& x, const String& y)
255    {
256       return strcmp(x.p->s, y.p->s) != 0;
257    }
258
259    friend int operator<=(const String& x, const String& y)
260    {
261       return strcmp(x.p->s, y.p->s) <= 0;
262    }
263
264    friend int operator>=(const String& x, const String& y)
265    {
266       return strcmp(x.p->s, y.p->s) >= 0;
267    }
268
269    friend int operator<(const String& x, const String& y)
270    {
271       return strcmp(x.p->s, y.p->s) < 0;
272    }
273
274    friend int operator>(const String& x, const String& y)
275    {
276       return strcmp(x.p->s, y.p->s) > 0;
277    }
278
279    friend int operator==(const String& x, const char * y)
280    {
281       return strcmp(x.p->s, y) == 0;
282    }
283
284    friend int operator!=(const String& x, const char * y)
285    {
286       return strcmp(x.p->s, y) != 0;
287    }
288
289    friend int operator<=(const String& x, const char * y)
290    {
291       return strcmp(x.p->s, y) <= 0;
292    }
293
294    friend int operator>=(const String& x, const char * y)
295    {
296       return strcmp(x.p->s, y) >= 0;
297    }
298
299    friend int operator<(const String& x, const char * y)
300    {
301       return strcmp(x.p->s, y) < 0;
302    }
303
304    friend int operator>(const String& x, const char * y)
305    {
306       return strcmp(x.p->s, y) > 0;
307    }
308
309    /*
310     *  Modifiers
311     */
312
313    String upper();   //  Convert to upper case (ASCII)
314    String lower();   //  Convert to lower case (ASCII)
315    String escape();   //  Insert backslashes to escape special characters
316    String unescape(); //  Remove backslashes from escape codes.
317
318    /*
319     *  Character and String searching
320     */
321
322    int index(char c);
323    int rindex(char c);
324
325    int index(const char * x);
326    int index(String & x)
327    {
328       return index(x.p->s);
329    }
330
331    int rindex(const char * x);
332    int rindex(String & x)
333    {
334       return rindex(x.p->s);
335    }
336
337    int in(String & x)
338    {
339       return index(x);
340    }
341
342    //  Regular expression pattern matching
343  
344    friend bool operator == (const String &s, const regex &r);
345    friend bool operator == (const regex &r, const String &s);
346    friend bool operator != (const String &s, const regex &r);
347    friend bool operator != (const regex &r, const String &s);
348
349    SuperString split(const String &separator);
350    SuperString tokenize(const String &delimiters);
351
352 };
353    /*
354     *   Other operators to think about...
355     *
356     *
357     *   Numeric conversion with strtod and strtol and vice-versa,
358     *   so we can do:
359     *                 String nr = 123  //  nr = "123"
360     *                 float x = 2.32; String f = x;  // f = "2.32"
361     *                             f = "3.145";
362     *                         int i = f;           // i = 3
363     *
364     *   String matching:
365     *       int index(String&, start=0)  // Find position of substring
366     *
367     *
368     *  Literature:  Bjarne Stroustrup, Section 6.9
369     *               DDJ October 1991, pg 24
370     */
371
372
373 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
374 **  NAME           : substring - Determine part of a String object.
375 **  MEMBERS        : str   : The String object of which this is a substring
376 **                   start : index of the first substring character.
377 **                   len   : Number of characters in the substring
378 **  OPERATORS      : =     : Assignment of a String or char *
379 **  METHODS        :
380 **
381 **  DESCRIPTION    : This implements substring selection from a String object
382 **                   with l-value semantics.
383 **
384 **  RELATIONS      : String
385 **  SEE ALSO       :
386 **  LAST MODIFIED  :
387 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
388 */
389
390 class substring
391 {
392    friend class String;
393
394    String     *str;   //  Where I am a substring of.
395    int  start, len;
396
397 public:
398    String& operator=(const String &); 
399    String& operator=(const char *s)
400    {
401       *this = String(s);
402       return *str;
403    }
404 };
405
406 /*  Regular expression matching */
407
408 class regex
409 {
410    friend class String;
411
412    regex_t    expression;
413    String     original;
414
415 public:
416
417    regex(const String & reg);
418    regex(const char * reg);
419    regex(const regex & reg);
420    ~regex();
421
422    regex& operator=(const regex &);
423
424    friend bool operator == (const String &s, const regex &r);
425    friend bool operator == (const regex &r, const String &s);
426    friend bool operator != (const String &s, const regex &r);
427    friend bool operator != (const regex &r, const String &s);
428 };
429
430 class SuperString
431 {
432    std::vector<String> _ss;
433
434 public:
435
436    SuperString()  {};
437
438    SuperString(const String &s)
439    {
440       std::vector<String> __ss(1, s);
441       _ss = __ss;
442    }
443
444    SuperString(const int n)
445    {
446       std::vector<String> __ss(n);
447       _ss = __ss;
448    }
449
450    operator bool()   //  Test for empty SuperString
451    {
452       return _ss.size() != 0;
453    }
454
455    int operator~() const      //  Length of the SuperString
456    {
457       return _ss.size();
458    }
459
460    String& operator[](size_t i)    //  Individual String access
461    {
462       return _ss.at(i);
463    }
464
465    // Inserting and erasing Strings
466
467    void insert(int position, const String &s)
468    {
469       _ss.insert(_ss.begin() + position, s);
470    }
471
472    void erase(int position)
473    {
474       _ss.erase(_ss.begin() + position);
475    }
476
477    // Adding Strings and SuperStrings
478
479    friend SuperString operator+(const SuperString&, const String&);
480    friend SuperString operator+(const String&, const SuperString&);
481    friend SuperString operator+(const SuperString&, const SuperString&);
482    SuperString& operator+=(const String&);
483
484    /*
485     *   SuperString comparison tests
486     */
487
488    friend int operator==(const SuperString& x, const SuperString& y)
489    {
490       return x._ss == y._ss;
491    }
492
493    friend int operator!=(const SuperString& x, const SuperString& y)
494    {
495       return x._ss != y._ss;
496    }
497
498    friend int operator<=(const SuperString& x, const SuperString& y)
499    {
500       return x._ss <= y._ss;
501    }
502
503    friend int operator>=(const SuperString& x, const SuperString& y)
504    {
505       return x._ss >= y._ss;
506    }
507
508    friend int operator<(const SuperString& x, const SuperString& y)
509    {
510       return x._ss < y._ss;
511    }
512
513    friend int operator>(const SuperString& x, const SuperString& y)
514    {
515       return x._ss > y._ss;
516    }
517
518    String join(const String &separator);
519 };
520
521 /*
522  *  Exception classes
523  */
524
525
526 class StringException
527 {
528    String message;
529
530 public:
531
532    StringException(String m)
533    {
534       message = m;
535    }
536
537    String what()
538    {
539       return message;
540    }
541 };
542
543 #define ERROR_MSG_SIZE 200
544
545 class RegexException
546 {
547    String message;
548
549 public:
550
551    RegexException(int errcode, regex_t *preg)
552    {
553       char errbuf[ERROR_MSG_SIZE];
554
555       regerror(errcode, preg, errbuf, ERROR_MSG_SIZE);
556       message = errbuf;
557    }
558
559    String what()
560    {
561       return message;
562    }
563 };
564
565 #endif  /* STRING_H */