Copyright header update, 2015 edition
[deliverable/tracecompass.git] / 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.event.io.BitBuffer;
19 import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
20 import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
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 ByteOrder fByteOrder;
40 private final long fAlignement;
41
42 // ------------------------------------------------------------------------
43 // Constructors
44 // ------------------------------------------------------------------------
45
46 /**
47 * Constructor
48 *
49 * @param exponent
50 * The exponent size in bits
51 * @param mantissa
52 * The mantissa size in bits (+1 for sign) (see CTF spec)
53 * @param byteOrder
54 * The byte order
55 * @param alignment
56 * The alignment. Should be ≥ 1
57 */
58 public FloatDeclaration(int exponent, int mantissa, @Nullable ByteOrder byteOrder,
59 long alignment) {
60 fMantissa = mantissa;
61 fExponent = exponent;
62 ByteOrder byteOrder2 = (byteOrder == null) ? ByteOrder.nativeOrder() : byteOrder;
63 if (byteOrder2 == null) {
64 throw new IllegalStateException("ByteOrder cannot be null"); //$NON-NLS-1$
65 }
66 fByteOrder = byteOrder2;
67 fAlignement = Math.max(alignment, 1);
68
69 }
70
71 // ------------------------------------------------------------------------
72 // Getters/Setters/Predicates
73 // ------------------------------------------------------------------------
74
75 /**
76 * @return the mant
77 */
78 public int getMantissa() {
79 return fMantissa;
80 }
81
82 /**
83 * @return the exp
84 */
85 public int getExponent() {
86 return fExponent;
87 }
88
89 /**
90 * @return the byteOrder
91 */
92 public ByteOrder getByteOrder() {
93 return fByteOrder;
94 }
95
96 @Override
97 public long getAlignment() {
98 return fAlignement;
99 }
100
101 /**
102 * @since 3.0
103 */
104 @Override
105 public int getMaximumSize() {
106 return fMantissa + fExponent + 1;
107 }
108
109 // ------------------------------------------------------------------------
110 // Operations
111 // ------------------------------------------------------------------------
112
113 /**
114 * @since 3.0
115 */
116 @Override
117 public FloatDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
118 String fieldName, BitBuffer input) throws CTFReaderException {
119 ByteOrder byteOrder = input.getByteOrder();
120 input.setByteOrder(fByteOrder);
121 double value = read(input);
122 input.setByteOrder(byteOrder);
123 return new FloatDefinition(this, definitionScope, fieldName, value);
124 }
125
126 @Override
127 public String toString() {
128 /* Only used for debugging */
129 return "[declaration] float[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
130 }
131
132 private double read(BitBuffer input) throws CTFReaderException {
133 /* Offset the buffer position wrt the current alignment */
134 alignRead(input);
135 final int exp = getExponent();
136 final int mant = getMantissa();
137 double value = Double.NaN;
138 if ((exp + mant) == 32) {
139 value = readRawFloat32(input, mant, exp);
140 } else if ((exp + mant) == 64) {
141 value = readRawFloat64(input, mant, exp);
142 }
143 return value;
144 }
145
146 private static double readRawFloat32(BitBuffer input, final int manBits,
147 final int expBits) throws CTFReaderException {
148 long temp = input.get(32, false);
149 return createFloat(temp, manBits - 1, expBits);
150 }
151
152 private static double readRawFloat64(BitBuffer input, final int manBits,
153 final int expBits) throws CTFReaderException {
154 long temp = input.get(64, false);
155 return createFloat(temp, manBits - 1, expBits);
156 }
157
158 /**
159 * Create a float from the raw value, Mathematicians beware.
160 *
161 * @param rawValue
162 * The raw value( up to 64 bits)
163 * @param manBits
164 * number of bits in the mantissa
165 * @param expBits
166 * number of bits in the exponent
167 */
168 private static double createFloat(long rawValue, final int manBits,
169 final int expBits) {
170 long manShift = 1L << (manBits);
171 long manMask = manShift - 1;
172 long expMask = (1L << expBits) - 1;
173
174 int exp = (int) ((rawValue >> (manBits)) & expMask) + 1;
175 long man = (rawValue & manMask);
176 final int offsetExponent = exp - (1 << (expBits - 1));
177 double expPow = Math.pow(2.0, offsetExponent);
178 double ret = man * 1.0f;
179 ret /= manShift;
180 ret += 1.0;
181 ret *= expPow;
182 return ret;
183 }
184
185 @Override
186 public int hashCode() {
187 final int prime = 31;
188 int result = 1;
189 result = prime * result + (int) (fAlignement ^ (fAlignement >>> 32));
190 result = prime * result + fByteOrder.toString().hashCode(); // don't evaluate object but string
191 result = prime * result + fExponent;
192 result = prime * result + fMantissa;
193 return result;
194 }
195
196 @Override
197 public boolean equals(@Nullable Object obj) {
198 if (this == obj) {
199 return true;
200 }
201 if (obj == null) {
202 return false;
203 }
204 if (getClass() != obj.getClass()) {
205 return false;
206 }
207 FloatDeclaration other = (FloatDeclaration) obj;
208 if (fAlignement != other.fAlignement) {
209 return false;
210 }
211 if (!fByteOrder.equals(other.fByteOrder)) {
212 return false;
213 }
214 if (fExponent != other.fExponent) {
215 return false;
216 }
217 if (fMantissa != other.fMantissa) {
218 return false;
219 }
220 return true;
221 }
222
223 @Override
224 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
225 return equals(obj);
226 }
227 }
This page took 0.047126 seconds and 6 git commands to generate.