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