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("<")) { 372a5e72196SApple OSS Distributions return false; 373a5e72196SApple OSS Distributions } 374c1dac77fSApple OSS Distributions } else if (*c == '>') { 375a5e72196SApple OSS Distributions if (!s->addString(">")) { 376a5e72196SApple OSS Distributions return false; 377a5e72196SApple OSS Distributions } 378c1dac77fSApple OSS Distributions } else if (*c == '&') { 379a5e72196SApple OSS Distributions if (!s->addString("&")) { 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