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