]> git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSString.cpp
2bd875ee6b5cbd01d247170ca02a144fe02ad1b6
[apple/xnu.git] / libkern / c++ / OSString.cpp
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /* IOString.m created by rsulack on Wed 17-Sep-1997 */
29 /* IOString.cpp converted to C++ on Tue 1998-9-22 */
30
31 #include <string.h>
32
33 #include <libkern/c++/OSString.h>
34 #include <libkern/c++/OSSerialize.h>
35 #include <libkern/c++/OSLib.h>
36 #include <libkern/c++/OSData.h>
37 #include <string.h>
38
39 #define super OSObject
40
41 OSDefineMetaClassAndStructors(OSString, OSObject)
42 OSMetaClassDefineReservedUnused(OSString, 0);
43 OSMetaClassDefineReservedUnused(OSString, 1);
44 OSMetaClassDefineReservedUnused(OSString, 2);
45 OSMetaClassDefineReservedUnused(OSString, 3);
46 OSMetaClassDefineReservedUnused(OSString, 4);
47 OSMetaClassDefineReservedUnused(OSString, 5);
48 OSMetaClassDefineReservedUnused(OSString, 6);
49 OSMetaClassDefineReservedUnused(OSString, 7);
50 OSMetaClassDefineReservedUnused(OSString, 8);
51 OSMetaClassDefineReservedUnused(OSString, 9);
52 OSMetaClassDefineReservedUnused(OSString, 10);
53 OSMetaClassDefineReservedUnused(OSString, 11);
54 OSMetaClassDefineReservedUnused(OSString, 12);
55 OSMetaClassDefineReservedUnused(OSString, 13);
56 OSMetaClassDefineReservedUnused(OSString, 14);
57 OSMetaClassDefineReservedUnused(OSString, 15);
58
59 bool OSString::initWithString(const OSString *aString)
60 {
61 return initWithCString(aString->string);
62 }
63
64 bool OSString::initWithCString(const char *cString)
65 {
66 unsigned int newLength;
67 char * newString;
68
69 if (!cString || !super::init()) return false;
70
71 newLength = strlen(cString) + 1;
72 newString = (char *) kalloc_container(newLength);
73 if (!newString) return false;
74
75 bcopy(cString, newString, newLength);
76
77 if ( !(flags & kOSStringNoCopy) && string) {
78 kfree(string, (vm_size_t)length);
79 OSCONTAINER_ACCUMSIZE(-((size_t)length));
80 }
81 string = newString;
82 length = newLength;
83 flags &= ~kOSStringNoCopy;
84
85 OSCONTAINER_ACCUMSIZE(length);
86
87 return true;
88 }
89
90 bool OSString::initWithStringOfLength(const char *cString, size_t inlength)
91 {
92 unsigned int newLength;
93 char * newString;
94
95 if (!cString || !super::init()) return false;
96
97 newLength = inlength + 1;
98 newString = (char *) kalloc_container(newLength);
99 if (!newString) return false;
100
101 bcopy(cString, newString, inlength);
102 newString[inlength] = 0;
103
104 if ( !(flags & kOSStringNoCopy) && string) {
105 kfree(string, (vm_size_t)length);
106 OSCONTAINER_ACCUMSIZE(-((size_t)length));
107 }
108
109 string = newString;
110 length = newLength;
111 flags &= ~kOSStringNoCopy;
112
113 OSCONTAINER_ACCUMSIZE(length);
114
115 return true;
116 }
117
118 bool OSString::initWithCStringNoCopy(const char *cString)
119 {
120 if (!cString || !super::init())
121 return false;
122
123 length = strlen(cString) + 1;
124 flags |= kOSStringNoCopy;
125 string = const_cast<char *>(cString);
126
127 return true;
128 }
129
130 OSString *OSString::withString(const OSString *aString)
131 {
132 OSString *me = new OSString;
133
134 if (me && !me->initWithString(aString)) {
135 me->release();
136 return 0;
137 }
138
139 return me;
140 }
141
142 OSString *OSString::withCString(const char *cString)
143 {
144 OSString *me = new OSString;
145
146 if (me && !me->initWithCString(cString)) {
147 me->release();
148 return 0;
149 }
150
151 return me;
152 }
153
154 OSString *OSString::withCStringNoCopy(const char *cString)
155 {
156 OSString *me = new OSString;
157
158 if (me && !me->initWithCStringNoCopy(cString)) {
159 me->release();
160 return 0;
161 }
162
163 return me;
164 }
165
166 OSString *OSString::withStringOfLength(const char *cString, size_t length)
167 {
168 OSString *me = new OSString;
169
170 if (me && !me->initWithStringOfLength(cString, length)) {
171 me->release();
172 return 0;
173 }
174
175 return me;
176 }
177
178
179
180 /* @@@ gvdl */
181 #if 0
182 OSString *OSString::stringWithFormat(const char *format, ...)
183 {
184 #ifndef KERNEL // mach3xxx
185 OSString *me;
186 va_list argList;
187
188 if (!format)
189 return 0;
190
191 va_start(argList, format);
192 me = stringWithCapacity(256);
193 me->length = vsnprintf(me->string, 256, format, argList);
194 me->length++; // we include the null in the length
195 if (me->Length > 256)
196 me->Length = 256;
197 va_end (argList);
198
199 return me;
200 #else
201 return 0;
202 #endif
203 }
204 #endif /* 0 */
205
206 void OSString::free()
207 {
208 if ( !(flags & kOSStringNoCopy) && string) {
209 kfree(string, (vm_size_t)length);
210 OSCONTAINER_ACCUMSIZE(-((size_t)length));
211 }
212
213 super::free();
214 }
215
216 unsigned int OSString::getLength() const { return length - 1; }
217
218 const char *OSString::getCStringNoCopy() const
219 {
220 return string;
221 }
222
223 bool OSString::setChar(char aChar, unsigned int index)
224 {
225 if ( !(flags & kOSStringNoCopy) && index < length - 1) {
226 string[index] = aChar;
227
228 return true;
229 }
230 else
231 return false;
232 }
233
234 char OSString::getChar(unsigned int index) const
235 {
236 if (index < length)
237 return string[index];
238 else
239 return '\0';
240 }
241
242
243 bool OSString::isEqualTo(const OSString *aString) const
244 {
245 if (length != aString->length)
246 return false;
247 else
248 return isEqualTo((const char *) aString->string);
249 }
250
251 bool OSString::isEqualTo(const char *aCString) const
252 {
253 return strncmp(string, aCString, length) == 0;
254 }
255
256 bool OSString::isEqualTo(const OSMetaClassBase *obj) const
257 {
258 OSString * str;
259 OSData * data;
260
261 if ((str = OSDynamicCast(OSString, obj)))
262 return isEqualTo(str);
263 else if ((data = OSDynamicCast (OSData, obj)))
264 return isEqualTo(data);
265 else
266 return false;
267 }
268
269 bool OSString::isEqualTo(const OSData *obj) const
270 {
271 if (NULL == obj)
272 return false;
273
274 unsigned int dataLen = obj->getLength ();;
275 char * dataPtr = (char *) obj->getBytesNoCopy ();
276
277 if (dataLen != length) {
278
279 // check for the fact that OSData may be a buffer that
280 // that includes a termination byte and will thus have
281 // a length of the actual string length PLUS 1. In this
282 // case we verify that the additional byte is a terminator
283 // and if so count the two lengths as being the same.
284
285 if ( (dataLen - length) == 1 ) {
286 if (dataPtr[dataLen-1] != 0)
287 return false;
288 dataLen--;
289 }
290 else
291 return false;
292 }
293
294 for ( unsigned int i=0; i < dataLen; i++ ) {
295 if ( *dataPtr++ != string[i] )
296 return false;
297 }
298
299 return true;
300 }
301
302 bool OSString::serialize(OSSerialize *s) const
303 {
304 char *c = string;
305
306 if (s->previouslySerialized(this)) return true;
307
308 if (!s->addXMLStartTag(this, "string")) return false;
309 while (*c) {
310 if (*c == '<') {
311 if (!s->addString("&lt;")) return false;
312 } else if (*c == '>') {
313 if (!s->addString("&gt;")) return false;
314 } else if (*c == '&') {
315 if (!s->addString("&amp;")) return false;
316 } else {
317 if (!s->addChar(*c)) return false;
318 }
319 c++;
320 }
321
322 return s->addXMLEndTag("string");
323 }