xref: /xnu-11215/libkern/c++/OSString.cpp (revision a3bb9fcc)
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 }
314