d32b276e3f457bdb6b94a30b27be8ce298be5ad6
[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 <string.h>
49
50 #include <regex.h>
51
52 //  Forward declarations.
53 class substring;
54 class regex;
55
56 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57 **  NAME           : String - Character String class.
58 **  MEMBERS        : p -> s : Pointer to the actual String data.
59 **                   p -> n : Number of references to this String.
60 **  OPERATORS      : =      : Assign a String, char *, char to a String.
61 **                   +, +=  : concatenate Strings
62 **                   ~      : Length of a String
63 **                   []     : Individual character access.
64 **                   !      : Empty String test.
65 **                   ()     : Substring selection.
66 **                   ostream << : String to output stream.
67 **                   istream << : String from input stream.
68 **                   ==, !=, <,
69 **                   >, <=, >= : String comparison.
70 **  METHODS        :
71 **
72 **  DESCRIPTION    : The String class counts the references to a String to
73 **                   minimize copying and uses standard C++ character strings
74 **                   as constants.
75 **
76 **  RELATIONS      : substring
77 **  SEE ALSO       :
78 **  LAST MODIFIED  : Aug 27, 1999
79 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
80 */
81
82 class String
83 {
84    friend class substring;
85    friend class regex;
86
87    struct srep
88    {
89       char  *s;    // pointer to data;
90       int    n;    // reference count
91    } *p;
92
93 public:
94
95    String(const char *);      // String x = "abc"
96    String(char);              // String x = 'a'
97    String();                  // String x;
98    String(const String &);    // String x = String ...
99    String(const substring &); // String x = String(s, l)
100
101    String& operator=(const char);
102    String& operator=(const char *);
103    String& operator=(const String &);
104    ~String();
105
106    /*  Numerical conversion */
107
108    String(int);              //  String x(12);  x = "12"
109    String(long);             //  String x(12);  x = "12"
110    String(unsigned long);    //  String x(12);  x = "12"
111
112    operator int()
113    {
114       return strtol(p->s, 0, 0);
115    }
116
117    operator long()
118    {
119       return strtol(p->s, 0, 0);
120    }
121
122    operator unsigned long()
123    {
124       return strtoul(p->s, 0, 0);
125    }
126
127    long dec(void)
128    {
129       return strtol(p->s, 0, 10);
130    }
131
132    long oct(void)
133    {
134       return strtol(p->s, 0, 8);
135    }
136
137    long hex(void) 
138    {
139       return strtol(p->s, 0, 16);
140    }
141
142    String(double);
143    operator double()
144    {
145       return strtod(p->s, 0);
146    }
147
148
149    char& operator[](size_t i);    //  Individual character access
150
151    int operator~() const      //  Length of the String
152    {
153       return p->s ? strlen(p->s) : 0;
154    }
155
156    operator char*()
157    {
158       if (p->s && p->s[0])
159          return p->s;
160       else
161          return 0;
162    }
163    operator const char*() const
164    {
165       if (p->s && p->s[0])
166          return p->s;
167       else
168          return 0;
169    }
170
171    operator bool()   //  Test for empty String
172    {
173       return p->s != 0 && p->s[0] != '\0';
174    }
175
176    /*
177     *   String concatenation.
178     *   char and char* are handled by constructors.
179     */
180
181    String& operator+=(const String&);
182    String& operator+=(const char *);
183    friend String operator+(const String&, const String&);
184    friend String operator+(const String&, const char *);
185    friend String operator+(const char *,  const String&);
186
187    /*
188     *  Shifting characters out
189     *            "abcdefgh" <<= 3  = "defgh"
190     *            "abcdefgh" >>= 3  = "abcde"
191     */
192
193    friend String operator<<(const String &x, int n);
194    String & operator<<=(int n);
195
196    friend String operator>>(const String &x, int n);
197    String & operator>>=(int n);
198
199    /*
200     *   Substring selection
201     *
202     *   A substring can be selected by a start index and a length or
203     *   by matching a regular expression.
204     *
205     *   Selecting a substring by regular expression, combined with
206     *   the lvalue semantics of the substring class is a particularly
207     *   powerful concept. Possible uses are for example:
208     *
209     *   (assuming String S, M; regex R;)
210     *   M = S(R);             ->  Returns matching part of S into M.
211     *   S(R) = "replacement"; -> replace matching part of S.
212     *   S(R) = "";            -> Removes matching part from S.
213     *   S(R) == S;            -> true if and only if all of S matches R exactly.
214     */
215
216    substring operator()(int start, int len);
217    substring operator()(const regex &r);
218
219    /*
220     *   Input and output
221     */
222
223    friend std::ostream& operator<<(std::ostream &, const String &);
224    // Read one line and remove the trailing line feed.
225    friend std::istream& operator>>(std::istream &, String &);
226
227    /*
228     *   String comparison tests
229     */
230
231    friend int operator==(const String& x, const String& y)
232    {
233       return strcmp(x.p->s, y.p->s) == 0;
234    }
235
236    friend int operator!=(const String& x, const String& y)
237    {
238       return strcmp(x.p->s, y.p->s) != 0;
239    }
240
241    friend int operator<=(const String& x, const String& y)
242    {
243       return strcmp(x.p->s, y.p->s) <= 0;
244    }
245
246    friend int operator>=(const String& x, const String& y)
247    {
248       return strcmp(x.p->s, y.p->s) >= 0;
249    }
250
251    friend int operator<(const String& x, const String& y)
252    {
253       return strcmp(x.p->s, y.p->s) < 0;
254    }
255
256    friend int operator>(const String& x, const String& y)
257    {
258       return strcmp(x.p->s, y.p->s) > 0;
259    }
260
261    friend int operator==(const String& x, const char * y)
262    {
263       return strcmp(x.p->s, y) == 0;
264    }
265
266    friend int operator!=(const String& x, const char * y)
267    {
268       return strcmp(x.p->s, y) != 0;
269    }
270
271    friend int operator<=(const String& x, const char * y)
272    {
273       return strcmp(x.p->s, y) <= 0;
274    }
275
276    friend int operator>=(const String& x, const char * y)
277    {
278       return strcmp(x.p->s, y) >= 0;
279    }
280
281    friend int operator<(const String& x, const char * y)
282    {
283       return strcmp(x.p->s, y) < 0;
284    }
285
286    friend int operator>(const String& x, const char * y)
287    {
288       return strcmp(x.p->s, y) > 0;
289    }
290
291    /*
292     *  Modifiers
293     */
294
295    String upper();   //  Convert to upper case (ASCII)
296    String lower();   //  Convert to lower case (ASCII)
297    String escape();   //  Insert backslashes to escape special characters
298    String unescape(); //  Remove backslashes from escape codes.
299
300    /*
301     *  Character searching and Pattern matching
302     */
303
304    int index(char c);
305    int rindex(char c);
306
307    int in(String & x);
308
309    //  Regular expression pattern matching
310  
311    friend bool operator == (const String &s, const regex &r);
312    friend bool operator == (const regex &r, const String &s);
313    // TODO: The != operator
314 };
315    /*
316     *   Other operators to think about...
317     *
318     *
319     *   Numeric conversion with strtod and strtol and vice-versa,
320     *   so we can do:
321     *                 String nr = 123  //  nr = "123"
322     *                 float x = 2.32; String f = x;  // f = "2.32"
323     *                             f = "3.145";
324     *                         int i = f;           // i = 3
325     *
326     *   String matching:
327     *       int index(String&, start=0)  // Find position of substring
328     *
329     *
330     *  Literature:  Bjarne Stroustrup, Section 6.9
331     *               DDJ October 1991, pg 24
332     */
333
334
335 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
336 **  NAME           : substring - Determine part of a String object.
337 **  MEMBERS        : str   : The String object of which this is a substring
338 **                   start : index of the first substring character.
339 **                   len   : Number of characters in the substring
340 **  OPERATORS      : =     : Assignment of a String or char *
341 **  METHODS        :
342 **
343 **  DESCRIPTION    : This implements substring selection from a String object
344 **                   with l-value semantics.
345 **
346 **  RELATIONS      : String
347 **  SEE ALSO       :
348 **  LAST MODIFIED  :
349 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
350 */
351
352 class substring
353 {
354    friend class String;
355
356    String     *str;   //  Where I am a substring of.
357    int  start, len;
358
359 public:
360    String& operator=(const String &); 
361    String& operator=(const char *s)
362    {
363       *this = String(s);
364       return *str;
365    }
366 };
367
368 /*  Regular expression matching */
369
370 class regex
371 {
372    friend class String;
373
374    regex_t    expression;
375    String     original;
376
377 public:
378
379    regex(const String & reg);
380    regex(const char * reg);
381    regex(const regex & reg);
382    ~regex();
383
384    regex& operator=(const regex &);
385
386    friend bool operator == (const String &s, const regex &r);
387    friend bool operator == (const regex &r, const String &s);
388 };
389
390 class StringException
391 {
392    String message;
393
394 public:
395
396    StringException(String m)
397    {
398       message = m;
399    }
400
401    String what()
402    {
403       return message;
404    }
405 };
406
407 #endif  /* STRING_H */