]> cygwin.com Git - cygwin-apps/setup.git/blob - String++.cc
2002-02-19 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / String++.cc
1 /*
2 * Copyright (c) 2002, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins.
13 *
14 */
15
16 // A String class to replace all the char * manipulation.
17
18 #include "String++.h"
19 #include <string.h>
20 #include <ctype.h>
21 #include "concat.h"
22 #include "io_stream.h"
23
24 // _data
25
26 String::_data::_data(_data const &aData) : count (1), theString (new unsigned char[aData.length]), cstr(0), length (aData.length) {
27 memcpy (theString, aData.theString, aData.length);
28 }
29
30 String::_data::_data(): count (1), theString(new unsigned char[0]), cstr (0), length (0) {}
31 String::_data::_data(size_t aLength): count (1), theString(new unsigned char[aLength]), cstr(0), length (aLength) {}
32 String::_data::~_data ()
33 {
34 if (theString)
35 delete[] theString;
36 if (cstr)
37 delete[] cstr;
38 }
39
40 //String
41
42 String::String (const char *acString) : theData (new _data(acString ? strlen(acString) : 0))
43 {
44 memcpy (theData->theString, acString, theData->length);
45 }
46
47 String::~String ()
48 {
49 if (--theData->count == 0)
50 delete theData;
51 }
52
53 // able to cache the result if needed.
54 char *
55 String::cstr ()
56 {
57 if (theData->length == 0)
58 return NULL;
59 char * tempcStr =new char[theData->length + 1];
60 // remove when exceptions are done
61 if (!tempcStr)
62 exit (100);
63 tempcStr[theData->length] = '\0';
64 memcpy (tempcStr, theData->theString, theData->length);
65 return tempcStr;
66 }
67
68 char *
69 String::cstr () const
70 {
71 if (theData->length == 0)
72 return NULL;
73 char * tempcStr =new char[theData->length + 1];
74 // remove when exceptions are done
75 if (!tempcStr)
76 exit (100);
77 tempcStr[theData->length] = '\0';
78 memcpy (tempcStr, theData->theString, theData->length);
79 return tempcStr;
80 }
81
82 // able to cache the result if needed.
83 char const *
84 String::cstr_oneuse () const
85 {
86 if (theData->length == 0)
87 return NULL;
88 if (theData->cstr)
89 delete[] theData->cstr;
90 theData->cstr = new char[theData->length + 1];
91 theData->cstr[theData->length] = '\0';
92 memcpy (theData->cstr, theData->theString, theData->length);
93 return theData->cstr;
94 }
95
96 // does this character exist in the string?
97 // 0 is false, 1 is the first position...
98 // XXX FIXME: Introduce npos, and change all
99 // if (size) calls to be if (size()==npos)
100 size_t
101 String::find(char aChar) const
102 {
103 for (size_t i=0; i < theData->length; ++i)
104 if (theData->theString[i] == aChar)
105 return i+1;
106 return 0;
107 }
108
109 int
110 String::compare (String const &aString, size_t const count) const
111 {
112 // trivial cases:
113 if (theData == aString.theData)
114 return 0;
115 size_t length = count ? count : theData->length;
116 if (length > theData->length)
117 length = theData->length;
118 if (length > aString.theData->length)
119 length = aString.theData->length;
120 size_t i;
121 for (i=0; i < length ; ++i)
122 if (theData->theString[i] < aString.theData->theString[i])
123 return -1;
124 else if (theData->theString[i] > aString.theData->theString[i])
125 return 1;
126 // equal for length
127 if (i == count && count != 0)
128 return 0;
129 if (theData->length < aString.theData->length)
130 return -1;
131 else if (theData->length > aString.theData->length)
132 return 1;
133 return 0;
134 }
135
136 int
137 String::casecompare (String const &aString, size_t const count) const
138 {
139 // trivial cases:
140 if (theData == aString.theData)
141 return 0;
142 size_t length = count ? count : theData->length;
143 if (length > theData->length)
144 length = theData->length;
145 if (length > aString.theData->length)
146 length = aString.theData->length;
147 size_t i;
148 for (i=0; i < length; ++i)
149 if (toupper(theData->theString[i]) < toupper(aString.theData->theString[i]))
150 return -1;
151 else if (toupper(theData->theString[i]) > toupper(aString.theData->theString[i]))
152 return 1;
153 // equal for length
154 if (i == count && count != 0)
155 return 0;
156 if (theData->length < aString.theData->length)
157 return -1;
158 else if (theData->length > aString.theData->length)
159 return 1;
160 return 0;
161 }
162
163 String
164 String::concat (const char *aString, ...)
165 {
166 va_list aList;
167 va_start (aList, aString);
168
169 return vconcat (aString, aList);
170 }
171
172 String
173 String::vconcat (const char *aString, va_list aList)
174 {
175 char *tempString = ::vconcat(aString, aList);
176 String theString = String (tempString);
177 delete[] tempString;
178 return theString;
179 }
180
181 String &
182 String::operator+= (String const &aString)
183 {
184 if (theData->count > 1)
185 {
186 _data * someData = new _data(*theData);
187 --theData->count;
188 theData = someData;
189 }
190
191 unsigned char *tempString = theData->theString;
192 theData->theString = new unsigned char [theData->length + aString.theData->length];
193 // remove when exceptions are done
194 if (!theData->theString)
195 exit (100);
196 memcpy (theData->theString, tempString, theData->length);
197 delete[] tempString;
198 memcpy (&theData->theString[theData->length], aString.theData->theString, aString.theData->length);
199 theData->length += aString.theData->length;
200 return *this;
201 }
202
203 String
204 String::operator + (String const &aString) const
205 {
206 unsigned char *tempcString = new unsigned char [theData->length + aString.theData->length];
207 // remove when exceptions are done
208 if (!tempcString)
209 exit (100);
210 memcpy (tempcString, theData->theString, theData->length);
211 memcpy (&tempcString[theData->length], aString.theData->theString, aString.theData->length);
212 return absorb (tempcString, theData->length + aString.theData->length);
213 }
214
215 String
216 String::operator + (char const *aString) const
217 {
218 // expensive, but quick to code.
219 return *this + String (aString);
220 }
221
222 bool
223 String::operator == (String const &rhs) const
224 {
225 return compare (rhs) ? false : true;
226 }
227
228 bool
229 String::operator == (char const *rhs) const
230 {
231 return compare (rhs) ? false : true;
232 }
233
234 String
235 String::absorb (unsigned char *aString, size_t aLength)
236 {
237 String theString;
238 theString.theData->theString = aString;
239 theString.theData->length = aLength;
240 return theString;
241 }
242
243 int
244 String::casecompare (String const lhs, String const rhs)
245 {
246 return lhs.casecompare (rhs);
247 }
This page took 0.049836 seconds and 6 git commands to generate.