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