1 /* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. 7 * 8 * This file contains Original Code and/or Modifications of Original Code 9 * as defined in and that are subject to the Apple Public Source License 10 * Version 2.0 (the 'License'). You may not use this file except in 11 * compliance with the License. Please obtain a copy of the License at 12 * http://www.opensource.apple.com/apsl/ and read it before using this 13 * file. 14 * 15 * The Original Code and all software distributed under the License are 16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 20 * Please see the License for the specific language governing rights and 21 * limitations under the License. 22 * 23 * @APPLE_LICENSE_HEADER_END@ 24 */ 25 /* IOString.m created by rsulack on Wed 17-Sep-1997 */ 26 /* IOString.cpp converted to C++ on Tue 1998-9-22 */ 27 28 #include <string.h> 29 30 #include <libkern/c++/OSString.h> 31 #include <libkern/c++/OSSerialize.h> 32 #include <libkern/c++/OSLib.h> 33 #include <libkern/c++/OSData.h> 34 #include <string.h> 35 36 #define super OSObject 37 38 OSDefineMetaClassAndStructors(OSString, OSObject) 39 OSMetaClassDefineReservedUnused(OSString, 0); 40 OSMetaClassDefineReservedUnused(OSString, 1); 41 OSMetaClassDefineReservedUnused(OSString, 2); 42 OSMetaClassDefineReservedUnused(OSString, 3); 43 OSMetaClassDefineReservedUnused(OSString, 4); 44 OSMetaClassDefineReservedUnused(OSString, 5); 45 OSMetaClassDefineReservedUnused(OSString, 6); 46 OSMetaClassDefineReservedUnused(OSString, 7); 47 OSMetaClassDefineReservedUnused(OSString, 8); 48 OSMetaClassDefineReservedUnused(OSString, 9); 49 OSMetaClassDefineReservedUnused(OSString, 10); 50 OSMetaClassDefineReservedUnused(OSString, 11); 51 OSMetaClassDefineReservedUnused(OSString, 12); 52 OSMetaClassDefineReservedUnused(OSString, 13); 53 OSMetaClassDefineReservedUnused(OSString, 14); 54 OSMetaClassDefineReservedUnused(OSString, 15); 55 56 #if OSALLOCDEBUG 57 extern "C" { 58 extern int debug_container_malloc_size; 59 }; 60 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) 61 #else 62 #define ACCUMSIZE(s) 63 #endif 64 65 bool OSString::initWithString(const OSString *aString) 66 { 67 return initWithCString(aString->string); 68 } 69 70 bool OSString::initWithCString(const char *cString) 71 { 72 if (!cString || !super::init()) 73 return false; 74 75 length = strlen(cString) + 1; 76 string = (char *) kalloc(length); 77 if (!string) 78 return false; 79 80 bcopy(cString, string, length); 81 82 ACCUMSIZE(length); 83 84 return true; 85 } 86 87 bool OSString::initWithCStringNoCopy(const char *cString) 88 { 89 if (!cString || !super::init()) 90 return false; 91 92 length = strlen(cString) + 1; 93 flags |= kOSStringNoCopy; 94 string = (char *) cString; 95 96 return true; 97 } 98 99 OSString *OSString::withString(const OSString *aString) 100 { 101 OSString *me = new OSString; 102 103 if (me && !me->initWithString(aString)) { 104 me->release(); 105 return 0; 106 } 107 108 return me; 109 } 110 111 OSString *OSString::withCString(const char *cString) 112 { 113 OSString *me = new OSString; 114 115 if (me && !me->initWithCString(cString)) { 116 me->release(); 117 return 0; 118 } 119 120 return me; 121 } 122 123 OSString *OSString::withCStringNoCopy(const char *cString) 124 { 125 OSString *me = new OSString; 126 127 if (me && !me->initWithCStringNoCopy(cString)) { 128 me->release(); 129 return 0; 130 } 131 132 return me; 133 } 134 135 /* @@@ gvdl */ 136 #if 0 137 OSString *OSString::stringWithFormat(const char *format, ...) 138 { 139 #ifndef KERNEL // mach3xxx 140 OSString *me; 141 va_list argList; 142 143 if (!format) 144 return 0; 145 146 va_start(argList, format); 147 me = stringWithCapacity(256); 148 me->length = vsnprintf(me->string, 256, format, argList); 149 me->length++; // we include the null in the length 150 if (me->Length > 256) 151 me->Length = 256; 152 va_end (argList); 153 154 return me; 155 #else 156 return 0; 157 #endif 158 } 159 #endif /* 0 */ 160 161 void OSString::free() 162 { 163 if ( !(flags & kOSStringNoCopy) && string) { 164 kfree((vm_offset_t)string, (vm_size_t)length); 165 ACCUMSIZE(-length); 166 } 167 168 super::free(); 169 } 170 171 unsigned int OSString::getLength() const { return length - 1; } 172 173 const char *OSString::getCStringNoCopy() const 174 { 175 return string; 176 } 177 178 bool OSString::setChar(char aChar, unsigned int index) 179 { 180 if ( !(flags & kOSStringNoCopy) && index < length - 1) { 181 string[index] = aChar; 182 183 return true; 184 } 185 else 186 return false; 187 } 188 189 char OSString::getChar(unsigned int index) const 190 { 191 if (index < length) 192 return string[index]; 193 else 194 return '\0'; 195 } 196 197 198 bool OSString::isEqualTo(const OSString *aString) const 199 { 200 if (length != aString->length) 201 return false; 202 else 203 return isEqualTo((const char *) aString->string); 204 } 205 206 bool OSString::isEqualTo(const char *aCString) const 207 { 208 return strcmp(string, aCString) == 0; 209 } 210 211 bool OSString::isEqualTo(const OSMetaClassBase *obj) const 212 { 213 OSString * str; 214 OSData * data; 215 216 if ((str = OSDynamicCast(OSString, obj))) 217 return isEqualTo(str); 218 else if ((data = OSDynamicCast (OSData, obj))) 219 return isEqualTo(data); 220 else 221 return false; 222 } 223 224 bool OSString::isEqualTo(const OSData *obj) const 225 { 226 if (NULL == obj) 227 return false; 228 229 unsigned int dataLen = obj->getLength ();; 230 char * dataPtr = (char *) obj->getBytesNoCopy (); 231 232 if (dataLen != length) { 233 234 // check for the fact that OSData may be a buffer that 235 // that includes a termination byte and will thus have 236 // a length of the actual string length PLUS 1. In this 237 // case we verify that the additional byte is a terminator 238 // and if so count the two lengths as being the same. 239 240 if ( (dataLen - length) == 1 ) { 241 if (dataPtr[dataLen-1] != 0) 242 return false; 243 dataLen--; 244 } 245 else 246 return false; 247 } 248 249 for ( unsigned int i=0; i < dataLen; i++ ) { 250 if ( *dataPtr++ != string[i] ) 251 return false; 252 } 253 254 return true; 255 } 256 257 bool OSString::serialize(OSSerialize *s) const 258 { 259 char *c = string; 260 261 if (s->previouslySerialized(this)) return true; 262 263 if (!s->addXMLStartTag(this, "string")) return false; 264 while (*c) { 265 if (*c == '<') { 266 if (!s->addString("<")) return false; 267 } else if (*c == '>') { 268 if (!s->addString(">")) return false; 269 } else if (*c == '&') { 270 if (!s->addString("&")) return false; 271 } else { 272 if (!s->addChar(*c)) return false; 273 } 274 c++; 275 } 276 277 return s->addXMLEndTag("string"); 278 } 279