xref: /xnu-10063.141.1/libkern/libkern/c++/OSNumber.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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