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