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
44class OSNumber;
45
46typedef 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 */
75class OSNumber : public OSObject
76{
77 friend class OSSerialize;
78
79 OSDeclareDefaultStructors(OSNumber);
80
81#if APPLE_KEXT_ALIGN_CONTAINERS
82
83protected:
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
97protected:
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
115public:
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