Added getHostName/getDomainName/getNetworkName/getNetworkAddr
[dyninst.git] / common / h / String.h
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /************************************************************************
43  * String.h: a simple character string class.
44  * $Id: String.h,v 1.19 2000/03/23 01:28:24 wylie Exp $
45 ************************************************************************/
46
47 #if !defined(_String_h_)
48 #define _String_h_
49
50
51 /************************************************************************
52  * header files.
53 ************************************************************************/
54
55 #include <iostream.h>
56 #include "util/h/debugOstream.h"
57 #include "util/h/headers.h"
58
59 \f
60 /************************************************************************
61  * class string
62 ************************************************************************/
63
64 const char WILDCARD_CHAR = '?';
65 const char MULTIPLE_WILDCARD_CHAR = '*';
66
67 class string_ll {
68 public:
69      string_ll ();
70      string_ll (const char *);
71      string_ll (const char *, unsigned n); // just copy the first n chars
72      string_ll (const string_ll &);
73      string_ll (int);      // convert int to its string_ll representation
74      string_ll (long);      // convert int to its string_ll representation
75      string_ll (unsigned); // convert unsigned to its string_ll representation
76      string_ll (unsigned long); // convert unsigned to its string_ll representation
77      string_ll (float);    // convert float to its string_ll representation
78      string_ll (double);   // convert double to its string_ll representation
79     ~string_ll ();
80
81     string_ll& operator= (const char *);
82     string_ll& operator= (const string_ll &);
83     string_ll& operator+= (const string_ll &);
84     string_ll& operator+= (const char *);
85     string_ll  operator+ (const string_ll &) const;
86     string_ll  operator+ (const char *) const;
87
88         char operator[] (unsigned pos) const {return str_[pos];}
89
90     bool operator== (const string_ll &) const;
91     bool operator== (const char *ptr) const {
92        // This routine exists as an optimization; doesn't need to create a temporary
93        // instance of "string" for "ptr"; hence, doesn't call string::string(char *)
94        // which calls new[].
95        return STREQ(ptr, str_);
96     }
97     bool operator!= (const string_ll &) const;
98     bool operator<  (const string_ll &s) const {return STRLT(str_, s.str_);}
99     bool operator<= (const string_ll &) const;
100     bool operator>  (const string_ll &s) const {return STRGT(str_, s.str_);}
101     bool operator>= (const string_ll &) const;
102
103     bool prefix_of (const char *, unsigned) const;
104     bool prefix_of (const char *s)          const {return prefix_of(s, STRLEN(s));};
105     bool prefix_of (const string_ll &)         const;
106
107     bool prefixed_by (const char *, unsigned) const;
108     bool prefixed_by (const char *s)          const {return prefixed_by(s, STRLEN(s));};
109     bool prefixed_by (const string_ll &)         const;
110
111     bool suffix_of (const char *, unsigned) const;
112     bool suffix_of (const char *s)          const {return suffix_of(s, STRLEN(s));};
113     bool suffix_of (const string_ll &)         const;
114
115     bool suffixed_by (const char *, unsigned) const;
116     bool suffixed_by (const char *s)          const {return suffixed_by(s, STRLEN(s));};
117     bool suffixed_by (const string_ll &)         const;
118
119         string_ll substr (unsigned, unsigned) const;
120
121     bool wildcardEquiv( const string_ll &, bool ) const;
122         bool wildcardEquiv( const char *ptr, bool checkCase ) const {
123                 return pattern_match( str_, ptr, checkCase );
124         }
125
126     bool regexEquiv( const string_ll &them, bool checkCase ) const {
127                 return regexEquiv( them.str_, checkCase );
128         }
129         bool regexEquiv( const char *, bool ) const;
130
131     const char*   string_of () const {return str_;}
132     unsigned         length () const {return len_;}
133
134     friend ostream& operator<< (ostream &os, const string_ll &s);
135     friend debug_ostream& operator<< (debug_ostream &os, const string_ll &s);
136 //    friend string_ll operator+(const char *, const string_ll &);
137 //       // a syntactical convenience
138
139     static unsigned       hash (const string_ll &s) {
140        s.updateKeyIfNeeded(); return s.key_;
141     }
142
143 private:
144     void updateKeyIfNeeded() const {if (0==key_) updateKey(); }
145     void updateKey() const {
146        key_ = hashs(str_); // properly checks for NULL; properly won't return 0
147     }
148
149     static unsigned      hashs (const char *);
150
151     static unsigned     STRLEN (const char *);
152     static char*        STRDUP (const char *);
153
154     static bool          STREQ (const char *, const char *);
155     static bool         STREQN (const char *, const char *, unsigned);
156     static bool          STRNE (const char *, const char *);
157     static bool          STRLT (const char *, const char *);
158     static bool          STRLE (const char *, const char *);
159     static bool          STRGT (const char *, const char *);
160     static bool          STRGE (const char *, const char *);
161         static const char*  STRCHR (const char *, char);
162
163         static bool  pattern_match ( const char *, const char *, bool );
164
165     char*    str_;
166     unsigned len_;
167
168     mutable unsigned key_;
169 };
170
171 #include "util/h/refCounter.h"
172
173 class string {
174    friend class string_counter;
175  private:
176    refCounter<string_ll> data;
177
178    static string *nilptr;
179
180    static void initialize_static_stuff();
181    static void free_static_stuff();
182
183  public:
184    // The second of the constructors below should be faster, but it means
185    // we must rely on nil.data being initialized before any global string
186    // objects (or static class members) created with this constructor.
187 //   string() : data(string_ll()) {};
188    string() : data(nilptr->data) {} // should be more efficient than above
189
190    string(const char *str) : data(string_ll(str)) {}
191
192    string(const char *str, unsigned n) : data(string_ll(str,n)) {}
193
194    string(const string& src) : data(src.data) {}
195    string(int i) : data(string_ll(i)) {}
196    string(long l) : data(string_ll(l)) {}
197    string(unsigned u) : data(string_ll(u)) {}
198    string(unsigned long ul) : data(string_ll(ul)) {}
199    string(float f) : data(string_ll(f)) {}
200    string(double d) : data(string_ll(d)) {}
201   ~string() {}
202
203    char operator[] (unsigned pos) const {
204            return data.getData()[ pos ];
205    }
206
207    string& operator=(const char *str) {
208       string_ll new_str_ll(str);
209       refCounter<string_ll> newRefCtr(new_str_ll);
210       
211       data = newRefCtr;
212       return *this;
213    }
214    string& operator=(const string &src) {
215       data = src.data;
216       return *this;
217    }
218
219    string& operator+=(const string &addme) {
220       // see comment in next routine as to why we don't modify in-place.
221       string_ll newstr = data.getData() + addme.data.getData();
222       data = newstr;
223       return *this;
224    }
225
226    string& operator+=(const char *str) {
227       // You might wonder why we can't just do:
228       // data.getData() += str; return *this;
229       // The answer is that that would make an in-place modification,
230       // thus messing up any others who might be attached to the same object as us.
231       // There are two alternative solutions: use prepareToModifyInPlace() followed
232       // by the above sequence, or what we use below.  In general, if the in-place
233       // modification doesn't require making an entirely new low-level object
234       // (the below example does require that), then it's better to use prepareToModifyInPlace()
235       // instead of operator=().
236       
237       string_ll newstr = data.getData() + str;
238       data = newstr;
239       return *this;
240    }
241
242    string operator+(const string &src) const {
243       string result = *this;
244       return (result += src);
245    }
246    string operator+(const char *src) const {
247       string result = *this;
248       return (result += src);
249    }
250    friend string operator+(const char *src, const string &str);
251       // a syntactical convenience
252
253    bool operator==(const string &src) const {
254       const string_ll &me = data.getData();
255       const string_ll &them = src.data.getData();
256       return (me == them);
257    }
258    bool operator==(const char *ptr) const {
259       const string_ll &me = data.getData();
260       return (me == ptr);
261    }
262    bool operator!=(const string &src) const {
263       const string_ll &me = data.getData();
264       const string_ll &them = src.data.getData();
265       return (me != them);
266    }
267    bool operator<(const string &src) const {
268       const string_ll &me = data.getData();
269       const string_ll &them = src.data.getData();
270       return (me < them);
271    }
272    bool operator<=(const string &src) const {
273       const string_ll &me = data.getData();
274       const string_ll &them = src.data.getData();
275       return (me <= them);
276    }
277    bool operator>(const string &src) const {
278       const string_ll &me = data.getData();
279       const string_ll &them = src.data.getData();
280       return (me > them);
281    }
282    bool operator>=(const string &src) const {
283       const string_ll &me = data.getData();
284       const string_ll &them = src.data.getData();
285       return (me >= them);
286    }
287    bool prefix_of(const char *str, unsigned n) const {
288       const string_ll &me = data.getData();
289       return (me.prefix_of(str, n));
290    }
291    bool prefix_of(const char *str) const {
292       const string_ll &me = data.getData();
293       return (me.prefix_of(str));
294    }
295    bool prefix_of(const string &src) const {
296       const string_ll &me = data.getData();
297       const string_ll &them = src.data.getData();
298       return (me.prefix_of(them));
299    }
300
301    bool prefixed_by(const char *str, unsigned n) const {
302       const string_ll &me = data.getData();
303       return (me.prefixed_by(str, n));
304    }
305    bool prefixed_by(const char *str) const {
306       const string_ll &me = data.getData();
307       return (me.prefixed_by(str));
308    }
309    bool prefixed_by(const string &src) const {
310       const string_ll &me = data.getData();
311       const string_ll &them = src.data.getData();
312       return (me.prefixed_by(them));
313    }
314
315    bool suffixed_by(const char *str, unsigned n) const {
316       const string_ll &me = data.getData();
317       return (me.suffixed_by(str, n));
318    }
319    bool suffixed_by(const char *str) const {
320       const string_ll &me = data.getData();
321       return (me.suffixed_by(str));
322    }
323    bool suffixed_by(const string &src) const {
324       const string_ll &me = data.getData();
325       const string_ll &them = src.data.getData();
326       return (me.suffixed_by(them));
327    }
328
329    const char *string_of() const {
330       const string_ll &me = data.getData();
331       return me.string_of();
332    }
333
334    unsigned length() const {
335       const string_ll &me = data.getData();
336       return me.length();
337    }
338
339    friend ostream& operator<<(ostream &os, const string &s) {
340       const string_ll &it = s.data.getData();
341       return (os << it);
342    }
343    friend debug_ostream& operator<<(debug_ostream &os, const string &s) {
344       const string_ll &it = s.data.getData();
345       return (os << it);
346    }
347
348    string substr( unsigned pos, unsigned len ) const {
349            string result = *this;
350            string_ll newstr = data.getData().substr( pos, len );
351            result.data = newstr;
352            return result;
353    }
354
355    bool wildcardEquiv( const string &src, bool checkCase = true ) const {
356       const string_ll &me = data.getData();
357       const string_ll &them = src.data.getData();
358       return me.wildcardEquiv( them, checkCase );
359    }
360    bool wildcardEquiv( const char *ptr, bool checkCase = true ) const {
361       const string_ll &me = data.getData();
362       return me.wildcardEquiv( ptr, checkCase );
363    }
364
365    bool regexEquiv( const string &src, bool checkCase = true ) const {
366       const string_ll &me = data.getData();
367       const string_ll &them = src.data.getData();
368       return me.regexEquiv( them, checkCase );
369    }
370    bool regexEquiv( const char *ptr, bool checkCase = true ) const {
371       const string_ll &me = data.getData();
372       return me.regexEquiv( ptr, checkCase );
373    }
374
375    static unsigned hash(const string &s) {
376       const string_ll &it = s.data.getData();
377       return (string_ll::hash(it));
378    }
379 };
380
381 // See Stroustrup, D & E, sec 3.11.4.2:
382 class string_counter {
383  private:
384    static int count;
385   
386  public:
387    string_counter() {
388       if (count++ == 0)
389          string::initialize_static_stuff();
390    }
391   ~string_counter() {
392       if (--count == 0)
393          string::free_static_stuff();
394    }
395 };
396 static string_counter sc;
397
398 #endif /* !defined(_String_h_) */