1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.tracecompass
.ctf
.core
.event
.types
;
14 import java
.nio
.ByteOrder
;
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
;
23 * A CTF float declaration.
25 * The declaration of a floating point basic data type.
28 * @author Matthew Khouzam
31 public final class FloatDeclaration
extends Declaration
implements ISimpleDatatypeDeclaration
{
33 // ------------------------------------------------------------------------
35 // ------------------------------------------------------------------------
37 private final int fMantissa
;
38 private final int fExponent
;
39 private final ByteOrder fByteOrder
;
40 private final long fAlignement
;
42 // ------------------------------------------------------------------------
44 // ------------------------------------------------------------------------
50 * The exponent size in bits
52 * The mantissa size in bits (+1 for sign) (see CTF spec)
56 * The alignment. Should be ≥ 1
58 public FloatDeclaration(int exponent
, int mantissa
, @Nullable ByteOrder byteOrder
,
62 ByteOrder byteOrder2
= (byteOrder
== null) ? ByteOrder
.nativeOrder() : byteOrder
;
63 if (byteOrder2
== null) {
64 throw new IllegalStateException("ByteOrder cannot be null"); //$NON-NLS-1$
66 fByteOrder
= byteOrder2
;
67 fAlignement
= Math
.max(alignment
, 1);
71 // ------------------------------------------------------------------------
72 // Getters/Setters/Predicates
73 // ------------------------------------------------------------------------
78 public int getMantissa() {
85 public int getExponent() {
90 * @return the byteOrder
92 public ByteOrder
getByteOrder() {
97 public long getAlignment() {
105 public int getMaximumSize() {
106 return fMantissa
+ fExponent
+ 1;
109 // ------------------------------------------------------------------------
111 // ------------------------------------------------------------------------
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
);
127 public String
toString() {
128 /* Only used for debugging */
129 return "[declaration] float[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
132 private double read(BitBuffer input
) throws CTFReaderException
{
133 /* Offset the buffer position wrt the current alignment */
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
);
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
);
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
);
159 * Create a float from the raw value, Mathematicians beware.
162 * The raw value( up to 64 bits)
164 * number of bits in the mantissa
166 * number of bits in the exponent
168 private static double createFloat(long rawValue
, final int manBits
,
170 long manShift
= 1L << (manBits
);
171 long manMask
= manShift
- 1;
172 long expMask
= (1L << expBits
) - 1;
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
;
186 public int hashCode() {
187 final int prime
= 31;
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
;
197 public boolean equals(@Nullable Object obj
) {
204 if (getClass() != obj
.getClass()) {
207 FloatDeclaration other
= (FloatDeclaration
) obj
;
208 if (fAlignement
!= other
.fAlignement
) {
211 if (!fByteOrder
.equals(other
.fByteOrder
)) {
214 if (fExponent
!= other
.fExponent
) {
217 if (fMantissa
!= other
.fMantissa
) {
224 public boolean isBinaryEquivalent(@Nullable IDeclaration obj
) {