1 /* 2 * Copyright (c) 2019 Apple 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.h created by rsulack on Wed 17-Sep-1997 */ 29 /* IOOffset.h converted to C++ by gvdl on Fri 1998-10-30 */ 30 31 #ifndef _OS_OSNUMBER_H 32 #define _OS_OSNUMBER_H 33 34 #include <libkern/c++/OSPtr.h> 35 #include <libkern/c++/OSObject.h> 36 37 /*! 38 * @header 39 * 40 * @abstract 41 * This header declares the OSNumber container class. 42 */ 43 44 class OSNumber; 45 46 typedef OSNumber* OSNumberPtr; 47 48 /*! 49 * @class OSNumber 50 * 51 * @abstract 52 * OSNumber wraps an integer value in a C++ object 53 * for use in Libkern collections. 54 * 55 * @discussion 56 * OSNumber represents an integer of 8, 16, 32, or 64 bits 57 * as a Libkern C++ object. 58 * OSNumber objects are mutable: you can add to or set their values. 59 * 60 * <b>Use Restrictions</b> 61 * 62 * With very few exceptions in the I/O Kit, all Libkern-based C++ 63 * classes, functions, and macros are <b>unsafe</b> 64 * to use in a primary interrupt context. 65 * Consult the I/O Kit documentation related to primary interrupts 66 * for more information. 67 * 68 * OSNumber provides no concurrency protection; 69 * it's up to the usage context to provide any protection necessary. 70 * Some portions of the I/O Kit, such as 71 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link, 72 * handle synchronization via defined member functions for setting 73 * properties. 74 */ 75 class OSNumber : public OSObject 76 { 77 friend class OSSerialize; 78 79 OSDeclareDefaultStructors(OSNumber); 80 81 #if APPLE_KEXT_ALIGN_CONTAINERS 82 83 protected: 84 unsigned int size; 85 86 #if XNU_KERNEL_PRIVATE 87 union { 88 unsigned long long value; 89 double fpValue; 90 }; 91 #else 92 unsigned long long value; 93 #endif /* XNU_KERNEL_PRIVATE */ 94 95 #else /* APPLE_KEXT_ALIGN_CONTAINERS */ 96 97 protected: 98 #if XNU_KERNEL_PRIVATE 99 union { 100 unsigned long long value; 101 double fpValue; 102 }; 103 #else 104 unsigned long long value; 105 #endif /* XNU_KERNEL_PRIVATE */ 106 unsigned int size; 107 108 struct ExpansionData { }; 109 110 /* Reserved for future use. (Internal use only) */ 111 ExpansionData * reserved; 112 113 #endif /* APPLE_KEXT_ALIGN_CONTAINERS */ 114 115 public: 116 117 /*! 118 * @function withNumber 119 * 120 * @abstract 121 * Creates and initializes an instance of OSNumber 122 * with an integer value. 123 * 124 * @param value The numeric integer value for the OSNumber to store. 125 * @param numberOfBits The number of bits to limit storage to. 126 * 127 * @result 128 * An instance of OSNumber with a reference count of 1; 129 * <code>NULL</code> on failure. 130 * 131 * @discussion 132 * <code>value</code> is masked to the provided <code>numberOfBits</code> 133 * when the OSNumber object is initialized. 134 * 135 * You can change the value of an OSNumber later 136 * using <code>@link setValue setValue@/link</code> 137 * and <code>@link addValue addValue@/link</code>, 138 * but you can't change the bit size. 139 */ 140 static OSPtr<OSNumber> withNumber( 141 unsigned long long value, 142 unsigned int numberOfBits); 143 144 #if KERNEL_PRIVATE 145 /*! 146 * @function withDouble 147 * @abstract 148 * Creates and initializes an instance of OSNumber 149 * with an double value. 150 */ 151 static OSPtr<OSNumber> withDouble( 152 double value); 153 /*! 154 * @function withFloat 155 * @abstract 156 * Creates and initializes an instance of OSNumber 157 * with an float value. 158 */ 159 static OSPtr<OSNumber> withFloat( 160 float value); 161 #endif /* KERNEL_PRIVATE */ 162 163 /*! 164 * @function withNumber 165 * 166 * @abstract 167 * Creates and initializes an instance of OSNumber 168 * with an unsigned integer value represented as a C string. 169 * 170 * @param valueString A C string representing a numeric value 171 * for the OSNumber to store. 172 * @param numberOfBits The number of bits to limit storage to. 173 * 174 * @result 175 * An instance of OSNumber with a reference count of 1; 176 * <code>NULL</code> on failure. 177 * 178 * @discussion 179 * This function does not work in I/O Kit versions prior to 8.0 (Mac OS X 10.4). 180 * In I/O Kit version 8.0 and later, it works 181 * but is limited to parsing unsigned 32 bit quantities. 182 * The format of the C string may be decimal, hexadecimal ("0x" prefix), 183 * binary ("0b" prefix), or octal ("0" prefix). 184 * 185 * The parsed value is masked to the provided <code>numberOfBits</code> 186 * when the OSNumber object is initialized. 187 * 188 * You can change the value of an OSNumber later 189 * using <code>@link setValue setValue@/link</code> 190 * and <code>@link addValue addValue@/link</code>, 191 * but you can't change the bit size. 192 */ 193 static OSPtr<OSNumber> withNumber( 194 const char * valueString, 195 unsigned int numberOfBits); 196 197 198 /*! 199 * @function init 200 * 201 * @abstract 202 * Initializes an instance of OSNumber with an integer value. 203 * 204 * @param value The numeric integer value for the OSNumber to store. 205 * @param numberOfBits The number of bits to limit storage to. 206 * 207 * @result 208 * <code>true</code> if initialization succeeds, 209 * <code>false</code> on failure. 210 * 211 * @discussion 212 * Not for general use. Use the static instance creation method 213 * <code>@link 214 * //apple_ref/cpp/clm/OSNumber/withNumber/staticOSNumber*\/(constchar*,unsignedint) 215 * withNumber(unsigned long long, unsigned int)@/link</code> 216 * instead. 217 */ 218 virtual bool init( 219 unsigned long long value, 220 unsigned int numberOfBits); 221 222 223 /*! 224 * @function init 225 * 226 * @abstract 227 * Initializes an instance of OSNumber 228 * with an unsigned integer value represented as a C string. 229 * 230 * @param valueString A C string representing a numeric value 231 * for the OSNumber to store. 232 * @param numberOfBits The number of bits to limit storage to. 233 * 234 * @result 235 * <code>true</code> if initialization succeeds, 236 * <code>false</code> on failure. 237 * 238 * @discussion 239 * Not for general use. Use the static instance creation method 240 * <code>@link 241 * //apple_ref/cpp/clm/OSNumber/withNumber/staticOSNumber*\/(constchar*,unsignedint) 242 * withNumber(const char *, unsigned int)@/link</code> 243 * instead. 244 */ 245 virtual bool init( 246 const char * valueString, 247 unsigned int numberOfBits); 248 249 250 /*! 251 * @function free 252 * 253 * @abstract 254 * Deallocates or releases any resources 255 * used by the OSNumber instance. 256 * 257 * @discussion 258 * This function should not be called directly; 259 * use 260 * <code>@link 261 * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() 262 * release@/link</code> 263 * instead. 264 */ 265 virtual void free() APPLE_KEXT_OVERRIDE; 266 267 268 /*! 269 * @function numberOfBits 270 * 271 * @abstract 272 * Returns the number of bits used to represent 273 * the OSNumber object's integer value. 274 * 275 * @result 276 * The number of bits used to represent 277 * the OSNumber object's integer value. 278 * 279 * @discussion 280 * The number of bits is used to limit the stored value of the OSNumber. 281 * Any change to its value is performed as an <code>unsigned long long</code> 282 * and then truncated to the number of bits. 283 */ 284 virtual unsigned int numberOfBits() const; 285 286 287 /*! 288 * @function numberOfBytes 289 * 290 * @abstract 291 * Returns the number of bytes used to represent 292 * the OSNumber object's integer value. 293 * 294 * @result 295 * The number of bytes used to represent 296 * the OSNumber object's integer value. 297 * See <code>@link numberOfBits numberOfBits@/link</code>. 298 */ 299 virtual unsigned int numberOfBytes() const; 300 301 302 // xx-review: should switch to explicitly-sized int types 303 // xx-review: but that messes up C++ mangled symbols :-( 304 305 306 /*! 307 * @function unsigned8BitValue 308 * 309 * @abstract 310 * Returns the OSNumber object's integer value 311 * cast as an unsigned 8-bit integer. 312 * 313 * @result 314 * The OSNumber object's integer value 315 * cast as an unsigned 8-bit integer. 316 * 317 * @discussion 318 * This function merely casts the internal integer value, 319 * giving no indication of truncation or other potential conversion problems. 320 */ 321 virtual unsigned char unsigned8BitValue() const; 322 323 324 /*! 325 * @function unsigned16BitValue 326 * 327 * @abstract 328 * Returns the OSNumber object's integer value 329 * cast as an unsigned 16-bit integer. 330 * 331 * @result 332 * Returns the OSNumber object's integer value 333 * cast as an unsigned 16-bit integer. 334 * 335 * @discussion 336 * This function merely casts the internal integer value, 337 * giving no indication of truncation or other potential conversion problems. 338 */ 339 virtual unsigned short unsigned16BitValue() const; 340 341 342 /*! 343 * @function unsigned32BitValue 344 * 345 * @abstract 346 * Returns the OSNumber object's integer value 347 * cast as an unsigned 32-bit integer. 348 * 349 * @result 350 * Returns the OSNumber object's integer value 351 * cast as an unsigned 32-bit integer. 352 * 353 * @discussion 354 * This function merely casts the internal integer value, 355 * giving no indication of truncation or other potential conversion problems. 356 */ 357 virtual unsigned int unsigned32BitValue() const; 358 359 360 /*! 361 * @function unsigned64BitValue 362 * 363 * @abstract 364 * Returns the OSNumber object's integer value 365 * cast as an unsigned 64-bit integer. 366 * 367 * @result 368 * Returns the OSNumber object's integer value 369 * cast as an unsigned 64-bit integer. 370 * 371 * @discussion 372 * This function merely casts the internal integer value, 373 * giving no indication of truncation or other potential conversion problems. 374 */ 375 virtual unsigned long long unsigned64BitValue() const; 376 377 #if KERNEL_PRIVATE 378 /*! 379 * @function withDouble 380 * @abstract 381 * Returns the OSNumber object's floating point value. 382 */ 383 double doubleValue() const; 384 /*! 385 * @function withFloat 386 * @abstract 387 * Returns the OSNumber object's floating point value. 388 */ 389 float floatValue() const; 390 #endif /* KERNEL_PRIVATE */ 391 392 393 // xx-review: wow, there's no addNumber(OSNumber *)! 394 395 /*! 396 * @function addValue 397 * 398 * @abstract 399 * Adds a signed integer value to the internal integer value 400 * of the OSNumber object. 401 * 402 * @param value The value to be added. 403 * 404 * @discussion 405 * This function adds values as 64-bit integers, 406 * but masks the result by the bit size 407 * (see <code>@link numberOfBits numberOfBits@/link</code>), 408 * so addition overflows will not necessarily 409 * be the same as for plain C integers. 410 */ 411 virtual void addValue(signed long long value); 412 413 414 /*! 415 * @function setValue 416 * 417 * @abstract 418 * Replaces the current internal integer value 419 * of the OSNumber object by the value given. 420 * 421 * @param value The new value for the OSNumber object, 422 * which is truncated by the bit size of the OSNumber object 423 * (see <code>@link numberOfBits numberOfBits@/link</code>). 424 */ 425 virtual void setValue(unsigned long long value); 426 427 428 /*! 429 * @function isEqualTo 430 * 431 * @abstract 432 * Tests the equality of two OSNumber objects. 433 * 434 * @param aNumber The OSNumber to be compared against the receiver. 435 * 436 * @result 437 * <code>true</code> if the OSNumber objects are equal, 438 * <code>false</code> if not. 439 * 440 * @discussion 441 * Two OSNumber objects are considered equal 442 * if they represent the same C integer value. 443 */ 444 #if KERNEL_PRIVATE 445 /* Only compares the integer portion of the two OSNumber values. 446 */ 447 #endif /* KERNEL_PRIVATE */ 448 virtual bool isEqualTo(const OSNumber * aNumber) const; 449 450 451 /*! 452 * @function isEqualTo 453 * 454 * @abstract 455 * Tests the equality an OSNumber to an arbitrary object. 456 * 457 * @param anObject An object to be compared against the receiver. 458 * 459 * @result 460 * <code>true</code> if the objects are equal, 461 * <code>false</code> if not. 462 * 463 * @discussion 464 * An OSNumber is considered equal to another object if that object is 465 * derived from OSNumber and represents the same C integer value. 466 */ 467 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 468 469 470 /*! 471 * @function serialize 472 * 473 * @abstract 474 * Archives the receiver into the provided 475 * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link object. 476 * 477 * @param serializer The OSSerialize object. 478 * 479 * @result 480 * <code>true</code> if serialization succeeds, <code>false</code> if not. 481 */ 482 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; 483 484 485 OSMetaClassDeclareReservedUnused(OSNumber, 0); 486 OSMetaClassDeclareReservedUnused(OSNumber, 1); 487 OSMetaClassDeclareReservedUnused(OSNumber, 2); 488 OSMetaClassDeclareReservedUnused(OSNumber, 3); 489 OSMetaClassDeclareReservedUnused(OSNumber, 4); 490 OSMetaClassDeclareReservedUnused(OSNumber, 5); 491 OSMetaClassDeclareReservedUnused(OSNumber, 6); 492 OSMetaClassDeclareReservedUnused(OSNumber, 7); 493 }; 494 495 #endif /* !_OS_OSNUMBER_H */ 496