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