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