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#include <sys/cdefs.h>
31
32#include <libkern/c++/OSNumber.h>
33#include <libkern/c++/OSString.h>
34#include <libkern/c++/OSSerialize.h>
35#include <libkern/c++/OSLib.h>
36
37#define sizeMask (~0ULL >> (64 - size))
38
39#define super OSObject
40
41OSDefineMetaClassAndStructors(OSNumber, OSObject)
42
43OSMetaClassDefineReservedUnused(OSNumber, 0);
44OSMetaClassDefineReservedUnused(OSNumber, 1);
45OSMetaClassDefineReservedUnused(OSNumber, 2);
46OSMetaClassDefineReservedUnused(OSNumber, 3);
47OSMetaClassDefineReservedUnused(OSNumber, 4);
48OSMetaClassDefineReservedUnused(OSNumber, 5);
49OSMetaClassDefineReservedUnused(OSNumber, 6);
50OSMetaClassDefineReservedUnused(OSNumber, 7);
51
52bool OSNumber::init(unsigned long long inValue, unsigned int newNumberOfBits)
53{
54    if (!super::init())
55        return false;
56
57    size = newNumberOfBits;
58    value = (inValue & sizeMask);
59
60    return true;
61}
62
63bool OSNumber::init(const char *newValue, unsigned int newNumberOfBits)
64{
65    return init((unsigned long long)strtoul(newValue, NULL, 0), newNumberOfBits);
66}
67
68void OSNumber::free() { super::free(); }
69
70OSNumber *OSNumber::withNumber(unsigned long long value,
71                           unsigned int newNumberOfBits)
72{
73    OSNumber *me = new OSNumber;
74
75    if (me && !me->init(value, newNumberOfBits)) {
76        me->release();
77        return 0;
78    }
79
80    return me;
81}
82
83OSNumber *OSNumber::withNumber(const char *value, unsigned int newNumberOfBits)
84{
85    OSNumber *me = new OSNumber;
86
87    if (me && !me->init(value, newNumberOfBits)) {
88        me->release();
89        return 0;
90    }
91
92    return me;
93}
94
95unsigned int OSNumber::numberOfBits() const { return size; }
96
97unsigned int OSNumber::numberOfBytes() const { return (size + 7) / 8; }
98
99
100unsigned char OSNumber::unsigned8BitValue() const
101{
102    return (unsigned char) value;
103}
104
105unsigned short OSNumber::unsigned16BitValue() const
106{
107    return (unsigned short) value;
108}
109
110unsigned int OSNumber::unsigned32BitValue() const
111{
112    return (unsigned int) value;
113}
114
115unsigned long long OSNumber::unsigned64BitValue() const
116{
117    return value;
118}
119
120void OSNumber::addValue(signed long long inValue)
121{
122    value = ((value + inValue) & sizeMask);
123}
124
125void OSNumber::setValue(unsigned long long inValue)
126{
127    value = (inValue & sizeMask);
128}
129
130bool OSNumber::isEqualTo(const OSNumber *integer) const
131{
132    return((value == integer->value));
133}
134
135bool OSNumber::isEqualTo(const OSMetaClassBase *obj) const
136{
137    OSNumber *	offset;
138    if ((offset = OSDynamicCast(OSNumber, obj)))
139	return isEqualTo(offset);
140    else
141	return false;
142}
143
144bool OSNumber::serialize(OSSerialize *s) const
145{
146    char temp[32];
147
148    if (s->previouslySerialized(this)) return true;
149
150    snprintf(temp, sizeof(temp), "integer size=\"%d\"", size);
151    if (!s->addXMLStartTag(this, temp)) return false;
152
153    //XXX    sprintf(temp, "0x%qx", value);
154    if ((value >> 32)) {
155        snprintf(temp, sizeof(temp), "0x%lx%08lx", (unsigned long)(value >> 32),
156                    (unsigned long)(value & 0xFFFFFFFF));
157    } else {
158        snprintf(temp, sizeof(temp), "0x%lx", (unsigned long)value);
159    }
160    if (!s->addString(temp)) return false;
161
162    return s->addXMLEndTag("integer");
163}
164