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