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