xref: /xnu-11215/libkern/c++/OSString.cpp (revision bb611c8f)
1c1dac77fSApple OSS Distributions /*
2a5e72196SApple OSS Distributions  * Copyright (c) 2019 Apple 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 
31*bb611c8fSApple OSS Distributions #define IOKIT_ENABLE_SHARED_PTR
32*bb611c8fSApple OSS Distributions 
33fad439e7SApple OSS Distributions #include <string.h>
34c1dac77fSApple OSS Distributions 
35c1dac77fSApple OSS Distributions #include <libkern/c++/OSString.h>
36c1dac77fSApple OSS Distributions #include <libkern/c++/OSSerialize.h>
37*bb611c8fSApple OSS Distributions #include <libkern/c++/OSSharedPtr.h>
38c1dac77fSApple OSS Distributions #include <libkern/c++/OSLib.h>
39c1dac77fSApple OSS Distributions #include <libkern/c++/OSData.h>
40fad439e7SApple OSS Distributions #include <string.h>
41c1dac77fSApple OSS Distributions 
42c1dac77fSApple OSS Distributions #define super OSObject
43c1dac77fSApple OSS Distributions 
44*bb611c8fSApple OSS Distributions OSDefineMetaClassAndStructorsWithZone(OSString, OSObject,
45*bb611c8fSApple OSS Distributions     (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM))
46c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 0);
47c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 1);
48c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 2);
49c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 3);
50c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 4);
51c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 5);
52c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 6);
53c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 7);
54c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 8);
55c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 9);
56c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 10);
57c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 11);
58c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 12);
59c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 13);
60c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 14);
61c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(OSString, 15);
62c1dac77fSApple OSS Distributions 
63a5e72196SApple OSS Distributions bool
64a5e72196SApple OSS Distributions OSString::initWithString(const OSString *aString)
65c1dac77fSApple OSS Distributions {
66c1dac77fSApple OSS Distributions 	return initWithCString(aString->string);
67c1dac77fSApple OSS Distributions }
68c1dac77fSApple OSS Distributions 
69a5e72196SApple OSS Distributions bool
70a5e72196SApple OSS Distributions OSString::initWithCString(const char *cString)
71c1dac77fSApple OSS Distributions {
720f3703acSApple OSS Distributions 	unsigned int   newLength;
730f3703acSApple OSS Distributions 	char         * newString;
74c1dac77fSApple OSS Distributions 
75a5e72196SApple OSS Distributions 	if (!cString || !super::init()) {
76a5e72196SApple OSS Distributions 		return false;
77a5e72196SApple OSS Distributions 	}
78c1dac77fSApple OSS Distributions 
79*bb611c8fSApple OSS Distributions 	newLength = (unsigned int) strnlen(cString, kMaxStringLength);
80a5e72196SApple OSS Distributions 	if (newLength >= kMaxStringLength) {
81a5e72196SApple OSS Distributions 		return false;
82a5e72196SApple OSS Distributions 	}
8388cc0b97SApple OSS Distributions 
8488cc0b97SApple OSS Distributions 	newLength++;
85*bb611c8fSApple OSS Distributions 	newString = (char *)kalloc_data_container(newLength, Z_WAITOK);
86a5e72196SApple OSS Distributions 	if (!newString) {
87a5e72196SApple OSS Distributions 		return false;
88a5e72196SApple OSS Distributions 	}
89c1dac77fSApple OSS Distributions 
900f3703acSApple OSS Distributions 	bcopy(cString, newString, newLength);
910f3703acSApple OSS Distributions 
920f3703acSApple OSS Distributions 	if (!(flags & kOSStringNoCopy) && string) {
93*bb611c8fSApple OSS Distributions 		kfree_data_container(string, length);
940f3703acSApple OSS Distributions 		OSCONTAINER_ACCUMSIZE(-((size_t)length));
950f3703acSApple OSS Distributions 	}
960f3703acSApple OSS Distributions 	string = newString;
970f3703acSApple OSS Distributions 	length = newLength;
980f3703acSApple OSS Distributions 	flags &= ~kOSStringNoCopy;
990f3703acSApple OSS Distributions 
1000f3703acSApple OSS Distributions 	OSCONTAINER_ACCUMSIZE(length);
101c1dac77fSApple OSS Distributions 
102c1dac77fSApple OSS Distributions 	return true;
103c1dac77fSApple OSS Distributions }
104c1dac77fSApple OSS Distributions 
105a5e72196SApple OSS Distributions bool
106a5e72196SApple OSS Distributions OSString::initWithStringOfLength(const char *cString, size_t inlength)
107a3bb9fccSApple OSS Distributions {
1080f3703acSApple OSS Distributions 	unsigned int   newLength;
1090f3703acSApple OSS Distributions 	char         * newString;
110a3bb9fccSApple OSS Distributions 
111a5e72196SApple OSS Distributions 	if (!cString || !super::init()) {
112a5e72196SApple OSS Distributions 		return false;
113a5e72196SApple OSS Distributions 	}
114a3bb9fccSApple OSS Distributions 
115a5e72196SApple OSS Distributions 	if (inlength >= kMaxStringLength) {
116a5e72196SApple OSS Distributions 		return false;
117a5e72196SApple OSS Distributions 	}
118a5e72196SApple OSS Distributions 
119a5e72196SApple OSS Distributions 	if (strnlen(cString, inlength) < inlength) {
120a5e72196SApple OSS Distributions 		return false;
121a5e72196SApple OSS Distributions 	}
12288cc0b97SApple OSS Distributions 
123*bb611c8fSApple OSS Distributions 	newLength = (unsigned int) (inlength + 1);
124*bb611c8fSApple OSS Distributions 	newString = (char *)kalloc_data_container(newLength, Z_WAITOK);
125a5e72196SApple OSS Distributions 	if (!newString) {
126a5e72196SApple OSS Distributions 		return false;
127a5e72196SApple OSS Distributions 	}
128a3bb9fccSApple OSS Distributions 
1290f3703acSApple OSS Distributions 	bcopy(cString, newString, inlength);
1300f3703acSApple OSS Distributions 	newString[inlength] = 0;
1310f3703acSApple OSS Distributions 
1320f3703acSApple OSS Distributions 	if (!(flags & kOSStringNoCopy) && string) {
133*bb611c8fSApple OSS Distributions 		kfree_data_container(string, length);
1340f3703acSApple OSS Distributions 		OSCONTAINER_ACCUMSIZE(-((size_t)length));
1350f3703acSApple OSS Distributions 	}
1360f3703acSApple OSS Distributions 
1370f3703acSApple OSS Distributions 	string = newString;
1380f3703acSApple OSS Distributions 	length = newLength;
1390f3703acSApple OSS Distributions 	flags &= ~kOSStringNoCopy;
1400f3703acSApple OSS Distributions 
1410f3703acSApple OSS Distributions 	OSCONTAINER_ACCUMSIZE(length);
142a3bb9fccSApple OSS Distributions 
143a3bb9fccSApple OSS Distributions 	return true;
144a3bb9fccSApple OSS Distributions }
145a3bb9fccSApple OSS Distributions 
146a5e72196SApple OSS Distributions bool
147a5e72196SApple OSS Distributions OSString::initWithCStringNoCopy(const char *cString)
148c1dac77fSApple OSS Distributions {
149a5e72196SApple OSS Distributions 	if (!cString || !super::init()) {
150c1dac77fSApple OSS Distributions 		return false;
151a5e72196SApple OSS Distributions 	}
152c1dac77fSApple OSS Distributions 
153*bb611c8fSApple OSS Distributions 	length = (unsigned int) strnlen(cString, kMaxStringLength);
154a5e72196SApple OSS Distributions 	if (length >= kMaxStringLength) {
155a5e72196SApple OSS Distributions 		return false;
156a5e72196SApple OSS Distributions 	}
15788cc0b97SApple OSS Distributions 
15888cc0b97SApple OSS Distributions 	length++;
159c1dac77fSApple OSS Distributions 	flags |= kOSStringNoCopy;
1603ca3bd55SApple OSS Distributions 	string = const_cast<char *>(cString);
161c1dac77fSApple OSS Distributions 
162c1dac77fSApple OSS Distributions 	return true;
163c1dac77fSApple OSS Distributions }
164c1dac77fSApple OSS Distributions 
165*bb611c8fSApple OSS Distributions OSSharedPtr<OSString>
166a5e72196SApple OSS Distributions OSString::withString(const OSString *aString)
167c1dac77fSApple OSS Distributions {
168*bb611c8fSApple OSS Distributions 	OSSharedPtr<OSString> me = OSMakeShared<OSString>();
169c1dac77fSApple OSS Distributions 
170c1dac77fSApple OSS Distributions 	if (me && !me->initWithString(aString)) {
171*bb611c8fSApple OSS Distributions 		return nullptr;
172c1dac77fSApple OSS Distributions 	}
173c1dac77fSApple OSS Distributions 
174c1dac77fSApple OSS Distributions 	return me;
175c1dac77fSApple OSS Distributions }
176c1dac77fSApple OSS Distributions 
177*bb611c8fSApple OSS Distributions OSSharedPtr<OSString>
178a5e72196SApple OSS Distributions OSString::withCString(const char *cString)
179c1dac77fSApple OSS Distributions {
180*bb611c8fSApple OSS Distributions 	OSSharedPtr<OSString> me = OSMakeShared<OSString>();
181c1dac77fSApple OSS Distributions 
182c1dac77fSApple OSS Distributions 	if (me && !me->initWithCString(cString)) {
183*bb611c8fSApple OSS Distributions 		return nullptr;
184c1dac77fSApple OSS Distributions 	}
185c1dac77fSApple OSS Distributions 
186c1dac77fSApple OSS Distributions 	return me;
187c1dac77fSApple OSS Distributions }
188c1dac77fSApple OSS Distributions 
189*bb611c8fSApple OSS Distributions OSSharedPtr<OSString>
190a5e72196SApple OSS Distributions OSString::withCStringNoCopy(const char *cString)
191c1dac77fSApple OSS Distributions {
192*bb611c8fSApple OSS Distributions 	OSSharedPtr<OSString> me = OSMakeShared<OSString>();
193c1dac77fSApple OSS Distributions 
194c1dac77fSApple OSS Distributions 	if (me && !me->initWithCStringNoCopy(cString)) {
195*bb611c8fSApple OSS Distributions 		return nullptr;
196c1dac77fSApple OSS Distributions 	}
197c1dac77fSApple OSS Distributions 
198c1dac77fSApple OSS Distributions 	return me;
199c1dac77fSApple OSS Distributions }
200c1dac77fSApple OSS Distributions 
201*bb611c8fSApple OSS Distributions OSSharedPtr<OSString>
202a5e72196SApple OSS Distributions OSString::withStringOfLength(const char *cString, size_t length)
203a3bb9fccSApple OSS Distributions {
204*bb611c8fSApple OSS Distributions 	OSSharedPtr<OSString> me = OSMakeShared<OSString>();
205a3bb9fccSApple OSS Distributions 
206a3bb9fccSApple OSS Distributions 	if (me && !me->initWithStringOfLength(cString, length)) {
207*bb611c8fSApple OSS Distributions 		return nullptr;
208a3bb9fccSApple OSS Distributions 	}
209a3bb9fccSApple OSS Distributions 
210a3bb9fccSApple OSS Distributions 	return me;
211a3bb9fccSApple OSS Distributions }
212a3bb9fccSApple OSS Distributions 
213a3bb9fccSApple OSS Distributions 
214a3bb9fccSApple OSS Distributions 
215c1dac77fSApple OSS Distributions /* @@@ gvdl */
216c1dac77fSApple OSS Distributions #if 0
217a5e72196SApple OSS Distributions OSString *
218a5e72196SApple OSS Distributions OSString::stringWithFormat(const char *format, ...)
219c1dac77fSApple OSS Distributions {
220c1dac77fSApple OSS Distributions #ifndef KERNEL                  // mach3xxx
221c1dac77fSApple OSS Distributions 	OSString *me;
222c1dac77fSApple OSS Distributions 	va_list argList;
223c1dac77fSApple OSS Distributions 
224a5e72196SApple OSS Distributions 	if (!format) {
225c1dac77fSApple OSS Distributions 		return 0;
226a5e72196SApple OSS Distributions 	}
227c1dac77fSApple OSS Distributions 
228c1dac77fSApple OSS Distributions 	va_start(argList, format);
229c1dac77fSApple OSS Distributions 	me = stringWithCapacity(256);
230c1dac77fSApple OSS Distributions 	me->length = vsnprintf(me->string, 256, format, argList);
231c1dac77fSApple OSS Distributions 	me->length++;   // we include the null in the length
232a5e72196SApple OSS Distributions 	if (me->Length > 256) {
233c1dac77fSApple OSS Distributions 		me->Length = 256;
234a5e72196SApple OSS Distributions 	}
235c1dac77fSApple OSS Distributions 	va_end(argList);
236c1dac77fSApple OSS Distributions 
237c1dac77fSApple OSS Distributions 	return me;
238c1dac77fSApple OSS Distributions #else
239c1dac77fSApple OSS Distributions 	return 0;
240c1dac77fSApple OSS Distributions #endif
241c1dac77fSApple OSS Distributions }
242c1dac77fSApple OSS Distributions #endif /* 0 */
243c1dac77fSApple OSS Distributions 
244a5e72196SApple OSS Distributions void
245a5e72196SApple OSS Distributions OSString::free()
246c1dac77fSApple OSS Distributions {
247c1dac77fSApple OSS Distributions 	if (!(flags & kOSStringNoCopy) && string) {
248*bb611c8fSApple OSS Distributions 		kfree_data_container(string, length);
2490f3703acSApple OSS Distributions 		OSCONTAINER_ACCUMSIZE(-((size_t)length));
250c1dac77fSApple OSS Distributions 	}
251c1dac77fSApple OSS Distributions 
252c1dac77fSApple OSS Distributions 	super::free();
253c1dac77fSApple OSS Distributions }
254c1dac77fSApple OSS Distributions 
255a5e72196SApple OSS Distributions unsigned int
256a5e72196SApple OSS Distributions OSString::getLength()  const
257a5e72196SApple OSS Distributions {
258a5e72196SApple OSS Distributions 	return length - 1;
259a5e72196SApple OSS Distributions }
260c1dac77fSApple OSS Distributions 
261a5e72196SApple OSS Distributions const char *
262a5e72196SApple OSS Distributions OSString::getCStringNoCopy() const
263c1dac77fSApple OSS Distributions {
264c1dac77fSApple OSS Distributions 	return string;
265c1dac77fSApple OSS Distributions }
266c1dac77fSApple OSS Distributions 
267a5e72196SApple OSS Distributions bool
268a5e72196SApple OSS Distributions OSString::setChar(char aChar, unsigned int index)
269c1dac77fSApple OSS Distributions {
270c1dac77fSApple OSS Distributions 	if (!(flags & kOSStringNoCopy) && index < length - 1) {
271c1dac77fSApple OSS Distributions 		string[index] = aChar;
272c1dac77fSApple OSS Distributions 
273c1dac77fSApple OSS Distributions 		return true;
274a5e72196SApple OSS Distributions 	} else {
275c1dac77fSApple OSS Distributions 		return false;
276c1dac77fSApple OSS Distributions 	}
277a5e72196SApple OSS Distributions }
278c1dac77fSApple OSS Distributions 
279a5e72196SApple OSS Distributions char
280a5e72196SApple OSS Distributions OSString::getChar(unsigned int index) const
281c1dac77fSApple OSS Distributions {
282a5e72196SApple OSS Distributions 	if (index < length) {
283c1dac77fSApple OSS Distributions 		return string[index];
284a5e72196SApple OSS Distributions 	} else {
285c1dac77fSApple OSS Distributions 		return '\0';
286c1dac77fSApple OSS Distributions 	}
287c1dac77fSApple OSS Distributions }
288c1dac77fSApple OSS Distributions 
289a5e72196SApple OSS Distributions 
290a5e72196SApple OSS Distributions bool
291a5e72196SApple OSS Distributions OSString::isEqualTo(const OSString *aString) const
292a5e72196SApple OSS Distributions {
293a5e72196SApple OSS Distributions 	if (length != aString->length) {
294a5e72196SApple OSS Distributions 		return false;
295a5e72196SApple OSS Distributions 	} else {
296a5e72196SApple OSS Distributions 		return isEqualTo((const char *) aString->string);
297a5e72196SApple OSS Distributions 	}
298a5e72196SApple OSS Distributions }
299a5e72196SApple OSS Distributions 
300a5e72196SApple OSS Distributions bool
301a5e72196SApple OSS Distributions OSString::isEqualTo(const char *aCString) const
302c1dac77fSApple OSS Distributions {
3033ca3bd55SApple OSS Distributions 	return strncmp(string, aCString, length) == 0;
304c1dac77fSApple OSS Distributions }
305c1dac77fSApple OSS Distributions 
306a5e72196SApple OSS Distributions bool
307a5e72196SApple OSS Distributions OSString::isEqualTo(const OSMetaClassBase *obj) const
308c1dac77fSApple OSS Distributions {
309c1dac77fSApple OSS Distributions 	OSString *  str;
310c1dac77fSApple OSS Distributions 	OSData *    data;
311c1dac77fSApple OSS Distributions 
312a5e72196SApple OSS Distributions 	if ((str = OSDynamicCast(OSString, obj))) {
313c1dac77fSApple OSS Distributions 		return isEqualTo(str);
314a5e72196SApple OSS Distributions 	} else if ((data = OSDynamicCast(OSData, obj))) {
315c1dac77fSApple OSS Distributions 		return isEqualTo(data);
316a5e72196SApple OSS Distributions 	} else {
317c1dac77fSApple OSS Distributions 		return false;
318c1dac77fSApple OSS Distributions 	}
319a5e72196SApple OSS Distributions }
320c1dac77fSApple OSS Distributions 
321a5e72196SApple OSS Distributions bool
322a5e72196SApple OSS Distributions OSString::isEqualTo(const OSData *obj) const
323c1dac77fSApple OSS Distributions {
324a5e72196SApple OSS Distributions 	if (NULL == obj) {
325c1dac77fSApple OSS Distributions 		return false;
326a5e72196SApple OSS Distributions 	}
327c1dac77fSApple OSS Distributions 
328c1dac77fSApple OSS Distributions 	unsigned int dataLen = obj->getLength();;
329cc9a6355SApple OSS Distributions 	const char * dataPtr = (const char *) obj->getBytesNoCopy();
330c1dac77fSApple OSS Distributions 
331c1dac77fSApple OSS Distributions 	if (dataLen != length) {
332c1dac77fSApple OSS Distributions 		// check for the fact that OSData may be a buffer that
333c1dac77fSApple OSS Distributions 		// that includes a termination byte and will thus have
334c1dac77fSApple OSS Distributions 		// a length of the actual string length PLUS 1. In this
335c1dac77fSApple OSS Distributions 		// case we verify that the additional byte is a terminator
336c1dac77fSApple OSS Distributions 		// and if so count the two lengths as being the same.
337c1dac77fSApple OSS Distributions 
338c1dac77fSApple OSS Distributions 		if ((dataLen - length) == 1) {
339a5e72196SApple OSS Distributions 			if (dataPtr[dataLen - 1] != 0) {
340c1dac77fSApple OSS Distributions 				return false;
341c1dac77fSApple OSS Distributions 			}
342a5e72196SApple OSS Distributions 			dataLen--;
343a5e72196SApple OSS Distributions 		} else {
344c1dac77fSApple OSS Distributions 			return false;
345c1dac77fSApple OSS Distributions 		}
346a5e72196SApple OSS Distributions 	}
347c1dac77fSApple OSS Distributions 
348c1dac77fSApple OSS Distributions 	for (unsigned int i = 0; i < dataLen; i++) {
349a5e72196SApple OSS Distributions 		if (*dataPtr++ != string[i]) {
350c1dac77fSApple OSS Distributions 			return false;
351c1dac77fSApple OSS Distributions 		}
352a5e72196SApple OSS Distributions 	}
353c1dac77fSApple OSS Distributions 
354c1dac77fSApple OSS Distributions 	return true;
355c1dac77fSApple OSS Distributions }
356c1dac77fSApple OSS Distributions 
357a5e72196SApple OSS Distributions bool
358a5e72196SApple OSS Distributions OSString::serialize(OSSerialize *s) const
359c1dac77fSApple OSS Distributions {
360c1dac77fSApple OSS Distributions 	char *c = string;
361c1dac77fSApple OSS Distributions 
362a5e72196SApple OSS Distributions 	if (s->previouslySerialized(this)) {
363a5e72196SApple OSS Distributions 		return true;
364a5e72196SApple OSS Distributions 	}
365c1dac77fSApple OSS Distributions 
366a5e72196SApple OSS Distributions 	if (!s->addXMLStartTag(this, "string")) {
367a5e72196SApple OSS Distributions 		return false;
368a5e72196SApple OSS Distributions 	}
369c1dac77fSApple OSS Distributions 	while (*c) {
370c1dac77fSApple OSS Distributions 		if (*c == '<') {
371a5e72196SApple OSS Distributions 			if (!s->addString("&lt;")) {
372a5e72196SApple OSS Distributions 				return false;
373a5e72196SApple OSS Distributions 			}
374c1dac77fSApple OSS Distributions 		} else if (*c == '>') {
375a5e72196SApple OSS Distributions 			if (!s->addString("&gt;")) {
376a5e72196SApple OSS Distributions 				return false;
377a5e72196SApple OSS Distributions 			}
378c1dac77fSApple OSS Distributions 		} else if (*c == '&') {
379a5e72196SApple OSS Distributions 			if (!s->addString("&amp;")) {
380a5e72196SApple OSS Distributions 				return false;
381a5e72196SApple OSS Distributions 			}
382c1dac77fSApple OSS Distributions 		} else {
383a5e72196SApple OSS Distributions 			if (!s->addChar(*c)) {
384a5e72196SApple OSS Distributions 				return false;
385a5e72196SApple OSS Distributions 			}
386c1dac77fSApple OSS Distributions 		}
387c1dac77fSApple OSS Distributions 		c++;
388c1dac77fSApple OSS Distributions 	}
389c1dac77fSApple OSS Distributions 
390c1dac77fSApple OSS Distributions 	return s->addXMLEndTag("string");
391c1dac77fSApple OSS Distributions }
392