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