]> cygwin.com Git - cygwin-apps/setup.git/blame - String++.cc
2003-03-16 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / String++.cc
CommitLineData
3c054baf
RC
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>
3c054baf 21#include "io_stream.h"
6391823e 22#include <iostream>
15004270 23#include <sstream>
b401ef47 24#include <string>
3c054baf 25
6625e635
RC
26using namespace std;
27
3c054baf
RC
28// _data
29
30String::_data::_data(_data const &aData) : count (1), theString (new unsigned char[aData.length]), cstr(0), length (aData.length) {
31 memcpy (theString, aData.theString, aData.length);
32}
33
34String::_data::_data(): count (1), theString(new unsigned char[0]), cstr (0), length (0) {}
35String::_data::_data(size_t aLength): count (1), theString(new unsigned char[aLength]), cstr(0), length (aLength) {}
36String::_data::~_data ()
37{
38 if (theString)
39 delete[] theString;
40 if (cstr)
41 delete[] cstr;
42}
43
44//String
45
46String::String (const char *acString) : theData (new _data(acString ? strlen(acString) : 0))
47{
48 memcpy (theData->theString, acString, theData->length);
49}
50
51String::~String ()
52{
53 if (--theData->count == 0)
54 delete theData;
55}
56
076654e7
RC
57String::String (int const anInt)
58{
15004270 59 ostringstream os;
076654e7 60 os << anInt;
15004270
RC
61 theData = new _data(os.str().size());
62 memcpy (theData->theString, os.str().c_str(), os.str().size());
076654e7
RC
63}
64
b401ef47
RC
65String::String (string const &aString) : theData (new _data (aString.c_str() ? strlen (aString.c_str()) : 0))
66{
67 memcpy (theData->theString, aString.c_str(), theData->length);
68}
69
3c054baf
RC
70// able to cache the result if needed.
71char *
72String::cstr ()
73{
74 if (theData->length == 0)
75 return NULL;
76 char * tempcStr =new char[theData->length + 1];
77 // remove when exceptions are done
78 if (!tempcStr)
79 exit (100);
80 tempcStr[theData->length] = '\0';
81 memcpy (tempcStr, theData->theString, theData->length);
82 return tempcStr;
83}
84
85char *
86String::cstr () const
87{
88 if (theData->length == 0)
89 return NULL;
90 char * tempcStr =new char[theData->length + 1];
91 // remove when exceptions are done
92 if (!tempcStr)
93 exit (100);
94 tempcStr[theData->length] = '\0';
95 memcpy (tempcStr, theData->theString, theData->length);
96 return tempcStr;
97}
98
99// able to cache the result if needed.
100char const *
101String::cstr_oneuse () const
102{
103 if (theData->length == 0)
104 return NULL;
105 if (theData->cstr)
106 delete[] theData->cstr;
107 theData->cstr = new char[theData->length + 1];
108 theData->cstr[theData->length] = '\0';
109 memcpy (theData->cstr, theData->theString, theData->length);
110 return theData->cstr;
111}
112
113// does this character exist in the string?
114// 0 is false, 1 is the first position...
115// XXX FIXME: Introduce npos, and change all
116// if (size) calls to be if (size()==npos)
117size_t
118String::find(char aChar) const
119{
120 for (size_t i=0; i < theData->length; ++i)
121 if (theData->theString[i] == aChar)
122 return i+1;
123 return 0;
124}
125
b401ef47 126String
ad646f43 127String::substr(size_t start, int len) const
b401ef47
RC
128{
129 // Adapt the C++ string class
130 return string(cstr_oneuse()).substr(start, len);
131}
132
3c054baf
RC
133int
134String::compare (String const &aString, size_t const count) const
135{
136 // trivial cases:
137 if (theData == aString.theData)
138 return 0;
139 size_t length = count ? count : theData->length;
140 if (length > theData->length)
141 length = theData->length;
142 if (length > aString.theData->length)
143 length = aString.theData->length;
144 size_t i;
145 for (i=0; i < length ; ++i)
146 if (theData->theString[i] < aString.theData->theString[i])
147 return -1;
148 else if (theData->theString[i] > aString.theData->theString[i])
149 return 1;
150 // equal for length
151 if (i == count && count != 0)
152 return 0;
153 if (theData->length < aString.theData->length)
154 return -1;
155 else if (theData->length > aString.theData->length)
156 return 1;
157 return 0;
158}
159
160int
161String::casecompare (String const &aString, size_t const count) const
162{
163 // trivial cases:
164 if (theData == aString.theData)
165 return 0;
166 size_t length = count ? count : theData->length;
167 if (length > theData->length)
168 length = theData->length;
169 if (length > aString.theData->length)
170 length = aString.theData->length;
171 size_t i;
172 for (i=0; i < length; ++i)
173 if (toupper(theData->theString[i]) < toupper(aString.theData->theString[i]))
174 return -1;
175 else if (toupper(theData->theString[i]) > toupper(aString.theData->theString[i]))
176 return 1;
177 // equal for length
178 if (i == count && count != 0)
179 return 0;
180 if (theData->length < aString.theData->length)
181 return -1;
182 else if (theData->length > aString.theData->length)
183 return 1;
184 return 0;
185}
186
3c054baf
RC
187String &
188String::operator+= (String const &aString)
189{
190 if (theData->count > 1)
191 {
192 _data * someData = new _data(*theData);
193 --theData->count;
194 theData = someData;
195 }
196
197 unsigned char *tempString = theData->theString;
198 theData->theString = new unsigned char [theData->length + aString.theData->length];
199 // remove when exceptions are done
200 if (!theData->theString)
201 exit (100);
202 memcpy (theData->theString, tempString, theData->length);
203 delete[] tempString;
204 memcpy (&theData->theString[theData->length], aString.theData->theString, aString.theData->length);
205 theData->length += aString.theData->length;
206 return *this;
207}
208
209String
210String::operator + (String const &aString) const
211{
212 unsigned char *tempcString = new unsigned char [theData->length + aString.theData->length];
213 // remove when exceptions are done
214 if (!tempcString)
215 exit (100);
216 memcpy (tempcString, theData->theString, theData->length);
217 memcpy (&tempcString[theData->length], aString.theData->theString, aString.theData->length);
218 return absorb (tempcString, theData->length + aString.theData->length);
219}
220
221String
222String::operator + (char const *aString) const
223{
224 // expensive, but quick to code.
225 return *this + String (aString);
226}
227
228bool
229String::operator == (String const &rhs) const
230{
231 return compare (rhs) ? false : true;
232}
233
234bool
235String::operator == (char const *rhs) const
236{
237 return compare (rhs) ? false : true;
238}
239
240String
241String::absorb (unsigned char *aString, size_t aLength)
242{
243 String theString;
244 theString.theData->theString = aString;
245 theString.theData->length = aLength;
246 return theString;
247}
248
249int
250String::casecompare (String const lhs, String const rhs)
251{
252 return lhs.casecompare (rhs);
253}
6391823e
RC
254
255/* TODO: research how wide char and unicode interoperate with
256 * C++ streams
257 */
258ostream &
259operator << (ostream &os, String const &theString)
260{
261 os << theString.cstr_oneuse();
262 return os;
263}
This page took 0.060522 seconds and 5 git commands to generate.