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