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
.CTFException
;
19 import org
.eclipse
.tracecompass
.ctf
.core
.event
.io
.BitBuffer
;
20 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.IDefinitionScope
;
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 boolean fIsByteOrderSet
;
40 private final ByteOrder fByteOrder
;
41 private final long fAlignement
;
43 // ------------------------------------------------------------------------
45 // ------------------------------------------------------------------------
51 * The exponent size in bits
53 * The mantissa size in bits (+1 for sign) (see CTF spec)
57 * The alignment. Should be ≥ 1
59 public FloatDeclaration(int exponent
, int mantissa
, @Nullable ByteOrder byteOrder
,
63 fIsByteOrderSet
= byteOrder
!= null;
64 fByteOrder
= (byteOrder
== null) ? ByteOrder
.nativeOrder() : byteOrder
;
65 fAlignement
= Math
.max(alignment
, 1);
69 // ------------------------------------------------------------------------
70 // Getters/Setters/Predicates
71 // ------------------------------------------------------------------------
74 * @return the mantissa
76 public int getMantissa() {
81 * @return the exponent
83 public int getExponent() {
91 public boolean isByteOrderSet() {
92 return fIsByteOrderSet
;
96 public ByteOrder
getByteOrder() {
101 public long getAlignment() {
106 public int getMaximumSize() {
107 return fMantissa
+ fExponent
+ 1;
110 // ------------------------------------------------------------------------
112 // ------------------------------------------------------------------------
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
);
125 public String
toString() {
126 /* Only used for debugging */
127 return "[declaration] float[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
130 private double read(BitBuffer input
) throws CTFException
{
131 /* Offset the buffer position wrt the current alignment */
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
);
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
);
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
);
157 * Create a float from the raw value, Mathematicians beware.
160 * The raw value( up to 64 bits)
162 * number of bits in the mantissa
164 * number of bits in the exponent
166 private static double createFloat(long rawValue
, final int manBits
,
168 long manShift
= 1L << (manBits
);
169 long manMask
= manShift
- 1;
170 long expMask
= (1L << expBits
) - 1;
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
;
184 public int hashCode() {
185 final int prime
= 31;
187 result
= prime
* result
+ (int) (fAlignement ^
(fAlignement
>>> 32));
188 result
= prime
* result
+ fByteOrder
.toString().hashCode(); // don't
193 result
= prime
* result
+ fExponent
;
194 result
= prime
* result
+ fMantissa
;
199 public boolean equals(@Nullable Object obj
) {
206 if (getClass() != obj
.getClass()) {
209 FloatDeclaration other
= (FloatDeclaration
) obj
;
210 if (fAlignement
!= other
.fAlignement
) {
213 if (!fByteOrder
.equals(other
.fByteOrder
)) {
216 if (fExponent
!= other
.fExponent
) {
219 if (fMantissa
!= other
.fMantissa
) {
226 public boolean isBinaryEquivalent(@Nullable IDeclaration obj
) {