]> git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSString.cpp
xnu-3789.1.32.tar.gz
[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 = strnlen(cString, kMaxStringLength);
72 if (newLength >= kMaxStringLength) return false;
73
74 newLength++;
75 newString = (char *) kalloc_container(newLength);
76 if (!newString) return false;
77
78 bcopy(cString, newString, newLength);
79
80 if ( !(flags & kOSStringNoCopy) && string) {
81 kfree(string, (vm_size_t)length);
82 OSCONTAINER_ACCUMSIZE(-((size_t)length));
83 }
84 string = newString;
85 length = newLength;
86 flags &= ~kOSStringNoCopy;
87
88 OSCONTAINER_ACCUMSIZE(length);
89
90 return true;
91 }
92
93 bool OSString::initWithStringOfLength(const char *cString, size_t inlength)
94 {
95 unsigned int newLength;
96 char * newString;
97
98 if (!cString || !super::init()) return false;
99
100 if (inlength >= kMaxStringLength) return false;
101
102 newLength = inlength + 1;
103 newString = (char *) kalloc_container(newLength);
104 if (!newString) return false;
105
106 bcopy(cString, newString, inlength);
107 newString[inlength] = 0;
108
109 if ( !(flags & kOSStringNoCopy) && string) {
110 kfree(string, (vm_size_t)length);
111 OSCONTAINER_ACCUMSIZE(-((size_t)length));
112 }
113
114 string = newString;
115 length = newLength;
116 flags &= ~kOSStringNoCopy;
117
118 OSCONTAINER_ACCUMSIZE(length);
119
120 return true;
121 }
122
123 bool OSString::initWithCStringNoCopy(const char *cString)
124 {
125 if (!cString || !super::init())
126 return false;
127
128 length = strnlen(cString, kMaxStringLength);
129 if (length >= kMaxStringLength) return false;
130
131 length++;
132 flags |= kOSStringNoCopy;
133 string = const_cast<char *>(cString);
134
135 return true;
136 }
137
138 OSString *OSString::withString(const OSString *aString)
139 {
140 OSString *me = new OSString;
141
142 if (me && !me->initWithString(aString)) {
143 me->release();
144 return 0;
145 }
146
147 return me;
148 }
149
150 OSString *OSString::withCString(const char *cString)
151 {
152 OSString *me = new OSString;
153
154 if (me && !me->initWithCString(cString)) {
155 me->release();
156 return 0;
157 }
158
159 return me;
160 }
161
162 OSString *OSString::withCStringNoCopy(const char *cString)
163 {
164 OSString *me = new OSString;
165
166 if (me && !me->initWithCStringNoCopy(cString)) {
167 me->release();
168 return 0;
169 }
170
171 return me;
172 }
173
174 OSString *OSString::withStringOfLength(const char *cString, size_t length)
175 {
176 OSString *me = new OSString;
177
178 if (me && !me->initWithStringOfLength(cString, length)) {
179 me->release();
180 return 0;
181 }
182
183 return me;
184 }
185
186
187
188 /* @@@ gvdl */
189 #if 0
190 OSString *OSString::stringWithFormat(const char *format, ...)
191 {
192 #ifndef KERNEL // mach3xxx
193 OSString *me;
194 va_list argList;
195
196 if (!format)
197 return 0;
198
199 va_start(argList, format);
200 me = stringWithCapacity(256);
201 me->length = vsnprintf(me->string, 256, format, argList);
202 me->length++; // we include the null in the length
203 if (me->Length > 256)
204 me->Length = 256;
205 va_end (argList);
206
207 return me;
208 #else
209 return 0;
210 #endif
211 }
212 #endif /* 0 */
213
214 void OSString::free()
215 {
216 if ( !(flags & kOSStringNoCopy) && string) {
217 kfree(string, (vm_size_t)length);
218 OSCONTAINER_ACCUMSIZE(-((size_t)length));
219 }
220
221 super::free();
222 }
223
224 unsigned int OSString::getLength() const { return length - 1; }
225
226 const char *OSString::getCStringNoCopy() const
227 {
228 return string;
229 }
230
231 bool OSString::setChar(char aChar, unsigned int index)
232 {
233 if ( !(flags & kOSStringNoCopy) && index < length - 1) {
234 string[index] = aChar;
235
236 return true;
237 }
238 else
239 return false;
240 }
241
242 char OSString::getChar(unsigned int index) const
243 {
244 if (index < length)
245 return string[index];
246 else
247 return '\0';
248 }
249
250
251 bool OSString::isEqualTo(const OSString *aString) const
252 {
253 if (length != aString->length)
254 return false;
255 else
256 return isEqualTo((const char *) aString->string);
257 }
258
259 bool OSString::isEqualTo(const char *aCString) const
260 {
261 return strncmp(string, aCString, length) == 0;
262 }
263
264 bool OSString::isEqualTo(const OSMetaClassBase *obj) const
265 {
266 OSString * str;
267 OSData * data;
268
269 if ((str = OSDynamicCast(OSString, obj)))
270 return isEqualTo(str);
271 else if ((data = OSDynamicCast (OSData, obj)))
272 return isEqualTo(data);
273 else
274 return false;
275 }
276
277 bool OSString::isEqualTo(const OSData *obj) const
278 {
279 if (NULL == obj)
280 return false;
281
282 unsigned int dataLen = obj->getLength ();;
283 char * dataPtr = (char *) obj->getBytesNoCopy ();
284
285 if (dataLen != length) {
286
287 // check for the fact that OSData may be a buffer that
288 // that includes a termination byte and will thus have
289 // a length of the actual string length PLUS 1. In this
290 // case we verify that the additional byte is a terminator
291 // and if so count the two lengths as being the same.
292
293 if ( (dataLen - length) == 1 ) {
294 if (dataPtr[dataLen-1] != 0)
295 return false;
296 dataLen--;
297 }
298 else
299 return false;
300 }
301
302 for ( unsigned int i=0; i < dataLen; i++ ) {
303 if ( *dataPtr++ != string[i] )
304 return false;
305 }
306
307 return true;
308 }
309
310 bool OSString::serialize(OSSerialize *s) const
311 {
312 char *c = string;
313
314 if (s->previouslySerialized(this)) return true;
315
316 if (!s->addXMLStartTag(this, "string")) return false;
317 while (*c) {
318 if (*c == '<') {
319 if (!s->addString("&lt;")) return false;
320 } else if (*c == '>') {
321 if (!s->addString("&gt;")) return false;
322 } else if (*c == '&') {
323 if (!s->addString("&amp;")) return false;
324 } else {
325 if (!s->addChar(*c)) return false;
326 }
327 c++;
328 }
329
330 return s->addXMLEndTag("string");
331 }