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 26 #include <libkern/c++/OSString.h> 27 #include <libkern/c++/OSSerialize.h> 28 #include <libkern/c++/OSLib.h> 29 #include <libkern/c++/OSData.h> 30 31 #define super OSObject 32 33 OSDefineMetaClassAndStructors(OSString, OSObject) 34 OSMetaClassDefineReservedUnused(OSString, 0); 35 OSMetaClassDefineReservedUnused(OSString, 1); 36 OSMetaClassDefineReservedUnused(OSString, 2); 37 OSMetaClassDefineReservedUnused(OSString, 3); 38 OSMetaClassDefineReservedUnused(OSString, 4); 39 OSMetaClassDefineReservedUnused(OSString, 5); 40 OSMetaClassDefineReservedUnused(OSString, 6); 41 OSMetaClassDefineReservedUnused(OSString, 7); 42 OSMetaClassDefineReservedUnused(OSString, 8); 43 OSMetaClassDefineReservedUnused(OSString, 9); 44 OSMetaClassDefineReservedUnused(OSString, 10); 45 OSMetaClassDefineReservedUnused(OSString, 11); 46 OSMetaClassDefineReservedUnused(OSString, 12); 47 OSMetaClassDefineReservedUnused(OSString, 13); 48 OSMetaClassDefineReservedUnused(OSString, 14); 49 OSMetaClassDefineReservedUnused(OSString, 15); 50 51 #if OSALLOCDEBUG 52 extern "C" { 53 extern int debug_container_malloc_size; 54 }; 55 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) 56 #else 57 #define ACCUMSIZE(s) 58 #endif 59 60 bool OSString::initWithString(const OSString *aString) 61 { 62 return initWithCString(aString->string); 63 } 64 65 bool OSString::initWithCString(const char *cString) 66 { 67 if (!cString || !super::init()) 68 return false; 69 70 length = strlen(cString) + 1; 71 string = (char *) kalloc(length); 72 if (!string) 73 return false; 74 75 bcopy(cString, string, length); 76 77 ACCUMSIZE(length); 78 79 return true; 80 } 81 82 bool OSString::initWithCStringNoCopy(const char *cString) 83 { 84 if (!cString || !super::init()) 85 return false; 86 87 length = strlen(cString) + 1; 88 flags |= kOSStringNoCopy; 89 string = (char *) cString; 90 91 return true; 92 } 93 94 OSString *OSString::withString(const OSString *aString) 95 { 96 OSString *me = new OSString; 97 98 if (me && !me->initWithString(aString)) { 99 me->free(); 100 return 0; 101 } 102 103 return me; 104 } 105 106 OSString *OSString::withCString(const char *cString) 107 { 108 OSString *me = new OSString; 109 110 if (me && !me->initWithCString(cString)) { 111 me->free(); 112 return 0; 113 } 114 115 return me; 116 } 117 118 OSString *OSString::withCStringNoCopy(const char *cString) 119 { 120 OSString *me = new OSString; 121 122 if (me && !me->initWithCStringNoCopy(cString)) { 123 me->free(); 124 return 0; 125 } 126 127 return me; 128 } 129 130 /* @@@ gvdl */ 131 #if 0 132 OSString *OSString::stringWithFormat(const char *format, ...) 133 { 134 #ifndef KERNEL // mach3xxx 135 OSString *me; 136 va_list argList; 137 138 if (!format) 139 return 0; 140 141 va_start(argList, format); 142 me = stringWithCapacity(256); 143 me->length = vsnprintf(me->string, 256, format, argList); 144 me->length++; // we include the null in the length 145 if (me->Length > 256) 146 me->Length = 256; 147 va_end (argList); 148 149 return me; 150 #else 151 return 0; 152 #endif 153 } 154 #endif /* 0 */ 155 156 void OSString::free() 157 { 158 if ( !(flags & kOSStringNoCopy) && string) { 159 kfree((vm_offset_t)string, (vm_size_t)length); 160 ACCUMSIZE(-length); 161 } 162 163 super::free(); 164 } 165 166 unsigned int OSString::getLength() const { return length - 1; } 167 168 const char *OSString::getCStringNoCopy() const 169 { 170 return string; 171 } 172 173 bool OSString::setChar(char aChar, unsigned int index) 174 { 175 if ( !(flags & kOSStringNoCopy) && index < length - 1) { 176 string[index] = aChar; 177 178 return true; 179 } 180 else 181 return false; 182 } 183 184 char OSString::getChar(unsigned int index) const 185 { 186 if (index < length) 187 return string[index]; 188 else 189 return '\0'; 190 } 191 192 193 bool OSString::isEqualTo(const OSString *aString) const 194 { 195 if (length != aString->length) 196 return false; 197 else 198 return isEqualTo((const char *) aString->string); 199 } 200 201 bool OSString::isEqualTo(const char *aCString) const 202 { 203 return strcmp(string, aCString) == 0; 204 } 205 206 bool OSString::isEqualTo(const OSMetaClassBase *obj) const 207 { 208 OSString * str; 209 OSData * data; 210 211 if ((str = OSDynamicCast(OSString, obj))) 212 return isEqualTo(str); 213 else if ((data = OSDynamicCast (OSData, obj))) 214 return isEqualTo(data); 215 else 216 return false; 217 } 218 219 bool OSString::isEqualTo(const OSData *obj) const 220 { 221 if (NULL == obj) 222 return false; 223 224 unsigned int dataLen = obj->getLength ();; 225 char * dataPtr = (char *) obj->getBytesNoCopy (); 226 227 if (dataLen != length) { 228 229 // check for the fact that OSData may be a buffer that 230 // that includes a termination byte and will thus have 231 // a length of the actual string length PLUS 1. In this 232 // case we verify that the additional byte is a terminator 233 // and if so count the two lengths as being the same. 234 235 if ( (dataLen - length) == 1 ) { 236 if (dataPtr[dataLen-1] != 0) 237 return false; 238 dataLen--; 239 } 240 else 241 return false; 242 } 243 244 for ( unsigned int i=0; i < dataLen; i++ ) { 245 if ( *dataPtr++ != string[i] ) 246 return false; 247 } 248 249 return true; 250 } 251 252 bool OSString::serialize(OSSerialize *s) const 253 { 254 char *c = string; 255 256 if (s->previouslySerialized(this)) return true; 257 258 if (!s->addXMLStartTag(this, "string")) return false; 259 while (*c) { 260 if (*c == '<') { 261 if (!s->addString("<")) return false; 262 } else if (*c == '>') { 263 if (!s->addString(">")) return false; 264 } else if (*c == '&') { 265 if (!s->addString("&")) return false; 266 } else { 267 if (!s->addChar(*c)) return false; 268 } 269 c++; 270 } 271 272 return s->addXMLEndTag("string"); 273 } 274