]>
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
);
78 String::substr(size_t start
, int len
) const
80 // Adapt the C++ string class
81 return string(c_str()).substr(start
, len
);
85 String::compare (String
const &aString
, size_t const count
) const
88 if (theData
== aString
.theData
)
90 size_t length
= count
? count
: theData
->length
;
91 if (length
> theData
->length
)
92 length
= theData
->length
;
93 if (length
> aString
.theData
->length
)
94 length
= aString
.theData
->length
;
96 for (i
=0; i
< length
; ++i
)
97 if (theData
->theString
[i
] < aString
.theData
->theString
[i
])
99 else if (theData
->theString
[i
] > aString
.theData
->theString
[i
])
102 if (i
== count
&& count
!= 0)
104 if (theData
->length
< aString
.theData
->length
)
106 else if (theData
->length
> aString
.theData
->length
)
112 String::casecompare (String
const &aString
, size_t const count
) const
115 if (theData
== aString
.theData
)
117 size_t length
= count
? count
: theData
->length
;
118 if (length
> theData
->length
)
119 length
= theData
->length
;
120 if (length
> aString
.theData
->length
)
121 length
= aString
.theData
->length
;
123 for (i
=0; i
< length
; ++i
)
124 if (toupper(theData
->theString
[i
]) < toupper(aString
.theData
->theString
[i
]))
126 else if (toupper(theData
->theString
[i
]) > toupper(aString
.theData
->theString
[i
]))
129 if (i
== count
&& count
!= 0)
131 if (theData
->length
< aString
.theData
->length
)
133 else if (theData
->length
> aString
.theData
->length
)
139 String::operator+= (String
const &aString
)
141 if (theData
->count
> 1)
143 _data
* someData
= new _data(*theData
);
148 unsigned char *tempString
= theData
->theString
;
149 theData
->theString
= new unsigned char [theData
->length
+ aString
.theData
->length
];
150 // remove when exceptions are done
151 if (!theData
->theString
)
153 memcpy (theData
->theString
, tempString
, theData
->length
);
155 memcpy (&theData
->theString
[theData
->length
], aString
.theData
->theString
, aString
.theData
->length
);
156 theData
->length
+= aString
.theData
->length
;
161 String::operator + (String
const &aString
) const
163 unsigned char *tempcString
= new unsigned char [theData
->length
+ aString
.theData
->length
];
164 // remove when exceptions are done
167 memcpy (tempcString
, theData
->theString
, theData
->length
);
168 memcpy (&tempcString
[theData
->length
], aString
.theData
->theString
, aString
.theData
->length
);
169 return absorb (tempcString
, theData
->length
+ aString
.theData
->length
);
173 String::operator + (char const *aString
) const
175 // expensive, but quick to code.
176 return *this + String (aString
);
180 String::operator == (String
const &rhs
) const
182 return compare (rhs
) ? false : true;
186 String::operator == (char const *rhs
) const
188 return compare (rhs
) ? false : true;
192 String::operator != (String
const &rhs
) const
194 return !(*this == rhs
);
198 String::operator != (char const *rhs
) const
200 return !(*this == rhs
);
204 String::absorb (unsigned char *aString
, size_t aLength
)
207 theString
.theData
->theString
= aString
;
208 theString
.theData
->length
= aLength
;
213 new_cstr_char_array (const std::string
&s
)
215 size_t len
= s
.size();
216 char *buf
= new char[len
+ 1];
218 memcpy (buf
, s
.c_str (), len
);
223 /* TODO: research how wide char and unicode interoperate with
227 operator << (ostream
&os
, String
const &theString
)
229 os
<< theString
.c_str();
234 format_1000s (int num
, char sep
)
237 while (mult
* 1000 < num
)
240 os
<< ((num
/ mult
) % 1000);
241 for (mult
/= 1000; mult
> 0; mult
/= 1000)
243 int triplet
= (num
/ mult
) % 1000;
245 if (triplet
< 100) os
<< '0';
246 if (triplet
< 10) os
<< '0';
255 std::ostringstream os
;
261 casecompare (const std::string
& a
, const std::string
& b
, size_t limit
)
263 size_t length_to_check
= std::min(a
.length(), b
.length());
264 if (limit
&& length_to_check
> limit
)
265 length_to_check
= limit
;
268 for (i
= 0; i
< length_to_check
; ++i
)
269 if (toupper(a
[i
]) < toupper(b
[i
]))
271 else if (toupper(a
[i
]) > toupper(b
[i
]))
274 // Hit the comparison limit without finding a difference
275 if (limit
&& i
== limit
)
278 if (a
.length() < b
.length())
280 else if (a
.length() > b
.length())
287 replace(const std::string
& haystack
, const std::string
& needle
,
288 const std::string
& replacement
)
290 std::string
rv(haystack
);
291 size_t n_len
= needle
.length(), r_len
= replacement
.length(),
296 size_t pos
= rv
.find(needle
, search_start
);
297 if (pos
== std::string::npos
)
299 rv
.replace(pos
, n_len
, replacement
);
300 search_start
= pos
+ r_len
;
This page took 0.050776 seconds and 6 git commands to generate.