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