1c1dac77fSApple OSS Distributions /* 2*a5e72196SApple 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 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 59*a5e72196SApple OSS Distributions bool 60*a5e72196SApple OSS Distributions OSString::initWithString(const OSString *aString) 61c1dac77fSApple OSS Distributions { 62c1dac77fSApple OSS Distributions return initWithCString(aString->string); 63c1dac77fSApple OSS Distributions } 64c1dac77fSApple OSS Distributions 65*a5e72196SApple OSS Distributions bool 66*a5e72196SApple OSS Distributions OSString::initWithCString(const char *cString) 67c1dac77fSApple OSS Distributions { 680f3703acSApple OSS Distributions unsigned int newLength; 690f3703acSApple OSS Distributions char * newString; 70c1dac77fSApple OSS Distributions 71*a5e72196SApple OSS Distributions if (!cString || !super::init()) { 72*a5e72196SApple OSS Distributions return false; 73*a5e72196SApple OSS Distributions } 74c1dac77fSApple OSS Distributions 7588cc0b97SApple OSS Distributions newLength = strnlen(cString, kMaxStringLength); 76*a5e72196SApple OSS Distributions if (newLength >= kMaxStringLength) { 77*a5e72196SApple OSS Distributions return false; 78*a5e72196SApple OSS Distributions } 7988cc0b97SApple OSS Distributions 8088cc0b97SApple OSS Distributions newLength++; 810f3703acSApple OSS Distributions newString = (char *) kalloc_container(newLength); 82*a5e72196SApple OSS Distributions if (!newString) { 83*a5e72196SApple OSS Distributions return false; 84*a5e72196SApple OSS Distributions } 85c1dac77fSApple OSS Distributions 860f3703acSApple OSS Distributions bcopy(cString, newString, newLength); 870f3703acSApple OSS Distributions 880f3703acSApple OSS Distributions if (!(flags & kOSStringNoCopy) && string) { 890f3703acSApple OSS Distributions kfree(string, (vm_size_t)length); 900f3703acSApple OSS Distributions OSCONTAINER_ACCUMSIZE(-((size_t)length)); 910f3703acSApple OSS Distributions } 920f3703acSApple OSS Distributions string = newString; 930f3703acSApple OSS Distributions length = newLength; 940f3703acSApple OSS Distributions flags &= ~kOSStringNoCopy; 950f3703acSApple OSS Distributions 960f3703acSApple OSS Distributions OSCONTAINER_ACCUMSIZE(length); 97c1dac77fSApple OSS Distributions 98c1dac77fSApple OSS Distributions return true; 99c1dac77fSApple OSS Distributions } 100c1dac77fSApple OSS Distributions 101*a5e72196SApple OSS Distributions bool 102*a5e72196SApple OSS Distributions OSString::initWithStringOfLength(const char *cString, size_t inlength) 103a3bb9fccSApple OSS Distributions { 1040f3703acSApple OSS Distributions unsigned int newLength; 1050f3703acSApple OSS Distributions char * newString; 106a3bb9fccSApple OSS Distributions 107*a5e72196SApple OSS Distributions if (!cString || !super::init()) { 108*a5e72196SApple OSS Distributions return false; 109*a5e72196SApple OSS Distributions } 110a3bb9fccSApple OSS Distributions 111*a5e72196SApple OSS Distributions if (inlength >= kMaxStringLength) { 112*a5e72196SApple OSS Distributions return false; 113*a5e72196SApple OSS Distributions } 114*a5e72196SApple OSS Distributions 115*a5e72196SApple OSS Distributions if (strnlen(cString, inlength) < inlength) { 116*a5e72196SApple OSS Distributions return false; 117*a5e72196SApple OSS Distributions } 11888cc0b97SApple OSS Distributions 1190f3703acSApple OSS Distributions newLength = inlength + 1; 1200f3703acSApple OSS Distributions newString = (char *) kalloc_container(newLength); 121*a5e72196SApple OSS Distributions if (!newString) { 122*a5e72196SApple OSS Distributions return false; 123*a5e72196SApple OSS Distributions } 124a3bb9fccSApple OSS Distributions 1250f3703acSApple OSS Distributions bcopy(cString, newString, inlength); 1260f3703acSApple OSS Distributions newString[inlength] = 0; 1270f3703acSApple OSS Distributions 1280f3703acSApple OSS Distributions if (!(flags & kOSStringNoCopy) && string) { 1290f3703acSApple OSS Distributions kfree(string, (vm_size_t)length); 1300f3703acSApple OSS Distributions OSCONTAINER_ACCUMSIZE(-((size_t)length)); 1310f3703acSApple OSS Distributions } 1320f3703acSApple OSS Distributions 1330f3703acSApple OSS Distributions string = newString; 1340f3703acSApple OSS Distributions length = newLength; 1350f3703acSApple OSS Distributions flags &= ~kOSStringNoCopy; 1360f3703acSApple OSS Distributions 1370f3703acSApple OSS Distributions OSCONTAINER_ACCUMSIZE(length); 138a3bb9fccSApple OSS Distributions 139a3bb9fccSApple OSS Distributions return true; 140a3bb9fccSApple OSS Distributions } 141a3bb9fccSApple OSS Distributions 142*a5e72196SApple OSS Distributions bool 143*a5e72196SApple OSS Distributions OSString::initWithCStringNoCopy(const char *cString) 144c1dac77fSApple OSS Distributions { 145*a5e72196SApple OSS Distributions if (!cString || !super::init()) { 146c1dac77fSApple OSS Distributions return false; 147*a5e72196SApple OSS Distributions } 148c1dac77fSApple OSS Distributions 14988cc0b97SApple OSS Distributions length = strnlen(cString, kMaxStringLength); 150*a5e72196SApple OSS Distributions if (length >= kMaxStringLength) { 151*a5e72196SApple OSS Distributions return false; 152*a5e72196SApple OSS Distributions } 15388cc0b97SApple OSS Distributions 15488cc0b97SApple OSS Distributions length++; 155c1dac77fSApple OSS Distributions flags |= kOSStringNoCopy; 1563ca3bd55SApple OSS Distributions string = const_cast<char *>(cString); 157c1dac77fSApple OSS Distributions 158c1dac77fSApple OSS Distributions return true; 159c1dac77fSApple OSS Distributions } 160c1dac77fSApple OSS Distributions 161*a5e72196SApple OSS Distributions OSString * 162*a5e72196SApple OSS Distributions OSString::withString(const OSString *aString) 163c1dac77fSApple OSS Distributions { 164c1dac77fSApple OSS Distributions OSString *me = new OSString; 165c1dac77fSApple OSS Distributions 166c1dac77fSApple OSS Distributions if (me && !me->initWithString(aString)) { 167368ad365SApple OSS Distributions me->release(); 168*a5e72196SApple OSS Distributions return NULL; 169c1dac77fSApple OSS Distributions } 170c1dac77fSApple OSS Distributions 171c1dac77fSApple OSS Distributions return me; 172c1dac77fSApple OSS Distributions } 173c1dac77fSApple OSS Distributions 174*a5e72196SApple OSS Distributions OSString * 175*a5e72196SApple OSS Distributions OSString::withCString(const char *cString) 176c1dac77fSApple OSS Distributions { 177c1dac77fSApple OSS Distributions OSString *me = new OSString; 178c1dac77fSApple OSS Distributions 179c1dac77fSApple OSS Distributions if (me && !me->initWithCString(cString)) { 180368ad365SApple OSS Distributions me->release(); 181*a5e72196SApple OSS Distributions return NULL; 182c1dac77fSApple OSS Distributions } 183c1dac77fSApple OSS Distributions 184c1dac77fSApple OSS Distributions return me; 185c1dac77fSApple OSS Distributions } 186c1dac77fSApple OSS Distributions 187*a5e72196SApple OSS Distributions OSString * 188*a5e72196SApple OSS Distributions OSString::withCStringNoCopy(const char *cString) 189c1dac77fSApple OSS Distributions { 190c1dac77fSApple OSS Distributions OSString *me = new OSString; 191c1dac77fSApple OSS Distributions 192c1dac77fSApple OSS Distributions if (me && !me->initWithCStringNoCopy(cString)) { 193368ad365SApple OSS Distributions me->release(); 194*a5e72196SApple OSS Distributions return NULL; 195c1dac77fSApple OSS Distributions } 196c1dac77fSApple OSS Distributions 197c1dac77fSApple OSS Distributions return me; 198c1dac77fSApple OSS Distributions } 199c1dac77fSApple OSS Distributions 200*a5e72196SApple OSS Distributions OSString * 201*a5e72196SApple OSS Distributions OSString::withStringOfLength(const char *cString, size_t length) 202a3bb9fccSApple OSS Distributions { 203a3bb9fccSApple OSS Distributions OSString *me = new OSString; 204a3bb9fccSApple OSS Distributions 205a3bb9fccSApple OSS Distributions if (me && !me->initWithStringOfLength(cString, length)) { 206a3bb9fccSApple OSS Distributions me->release(); 207*a5e72196SApple OSS Distributions return NULL; 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 217*a5e72196SApple OSS Distributions OSString * 218*a5e72196SApple 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 224*a5e72196SApple OSS Distributions if (!format) { 225c1dac77fSApple OSS Distributions return 0; 226*a5e72196SApple 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 232*a5e72196SApple OSS Distributions if (me->Length > 256) { 233c1dac77fSApple OSS Distributions me->Length = 256; 234*a5e72196SApple 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 244*a5e72196SApple OSS Distributions void 245*a5e72196SApple OSS Distributions OSString::free() 246c1dac77fSApple OSS Distributions { 247c1dac77fSApple OSS Distributions if (!(flags & kOSStringNoCopy) && string) { 248e13b1fa5SApple OSS Distributions kfree(string, (vm_size_t)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 255*a5e72196SApple OSS Distributions unsigned int 256*a5e72196SApple OSS Distributions OSString::getLength() const 257*a5e72196SApple OSS Distributions { 258*a5e72196SApple OSS Distributions return length - 1; 259*a5e72196SApple OSS Distributions } 260c1dac77fSApple OSS Distributions 261*a5e72196SApple OSS Distributions const char * 262*a5e72196SApple OSS Distributions OSString::getCStringNoCopy() const 263c1dac77fSApple OSS Distributions { 264c1dac77fSApple OSS Distributions return string; 265c1dac77fSApple OSS Distributions } 266c1dac77fSApple OSS Distributions 267*a5e72196SApple OSS Distributions bool 268*a5e72196SApple 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; 274*a5e72196SApple OSS Distributions } else { 275c1dac77fSApple OSS Distributions return false; 276c1dac77fSApple OSS Distributions } 277*a5e72196SApple OSS Distributions } 278c1dac77fSApple OSS Distributions 279*a5e72196SApple OSS Distributions char 280*a5e72196SApple OSS Distributions OSString::getChar(unsigned int index) const 281c1dac77fSApple OSS Distributions { 282*a5e72196SApple OSS Distributions if (index < length) { 283c1dac77fSApple OSS Distributions return string[index]; 284*a5e72196SApple OSS Distributions } else { 285c1dac77fSApple OSS Distributions return '\0'; 286c1dac77fSApple OSS Distributions } 287c1dac77fSApple OSS Distributions } 288c1dac77fSApple OSS Distributions 289*a5e72196SApple OSS Distributions 290*a5e72196SApple OSS Distributions bool 291*a5e72196SApple OSS Distributions OSString::isEqualTo(const OSString *aString) const 292*a5e72196SApple OSS Distributions { 293*a5e72196SApple OSS Distributions if (length != aString->length) { 294*a5e72196SApple OSS Distributions return false; 295*a5e72196SApple OSS Distributions } else { 296*a5e72196SApple OSS Distributions return isEqualTo((const char *) aString->string); 297*a5e72196SApple OSS Distributions } 298*a5e72196SApple OSS Distributions } 299*a5e72196SApple OSS Distributions 300*a5e72196SApple OSS Distributions bool 301*a5e72196SApple 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 306*a5e72196SApple OSS Distributions bool 307*a5e72196SApple OSS Distributions OSString::isEqualTo(const OSMetaClassBase *obj) const 308c1dac77fSApple OSS Distributions { 309c1dac77fSApple OSS Distributions OSString * str; 310c1dac77fSApple OSS Distributions OSData * data; 311c1dac77fSApple OSS Distributions 312*a5e72196SApple OSS Distributions if ((str = OSDynamicCast(OSString, obj))) { 313c1dac77fSApple OSS Distributions return isEqualTo(str); 314*a5e72196SApple OSS Distributions } else if ((data = OSDynamicCast(OSData, obj))) { 315c1dac77fSApple OSS Distributions return isEqualTo(data); 316*a5e72196SApple OSS Distributions } else { 317c1dac77fSApple OSS Distributions return false; 318c1dac77fSApple OSS Distributions } 319*a5e72196SApple OSS Distributions } 320c1dac77fSApple OSS Distributions 321*a5e72196SApple OSS Distributions bool 322*a5e72196SApple OSS Distributions OSString::isEqualTo(const OSData *obj) const 323c1dac77fSApple OSS Distributions { 324*a5e72196SApple OSS Distributions if (NULL == obj) { 325c1dac77fSApple OSS Distributions return false; 326*a5e72196SApple 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) { 339*a5e72196SApple OSS Distributions if (dataPtr[dataLen - 1] != 0) { 340c1dac77fSApple OSS Distributions return false; 341c1dac77fSApple OSS Distributions } 342*a5e72196SApple OSS Distributions dataLen--; 343*a5e72196SApple OSS Distributions } else { 344c1dac77fSApple OSS Distributions return false; 345c1dac77fSApple OSS Distributions } 346*a5e72196SApple OSS Distributions } 347c1dac77fSApple OSS Distributions 348c1dac77fSApple OSS Distributions for (unsigned int i = 0; i < dataLen; i++) { 349*a5e72196SApple OSS Distributions if (*dataPtr++ != string[i]) { 350c1dac77fSApple OSS Distributions return false; 351c1dac77fSApple OSS Distributions } 352*a5e72196SApple OSS Distributions } 353c1dac77fSApple OSS Distributions 354c1dac77fSApple OSS Distributions return true; 355c1dac77fSApple OSS Distributions } 356c1dac77fSApple OSS Distributions 357*a5e72196SApple OSS Distributions bool 358*a5e72196SApple OSS Distributions OSString::serialize(OSSerialize *s) const 359c1dac77fSApple OSS Distributions { 360c1dac77fSApple OSS Distributions char *c = string; 361c1dac77fSApple OSS Distributions 362*a5e72196SApple OSS Distributions if (s->previouslySerialized(this)) { 363*a5e72196SApple OSS Distributions return true; 364*a5e72196SApple OSS Distributions } 365c1dac77fSApple OSS Distributions 366*a5e72196SApple OSS Distributions if (!s->addXMLStartTag(this, "string")) { 367*a5e72196SApple OSS Distributions return false; 368*a5e72196SApple OSS Distributions } 369c1dac77fSApple OSS Distributions while (*c) { 370c1dac77fSApple OSS Distributions if (*c == '<') { 371*a5e72196SApple OSS Distributions if (!s->addString("<")) { 372*a5e72196SApple OSS Distributions return false; 373*a5e72196SApple OSS Distributions } 374c1dac77fSApple OSS Distributions } else if (*c == '>') { 375*a5e72196SApple OSS Distributions if (!s->addString(">")) { 376*a5e72196SApple OSS Distributions return false; 377*a5e72196SApple OSS Distributions } 378c1dac77fSApple OSS Distributions } else if (*c == '&') { 379*a5e72196SApple OSS Distributions if (!s->addString("&")) { 380*a5e72196SApple OSS Distributions return false; 381*a5e72196SApple OSS Distributions } 382c1dac77fSApple OSS Distributions } else { 383*a5e72196SApple OSS Distributions if (!s->addChar(*c)) { 384*a5e72196SApple OSS Distributions return false; 385*a5e72196SApple 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