Added new classes: Cstring KeyList, KList
[dyninst.git] / pdutil / h / cstring.h
1
2 /*
3  *  String ADT.
4  *  Implements copy semantics. 
5  *  This class has been purified.
6  *  This class can be used with klist.
7  *  See the tests subdirectory for examples of its use.
8  */
9
10 /*
11  * $Log: cstring.h,v $
12  * Revision 1.1  1994/08/17 18:23:46  markc
13  * Added new classes: Cstring KeyList, KList
14  * Added new function: RPCgetArg
15  * Changed typedefs in machineType.h to #defines
16  *
17  */
18
19 #ifndef _string_hpp
20 #define _string_hpp
21
22 #include <string.h>
23 #include <assert.h>
24 #include <iostream.h>
25
26 #define VALID(x) assert(x)
27 #define MAX_STRING_LEN 2000
28 #define CS_TRUE 1
29 #define CS_FALSE 0
30
31 #pragma interface
32
33 typedef int CS_BOOL;
34
35 class Cstring
36 {
37 public:
38 friend ostream &operator << (ostream& os, const Cstring& S) {
39   if (!S.len)
40     os << "<empty>";
41   else 
42     os << S.str;
43   return os;
44 }
45
46   // the integer serves to choose the correct constructor
47   // otherwise you would have to typecast to const char
48   // to get other constructor
49   Cstring(int i, char *use_me) :len(0), str((char*) 0) {use(use_me);}
50   Cstring() : len(0), str((char*) 0) { ; }
51   Cstring(const char *copy_me) : len(0), str((char*) 0) {set(copy_me);}
52   Cstring(const Cstring& S) : len(0), str((char*) 0) {set(S);}
53   ~Cstring() {destroy();}
54   void destroy() {if (str) delete [] str; len=0; str= (char*) 0;}
55
56   CS_BOOL extend (const char *);
57   CS_BOOL extend (Cstring &S) {return (extend(S.str));}
58   Cstring operator+ ( const Cstring& S) const;
59   Cstring operator+ ( const char *s) const;
60   Cstring& operator= ( const Cstring& S);
61   Cstring& operator= ( const char *c);
62   CS_BOOL operator== (const Cstring& S) const { return (*this == S.str);}
63   CS_BOOL operator== (const char * s) const;
64   CS_BOOL operator< (const char * s) const;
65   CS_BOOL operator< (const Cstring& S) const {return ((*this) < S.str);}
66   CS_BOOL operator> (const char *s) const;
67   CS_BOOL operator> (const Cstring& S) const {return ((*this) > S.str);}
68
69   const char *get() const {return (const char*) str;}
70   char *get_copy() const;
71   int getLen() const {return len;}
72   // copy the string from the input
73   void set(const Cstring& S);
74   void set(const char *s);
75
76   // use the string in the input
77   void use(char *s);
78
79   int invariant()
80     {return (((len>=0) && str) || (!len && !str));}
81
82   int empty() {return (len == 0);}
83
84 protected:
85   int len;
86   char *str;
87   int prefix_compare (const char *s, int &slen) const;
88   int prefix_compare (const Cstring& S, int &slen) const
89     {return prefix_compare(S.str, slen);}
90 };
91
92 void 
93 Cstring::use (char *use_me)
94 {
95   if (str)
96     delete [] str;
97   str = (char *)  0;
98
99   if (!use_me) {
100     len = 0;
101     return;
102   } else {
103     len = strlen(use_me);
104     if (len >= 0) {
105       str = use_me;
106       return;
107     } else {
108       len = 0;
109       return;
110     }
111   }
112 }
113
114 void Cstring::set(const Cstring& S)
115 {
116   set(S.str);
117 }
118
119 void
120 Cstring::set (const char *s)
121 {
122   if (str) 
123     delete [] str;
124   str = (char*) 0;
125
126   if (!s) {
127     len = 0;
128     return;
129   }
130
131   len = strlen(s);
132   if (len >= 0) {
133     str = new char [len + 1];
134     if (str)
135       strcpy (str, s);
136     else
137       len = 0;
138   } else
139     len = 0;
140
141   VALID(invariant());
142 }
143
144 int Cstring::operator==(const char *s) const
145 {
146   if ((len == strlen(s)) &&
147       ((!len) || (!strcmp(str, s))))
148     return CS_TRUE;
149   else
150     return 0;
151 }
152
153 //
154 // compare up to the length of the smaller string
155 // used for less than
156 //
157 int Cstring::prefix_compare(const char *s, int &slen) const
158 {
159   if (!len || !s)
160     return -2;
161
162   slen = strlen(s);
163   return (strncmp(str, s, slen > len ? len : slen));
164 }
165
166 Cstring Cstring::operator+ ( const Cstring& S) const return Ret;
167 {
168   Ret = (*this + S.str);
169   return Ret;
170 }
171
172 Cstring Cstring::operator + (const char *s) const return Ret;
173 {
174   Ret = (*this);
175   Ret.extend(s);
176   return Ret;
177 }
178
179 CS_BOOL Cstring::extend (const char *s)
180 {
181   char *new_str;
182   int new_len;
183
184   if (s) {
185     if (new_len = strlen(s)) {
186       if (new_str = new char[len + new_len + 1]) {
187         if (strcpy(new_str, str) && strcat(new_str, s)) {
188           if (str)
189             delete (str);
190           len += new_len;
191           str = new_str;
192           return (CS_TRUE);
193         }
194       }
195     }
196   } else
197     return (CS_TRUE);
198
199   return (CS_FALSE);
200 }
201  
202 Cstring& Cstring::operator= ( const Cstring& S) 
203 {
204   if (this == &S)
205     return (*this);
206   else {
207     set(S);
208     return (*this);
209   }
210 }
211
212 Cstring& Cstring::operator= ( const char *c) 
213 {
214   if (str == c)
215     return (*this);
216   else {
217     set(c);
218     return (*this);
219   }
220 }
221
222 CS_BOOL Cstring::operator< (const char * s) const { 
223   int slen, res;
224
225   if ((res = prefix_compare(s, slen)) == -2)
226     return CS_FALSE;
227   else if (res < 0)
228     return CS_TRUE;
229   else if (res > 0)
230     return CS_FALSE;
231   else
232     return (len < slen);
233 }
234
235 CS_BOOL Cstring::operator> (const char *s) const {
236   int slen, res;
237
238   if ((res = prefix_compare(s, slen)) == -2)
239     return CS_TRUE;
240   else if (res < 0)
241     return (len > slen);
242   else if (res > 0)
243     return CS_TRUE;
244   else
245     return (len > slen);
246 }
247
248 char *Cstring::get_copy() const
249 {
250   char *ret= (char*) 0;
251   if (str) 
252     ret = strdup(str);
253   return ret;
254 }
255
256
257 #endif    
258
259
260   
261