1 /* 2 * Copyright (c) 2000 Apple Computer, 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 #if OSALLOCDEBUG 60 extern "C" { 61 extern int debug_container_malloc_size; 62 }; 63 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) 64 #else 65 #define ACCUMSIZE(s) 66 #endif 67 68 bool OSString::initWithString(const OSString *aString) 69 { 70 return initWithCString(aString->string); 71 } 72 73 bool OSString::initWithCString(const char *cString) 74 { 75 if (!cString || !super::init()) 76 return false; 77 78 length = strlen(cString) + 1; 79 string = (char *) kalloc(length); 80 if (!string) 81 return false; 82 83 bcopy(cString, string, length); 84 85 ACCUMSIZE(length); 86 87 return true; 88 } 89 90 bool OSString::initWithStringOfLength(const char *cString, size_t inlength) 91 { 92 if (!cString || !super::init()) 93 return false; 94 95 length = inlength + 1; 96 string = (char *) kalloc(length); 97 if (!string) 98 return false; 99 100 bcopy(cString, string, inlength); 101 string[inlength] = 0; 102 103 ACCUMSIZE(length); 104 105 return true; 106 } 107 108 bool OSString::initWithCStringNoCopy(const char *cString) 109 { 110 if (!cString || !super::init()) 111 return false; 112 113 length = strlen(cString) + 1; 114 flags |= kOSStringNoCopy; 115 string = const_cast<char *>(cString); 116 117 return true; 118 } 119 120 OSString *OSString::withString(const OSString *aString) 121 { 122 OSString *me = new OSString; 123 124 if (me && !me->initWithString(aString)) { 125 me->release(); 126 return 0; 127 } 128 129 return me; 130 } 131 132 OSString *OSString::withCString(const char *cString) 133 { 134 OSString *me = new OSString; 135 136 if (me && !me->initWithCString(cString)) { 137 me->release(); 138 return 0; 139 } 140 141 return me; 142 } 143 144 OSString *OSString::withCStringNoCopy(const char *cString) 145 { 146 OSString *me = new OSString; 147 148 if (me && !me->initWithCStringNoCopy(cString)) { 149 me->release(); 150 return 0; 151 } 152 153 return me; 154 } 155 156 OSString *OSString::withStringOfLength(const char *cString, size_t length) 157 { 158 OSString *me = new OSString; 159 160 if (me && !me->initWithStringOfLength(cString, length)) { 161 me->release(); 162 return 0; 163 } 164 165 return me; 166 } 167 168 169 170 /* @@@ gvdl */ 171 #if 0 172 OSString *OSString::stringWithFormat(const char *format, ...) 173 { 174 #ifndef KERNEL // mach3xxx 175 OSString *me; 176 va_list argList; 177 178 if (!format) 179 return 0; 180 181 va_start(argList, format); 182 me = stringWithCapacity(256); 183 me->length = vsnprintf(me->string, 256, format, argList); 184 me->length++; // we include the null in the length 185 if (me->Length > 256) 186 me->Length = 256; 187 va_end (argList); 188 189 return me; 190 #else 191 return 0; 192 #endif 193 } 194 #endif /* 0 */ 195 196 void OSString::free() 197 { 198 if ( !(flags & kOSStringNoCopy) && string) { 199 kfree(string, (vm_size_t)length); 200 ACCUMSIZE(-length); 201 } 202 203 super::free(); 204 } 205 206 unsigned int OSString::getLength() const { return length - 1; } 207 208 const char *OSString::getCStringNoCopy() const 209 { 210 return string; 211 } 212 213 bool OSString::setChar(char aChar, unsigned int index) 214 { 215 if ( !(flags & kOSStringNoCopy) && index < length - 1) { 216 string[index] = aChar; 217 218 return true; 219 } 220 else 221 return false; 222 } 223 224 char OSString::getChar(unsigned int index) const 225 { 226 if (index < length) 227 return string[index]; 228 else 229 return '\0'; 230 } 231 232 233 bool OSString::isEqualTo(const OSString *aString) const 234 { 235 if (length != aString->length) 236 return false; 237 else 238 return isEqualTo((const char *) aString->string); 239 } 240 241 bool OSString::isEqualTo(const char *aCString) const 242 { 243 return strncmp(string, aCString, length) == 0; 244 } 245 246 bool OSString::isEqualTo(const OSMetaClassBase *obj) const 247 { 248 OSString * str; 249 OSData * data; 250 251 if ((str = OSDynamicCast(OSString, obj))) 252 return isEqualTo(str); 253 else if ((data = OSDynamicCast (OSData, obj))) 254 return isEqualTo(data); 255 else 256 return false; 257 } 258 259 bool OSString::isEqualTo(const OSData *obj) const 260 { 261 if (NULL == obj) 262 return false; 263 264 unsigned int dataLen = obj->getLength ();; 265 char * dataPtr = (char *) obj->getBytesNoCopy (); 266 267 if (dataLen != length) { 268 269 // check for the fact that OSData may be a buffer that 270 // that includes a termination byte and will thus have 271 // a length of the actual string length PLUS 1. In this 272 // case we verify that the additional byte is a terminator 273 // and if so count the two lengths as being the same. 274 275 if ( (dataLen - length) == 1 ) { 276 if (dataPtr[dataLen-1] != 0) 277 return false; 278 dataLen--; 279 } 280 else 281 return false; 282 } 283 284 for ( unsigned int i=0; i < dataLen; i++ ) { 285 if ( *dataPtr++ != string[i] ) 286 return false; 287 } 288 289 return true; 290 } 291 292 bool OSString::serialize(OSSerialize *s) const 293 { 294 char *c = string; 295 296 if (s->previouslySerialized(this)) return true; 297 298 if (!s->addXMLStartTag(this, "string")) return false; 299 while (*c) { 300 if (*c == '<') { 301 if (!s->addString("<")) return false; 302 } else if (*c == '>') { 303 if (!s->addString(">")) return false; 304 } else if (*c == '&') { 305 if (!s->addString("&")) return false; 306 } else { 307 if (!s->addChar(*c)) return false; 308 } 309 c++; 310 } 311 312 return s->addXMLEndTag("string"); 313 } 314