1 /* 2 * Copyright (c) 2000-2006 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 /* IOOffset.m created by rsulack on Wed 17-Sep-1997 */ 29 30 #define IOKIT_ENABLE_SHARED_PTR 31 32 #include <sys/cdefs.h> 33 34 #include <libkern/c++/OSNumber.h> 35 #include <libkern/c++/OSString.h> 36 #include <libkern/c++/OSSerialize.h> 37 #include <libkern/c++/OSSharedPtr.h> 38 #include <libkern/c++/OSLib.h> 39 40 #define sizeMask (~0ULL >> (64 - size)) 41 42 #define super OSObject 43 44 OSDefineMetaClassAndStructorsWithZone(OSNumber, OSObject, 45 (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM)) 46 47 OSMetaClassDefineReservedUnused(OSNumber, 0); 48 OSMetaClassDefineReservedUnused(OSNumber, 1); 49 OSMetaClassDefineReservedUnused(OSNumber, 2); 50 OSMetaClassDefineReservedUnused(OSNumber, 3); 51 OSMetaClassDefineReservedUnused(OSNumber, 4); 52 OSMetaClassDefineReservedUnused(OSNumber, 5); 53 OSMetaClassDefineReservedUnused(OSNumber, 6); 54 OSMetaClassDefineReservedUnused(OSNumber, 7); 55 56 bool 57 OSNumber::init(unsigned long long inValue, unsigned int newNumberOfBits) 58 { 59 if (!super::init()) { 60 return false; 61 } 62 if (newNumberOfBits > 64) { 63 return false; 64 } 65 66 size = newNumberOfBits; 67 value = (inValue & sizeMask); 68 69 return true; 70 } 71 72 bool 73 OSNumber::init(const char *newValue, unsigned int newNumberOfBits) 74 { 75 return init((unsigned long long)strtoul(newValue, NULL, 0), newNumberOfBits); 76 } 77 78 void 79 OSNumber::free() 80 { 81 super::free(); 82 } 83 84 OSSharedPtr<OSNumber> 85 OSNumber::withNumber(unsigned long long value, 86 unsigned int newNumberOfBits) 87 { 88 OSSharedPtr<OSNumber> me = OSMakeShared<OSNumber>(); 89 90 if (me && !me->init(value, newNumberOfBits)) { 91 return nullptr; 92 } 93 94 return me; 95 } 96 97 OSSharedPtr<OSNumber> 98 OSNumber::withNumber(const char *value, unsigned int newNumberOfBits) 99 { 100 OSSharedPtr<OSNumber> me = OSMakeShared<OSNumber>(); 101 102 if (me && !me->init(value, newNumberOfBits)) { 103 return nullptr; 104 } 105 106 return me; 107 } 108 109 OSSharedPtr<OSNumber> 110 OSNumber::withDouble( 111 double value) 112 { 113 OSSharedPtr<OSNumber> me = OSMakeShared<OSNumber>(); 114 115 if (me && !me->OSObject::init()) { 116 return nullptr; 117 } 118 me->size = 63; 119 me->fpValue = value; 120 121 return me; 122 } 123 124 OSSharedPtr<OSNumber> 125 OSNumber::withFloat( 126 float value) 127 { 128 OSSharedPtr<OSNumber> me = OSMakeShared<OSNumber>(); 129 130 if (me && !me->OSObject::init()) { 131 return nullptr; 132 } 133 me->size = 31; 134 me->fpValue = (double) value; 135 136 return me; 137 } 138 139 double 140 OSNumber::doubleValue() const 141 { 142 if ((size != 63) && (size != 31)) { 143 return (double) value; 144 } 145 return fpValue; 146 } 147 148 float 149 OSNumber::floatValue() const 150 { 151 if ((size != 63) && (size != 31)) { 152 return (float) value; 153 } 154 return (float) fpValue; 155 } 156 157 unsigned int 158 OSNumber::numberOfBits() const 159 { 160 return size; 161 } 162 163 unsigned int 164 OSNumber::numberOfBytes() const 165 { 166 return (size + 7) / 8; 167 } 168 169 170 unsigned char 171 OSNumber::unsigned8BitValue() const 172 { 173 if ((size == 63) || (size == 31)) { 174 return (unsigned char) fpValue; 175 } 176 return (unsigned char) value; 177 } 178 179 unsigned short 180 OSNumber::unsigned16BitValue() const 181 { 182 if ((size == 63) || (size == 31)) { 183 return (unsigned short) fpValue; 184 } 185 return (unsigned short) value; 186 } 187 188 unsigned int 189 OSNumber::unsigned32BitValue() const 190 { 191 if ((size == 63) || (size == 31)) { 192 return (unsigned int) fpValue; 193 } 194 return (unsigned int) value; 195 } 196 197 unsigned long long 198 OSNumber::unsigned64BitValue() const 199 { 200 if ((size == 63) || (size == 31)) { 201 return (unsigned long long) fpValue; 202 } 203 return value; 204 } 205 206 void 207 OSNumber::addValue(signed long long inValue) 208 { 209 if ((size == 63) || (size == 31)) { 210 fpValue += inValue; 211 } else { 212 value = ((value + inValue) & sizeMask); 213 } 214 } 215 216 void 217 OSNumber::setValue(unsigned long long inValue) 218 { 219 if ((size == 63) || (size == 31)) { 220 fpValue = (double) inValue; 221 } else { 222 value = (inValue & sizeMask); 223 } 224 } 225 226 bool 227 OSNumber::isEqualTo(const OSNumber *integer) const 228 { 229 return unsigned64BitValue() == integer->unsigned64BitValue(); 230 } 231 232 bool 233 OSNumber::isEqualTo(const OSMetaClassBase *obj) const 234 { 235 OSNumber * offset; 236 if ((offset = OSDynamicCast(OSNumber, obj))) { 237 return isEqualTo(offset); 238 } else { 239 return false; 240 } 241 } 242 243 bool 244 OSNumber::serialize(OSSerialize *s) const 245 { 246 char temp[32]; 247 248 if (s->previouslySerialized(this)) { 249 return true; 250 } 251 252 snprintf(temp, sizeof(temp), "integer size=\"%d\"", size); 253 if (!s->addXMLStartTag(this, temp)) { 254 return false; 255 } 256 257 //XXX sprintf(temp, "0x%qx", value); 258 if ((value >> 32)) { 259 snprintf(temp, sizeof(temp), "0x%lx%08lx", (unsigned long)(value >> 32), 260 (unsigned long)(value & 0xFFFFFFFF)); 261 } else { 262 snprintf(temp, sizeof(temp), "0x%lx", (unsigned long)value); 263 } 264 if (!s->addString(temp)) { 265 return false; 266 } 267 268 return s->addXMLEndTag("integer"); 269 } 270