xref: /xnu-11215/libkern/c++/OSString.cpp (revision 3ca3bd55)
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::initWithCStringNoCopy(const char *cString)
91 {
92     if (!cString || !super::init())
93         return false;
94 
95     length = strlen(cString) + 1;
96     flags |= kOSStringNoCopy;
97     string = const_cast<char *>(cString);
98 
99     return true;
100 }
101 
102 OSString *OSString::withString(const OSString *aString)
103 {
104     OSString *me = new OSString;
105 
106     if (me && !me->initWithString(aString)) {
107         me->release();
108         return 0;
109     }
110 
111     return me;
112 }
113 
114 OSString *OSString::withCString(const char *cString)
115 {
116     OSString *me = new OSString;
117 
118     if (me && !me->initWithCString(cString)) {
119         me->release();
120         return 0;
121     }
122 
123     return me;
124 }
125 
126 OSString *OSString::withCStringNoCopy(const char *cString)
127 {
128     OSString *me = new OSString;
129 
130     if (me && !me->initWithCStringNoCopy(cString)) {
131         me->release();
132         return 0;
133     }
134 
135     return me;
136 }
137 
138 /* @@@ gvdl */
139 #if 0
140 OSString *OSString::stringWithFormat(const char *format, ...)
141 {
142 #ifndef KERNEL			// mach3xxx
143     OSString *me;
144     va_list argList;
145 
146     if (!format)
147         return 0;
148 
149     va_start(argList, format);
150     me = stringWithCapacity(256);
151     me->length = vsnprintf(me->string, 256, format, argList);
152     me->length++;	// we include the null in the length
153     if (me->Length > 256)
154         me->Length = 256;
155     va_end (argList);
156 
157     return me;
158 #else
159     return 0;
160 #endif
161 }
162 #endif /* 0 */
163 
164 void OSString::free()
165 {
166     if ( !(flags & kOSStringNoCopy) && string) {
167         kfree(string, (vm_size_t)length);
168         ACCUMSIZE(-length);
169     }
170 
171     super::free();
172 }
173 
174 unsigned int OSString::getLength()  const { return length - 1; }
175 
176 const char *OSString::getCStringNoCopy() const
177 {
178     return string;
179 }
180 
181 bool OSString::setChar(char aChar, unsigned int index)
182 {
183     if ( !(flags & kOSStringNoCopy) && index < length - 1) {
184         string[index] = aChar;
185 
186         return true;
187     }
188     else
189         return false;
190 }
191 
192 char OSString::getChar(unsigned int index) const
193 {
194     if (index < length)
195         return string[index];
196     else
197         return '\0';
198 }
199 
200 
201 bool OSString::isEqualTo(const OSString *aString) const
202 {
203     if (length != aString->length)
204         return false;
205     else
206         return isEqualTo((const char *) aString->string);
207 }
208 
209 bool OSString::isEqualTo(const char *aCString) const
210 {
211     return strncmp(string, aCString, length) == 0;
212 }
213 
214 bool OSString::isEqualTo(const OSMetaClassBase *obj) const
215 {
216     OSString *	str;
217     OSData *    data;
218 
219     if ((str = OSDynamicCast(OSString, obj)))
220         return isEqualTo(str);
221     else if ((data = OSDynamicCast (OSData, obj)))
222         return isEqualTo(data);
223     else
224         return false;
225 }
226 
227 bool OSString::isEqualTo(const OSData *obj) const
228 {
229     if (NULL == obj)
230       return false;
231 
232     unsigned int dataLen = obj->getLength ();;
233     char * dataPtr = (char *) obj->getBytesNoCopy ();
234 
235     if (dataLen != length) {
236 
237       // check for the fact that OSData may be a buffer that
238       // that includes a termination byte and will thus have
239       // a length of the actual string length PLUS 1. In this
240       // case we verify that the additional byte is a terminator
241       // and if so count the two lengths as being the same.
242 
243       if ( (dataLen - length) == 1 ) {
244 	if (dataPtr[dataLen-1] != 0)
245 	  return false;
246 	dataLen--;
247       }
248       else
249 	return false;
250     }
251 
252     for ( unsigned int i=0; i < dataLen; i++ ) {
253       if ( *dataPtr++ != string[i] )
254         return false;
255     }
256 
257     return true;
258 }
259 
260 bool OSString::serialize(OSSerialize *s) const
261 {
262     char *c = string;
263 
264     if (s->previouslySerialized(this)) return true;
265 
266     if (!s->addXMLStartTag(this, "string")) return false;
267     while (*c) {
268         if (*c == '<') {
269             if (!s->addString("&lt;")) return false;
270         } else if (*c == '>') {
271             if (!s->addString("&gt;")) return false;
272         } else if (*c == '&') {
273             if (!s->addString("&amp;")) return false;
274         } else {
275             if (!s->addChar(*c)) return false;
276         }
277         c++;
278     }
279 
280     return s->addXMLEndTag("string");
281 }
282