Remove unneeded checkNotNull() calls
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / FloatDeclaration.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11
12 package org.eclipse.tracecompass.ctf.core.event.types;
13
14 import java.nio.ByteOrder;
15
16 import org.eclipse.jdt.annotation.NonNullByDefault;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.eclipse.tracecompass.ctf.core.CTFException;
19 import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
20 import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
21
22 /**
23 * A CTF float declaration.
24 *
25 * The declaration of a floating point basic data type.
26 *
27 * @version 1.0
28 * @author Matthew Khouzam
29 */
30 @NonNullByDefault
31 public final class FloatDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
32
33 // ------------------------------------------------------------------------
34 // Attributes
35 // ------------------------------------------------------------------------
36
37 private final int fMantissa;
38 private final int fExponent;
39 private final boolean fIsByteOrderSet;
40 private final ByteOrder fByteOrder;
41 private final long fAlignement;
42
43 // ------------------------------------------------------------------------
44 // Constructors
45 // ------------------------------------------------------------------------
46
47 /**
48 * Constructor
49 *
50 * @param exponent
51 * The exponent size in bits
52 * @param mantissa
53 * The mantissa size in bits (+1 for sign) (see CTF spec)
54 * @param byteOrder
55 * The byte order
56 * @param alignment
57 * The alignment. Should be ≥ 1
58 */
59 public FloatDeclaration(int exponent, int mantissa, @Nullable ByteOrder byteOrder,
60 long alignment) {
61 fMantissa = mantissa;
62 fExponent = exponent;
63 fIsByteOrderSet = byteOrder != null;
64 fByteOrder = (byteOrder == null) ? ByteOrder.nativeOrder() : byteOrder;
65 fAlignement = Math.max(alignment, 1);
66
67 }
68
69 // ------------------------------------------------------------------------
70 // Getters/Setters/Predicates
71 // ------------------------------------------------------------------------
72
73 /**
74 * @return the mantissa
75 */
76 public int getMantissa() {
77 return fMantissa;
78 }
79
80 /**
81 * @return the exponent
82 */
83 public int getExponent() {
84 return fExponent;
85 }
86
87 /**
88 * @since 2.0
89 */
90 @Override
91 public boolean isByteOrderSet() {
92 return fIsByteOrderSet;
93 }
94
95 @Override
96 public ByteOrder getByteOrder() {
97 return fByteOrder;
98 }
99
100 @Override
101 public long getAlignment() {
102 return fAlignement;
103 }
104
105 @Override
106 public int getMaximumSize() {
107 return fMantissa + fExponent + 1;
108 }
109
110 // ------------------------------------------------------------------------
111 // Operations
112 // ------------------------------------------------------------------------
113
114 @Override
115 public FloatDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
116 String fieldName, BitBuffer input) throws CTFException {
117 ByteOrder byteOrder = input.getByteOrder();
118 input.setByteOrder(fByteOrder);
119 double value = read(input);
120 input.setByteOrder(byteOrder);
121 return new FloatDefinition(this, definitionScope, fieldName, value);
122 }
123
124 @Override
125 public String toString() {
126 /* Only used for debugging */
127 return "[declaration] float[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
128 }
129
130 private double read(BitBuffer input) throws CTFException {
131 /* Offset the buffer position wrt the current alignment */
132 alignRead(input);
133 final int exp = getExponent();
134 final int mant = getMantissa();
135 double value = Double.NaN;
136 if ((exp + mant) == 32) {
137 value = readRawFloat32(input, mant, exp);
138 } else if ((exp + mant) == 64) {
139 value = readRawFloat64(input, mant, exp);
140 }
141 return value;
142 }
143
144 private static double readRawFloat32(BitBuffer input, final int manBits,
145 final int expBits) throws CTFException {
146 long temp = input.get(32, false);
147 return createFloat(temp, manBits - 1, expBits);
148 }
149
150 private static double readRawFloat64(BitBuffer input, final int manBits,
151 final int expBits) throws CTFException {
152 long temp = input.get(64, false);
153 return createFloat(temp, manBits - 1, expBits);
154 }
155
156 /**
157 * Create a float from the raw value, Mathematicians beware.
158 *
159 * @param rawValue
160 * The raw value( up to 64 bits)
161 * @param manBits
162 * number of bits in the mantissa
163 * @param expBits
164 * number of bits in the exponent
165 */
166 private static double createFloat(long rawValue, final int manBits,
167 final int expBits) {
168 long manShift = 1L << (manBits);
169 long manMask = manShift - 1;
170 long expMask = (1L << expBits) - 1;
171
172 int exp = (int) ((rawValue >> (manBits)) & expMask) + 1;
173 long man = (rawValue & manMask);
174 final int offsetExponent = exp - (1 << (expBits - 1));
175 double expPow = Math.pow(2.0, offsetExponent);
176 double ret = man * 1.0f;
177 ret /= manShift;
178 ret += 1.0;
179 ret *= expPow;
180 return ret;
181 }
182
183 @Override
184 public int hashCode() {
185 final int prime = 31;
186 int result = 1;
187 result = prime * result + (int) (fAlignement ^ (fAlignement >>> 32));
188 result = prime * result + fByteOrder.toString().hashCode(); // don't
189 // evaluate
190 // object
191 // but
192 // string
193 result = prime * result + fExponent;
194 result = prime * result + fMantissa;
195 return result;
196 }
197
198 @Override
199 public boolean equals(@Nullable Object obj) {
200 if (this == obj) {
201 return true;
202 }
203 if (obj == null) {
204 return false;
205 }
206 if (getClass() != obj.getClass()) {
207 return false;
208 }
209 FloatDeclaration other = (FloatDeclaration) obj;
210 if (fAlignement != other.fAlignement) {
211 return false;
212 }
213 if (!fByteOrder.equals(other.fByteOrder)) {
214 return false;
215 }
216 if (fExponent != other.fExponent) {
217 return false;
218 }
219 if (fMantissa != other.fMantissa) {
220 return false;
221 }
222 return true;
223 }
224
225 @Override
226 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
227 return equals(obj);
228 }
229 }
This page took 0.035172 seconds and 5 git commands to generate.