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