]>
cygwin.com Git - cygwin-apps/setup.git/blob - String++.cc
2 * Copyright (c) 2002, Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins.
16 // A String class to replace all the char * manipulation.
21 #include "io_stream.h"
31 String::_data::_data(_data
const &aData
) : count (1), theString (new unsigned char[aData
.length
]), cstr(0), length (aData
.length
) {
32 memcpy (theString
, aData
.theString
, aData
.length
);
35 String::_data::_data(): count (1), theString(new unsigned char[0]), cstr (0), length (0) {}
36 String::_data::_data(size_t aLength
): count (1), theString(new unsigned char[aLength
]), cstr(0), length (aLength
) {}
37 String::_data::~_data ()
47 String::String (const char *acString
) : theData (new _data(acString
? strlen(acString
) : 0))
49 memcpy (theData
->theString
, acString
, theData
->length
);
54 if (--theData
->count
== 0)
58 String::String (string
const &aString
) : theData (new _data (aString
.c_str() ? strlen (aString
.c_str()) : 0))
60 memcpy (theData
->theString
, aString
.c_str(), theData
->length
);
63 // able to cache the result if needed.
65 String::c_str () const
67 if (theData
->length
== 0)
70 delete[] theData
->cstr
;
71 theData
->cstr
= new char[theData
->length
+ 1];
72 theData
->cstr
[theData
->length
] = '\0';
73 memcpy (theData
->cstr
, theData
->theString
, theData
->length
);
77 // does this character exist in the string?
78 // 0 is false, 1 is the first position...
79 // XXX FIXME: Introduce npos, and change all
80 // if (size) calls to be if (size()==npos)
82 String::find(char aChar
) const
84 for (size_t i
=0; i
< theData
->length
; ++i
)
85 if (theData
->theString
[i
] == aChar
)
91 String::substr(size_t start
, int len
) const
93 // Adapt the C++ string class
94 return string(c_str()).substr(start
, len
);
98 String::compare (String
const &aString
, size_t const count
) const
101 if (theData
== aString
.theData
)
103 size_t length
= count
? count
: theData
->length
;
104 if (length
> theData
->length
)
105 length
= theData
->length
;
106 if (length
> aString
.theData
->length
)
107 length
= aString
.theData
->length
;
109 for (i
=0; i
< length
; ++i
)
110 if (theData
->theString
[i
] < aString
.theData
->theString
[i
])
112 else if (theData
->theString
[i
] > aString
.theData
->theString
[i
])
115 if (i
== count
&& count
!= 0)
117 if (theData
->length
< aString
.theData
->length
)
119 else if (theData
->length
> aString
.theData
->length
)
125 String::casecompare (String
const &aString
, size_t const count
) const
128 if (theData
== aString
.theData
)
130 size_t length
= count
? count
: theData
->length
;
131 if (length
> theData
->length
)
132 length
= theData
->length
;
133 if (length
> aString
.theData
->length
)
134 length
= aString
.theData
->length
;
136 for (i
=0; i
< length
; ++i
)
137 if (toupper(theData
->theString
[i
]) < toupper(aString
.theData
->theString
[i
]))
139 else if (toupper(theData
->theString
[i
]) > toupper(aString
.theData
->theString
[i
]))
142 if (i
== count
&& count
!= 0)
144 if (theData
->length
< aString
.theData
->length
)
146 else if (theData
->length
> aString
.theData
->length
)
152 String::operator+= (String
const &aString
)
154 if (theData
->count
> 1)
156 _data
* someData
= new _data(*theData
);
161 unsigned char *tempString
= theData
->theString
;
162 theData
->theString
= new unsigned char [theData
->length
+ aString
.theData
->length
];
163 // remove when exceptions are done
164 if (!theData
->theString
)
166 memcpy (theData
->theString
, tempString
, theData
->length
);
168 memcpy (&theData
->theString
[theData
->length
], aString
.theData
->theString
, aString
.theData
->length
);
169 theData
->length
+= aString
.theData
->length
;
174 String::operator + (String
const &aString
) const
176 unsigned char *tempcString
= new unsigned char [theData
->length
+ aString
.theData
->length
];
177 // remove when exceptions are done
180 memcpy (tempcString
, theData
->theString
, theData
->length
);
181 memcpy (&tempcString
[theData
->length
], aString
.theData
->theString
, aString
.theData
->length
);
182 return absorb (tempcString
, theData
->length
+ aString
.theData
->length
);
186 String::operator + (char const *aString
) const
188 // expensive, but quick to code.
189 return *this + String (aString
);
193 String::operator == (String
const &rhs
) const
195 return compare (rhs
) ? false : true;
199 String::operator == (char const *rhs
) const
201 return compare (rhs
) ? false : true;
205 String::operator != (String
const &rhs
) const
207 return !(*this == rhs
);
211 String::operator != (char const *rhs
) const
213 return !(*this == rhs
);
217 String::absorb (unsigned char *aString
, size_t aLength
)
220 theString
.theData
->theString
= aString
;
221 theString
.theData
->length
= aLength
;
226 String::replace (char pattern
, char replacement
) const
228 unsigned char *tempcString
= new unsigned char [theData
->length
];
229 // remove when exceptions are done
232 unsigned char *s
= theData
->theString
;
233 unsigned char *d
= tempcString
;
234 unsigned char *end
= theData
->theString
+ theData
->length
;
235 for (s
= theData
->theString
; s
< end
; ++s
)
242 return absorb (tempcString
, theData
->length
);
246 String::replace (String
const &pattern
, String
const &replacement
) const
248 int growth
= replacement
.theData
->length
- pattern
.theData
->length
+ 1;
249 if (growth
< 1) growth
= 1;
250 unsigned char *tempcString
= new unsigned char [theData
->length
* growth
];
251 // remove when exceptions are done
254 unsigned char *s
= theData
->theString
;
255 unsigned char *d
= tempcString
;
256 unsigned char *end
= theData
->theString
+ theData
->length
;
257 for (s
= theData
->theString
; s
< end
- pattern
.theData
->length
; )
259 if (memcmp(s
, pattern
.theData
->theString
, pattern
.theData
->length
) == 0)
261 s
+= pattern
.theData
->length
;
262 memcpy(d
, replacement
.theData
->theString
, replacement
.theData
->length
);
263 d
+= replacement
.theData
->length
;
270 size_t length
= d
- tempcString
;
271 // Avoid wasting space
272 unsigned char *newCopy
= new unsigned char[length
];
273 // remove when exceptions are done
276 memcpy (newCopy
, tempcString
, length
);
277 delete[] tempcString
;
279 return absorb (newCopy
, length
);
283 new_cstr_char_array (const String
&s
)
285 size_t len
= s
.size();
286 char *buf
= new char[len
+ 1];
288 memcpy (buf
, s
.c_str (), len
);
293 /* TODO: research how wide char and unicode interoperate with
297 operator << (ostream
&os
, String
const &theString
)
299 os
<< theString
.c_str();
304 format_1000s(const int num
, char sep
)
307 while (mult
* 1000 < num
)
310 os
<< ((num
/ mult
) % 1000);
311 for (mult
/= 1000; mult
> 0; mult
/= 1000)
313 int triplet
= (num
/ mult
) % 1000;
315 if (triplet
< 100) os
<< '0';
316 if (triplet
< 10) os
<< '0';
319 return String(os
.str());
325 std::ostringstream os
;
331 casecompare (const std::string
& a
, const std::string
& b
, size_t limit
)
333 size_t length_to_check
= std::min(a
.length(), b
.length());
334 if (limit
&& length_to_check
> limit
)
335 length_to_check
= limit
;
338 for (i
= 0; i
< length_to_check
; ++i
)
339 if (toupper(a
[i
]) < toupper(b
[i
]))
341 else if (toupper(a
[i
]) > toupper(b
[i
]))
344 // Hit the comparison limit without finding a difference
345 if (limit
&& i
== limit
)
348 if (a
.length() < b
.length())
350 else if (a
.length() > b
.length())
357 replace(const std::string
& haystack
, const std::string
& needle
,
358 const std::string
& replacement
)
360 std::string
rv(haystack
);
361 size_t n_len
= needle
.length(), r_len
= replacement
.length(),
366 size_t pos
= rv
.find(needle
, search_start
);
367 if (pos
== std::string::npos
)
369 rv
.replace(pos
, n_len
, replacement
);
370 search_start
= pos
+ r_len
;
This page took 0.052764 seconds and 6 git commands to generate.