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 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() {
102 public int getMaximumSize() {
103 return fMantissa
+ fExponent
+ 1;
106 // ------------------------------------------------------------------------
108 // ------------------------------------------------------------------------
111 public FloatDefinition
createDefinition(@Nullable IDefinitionScope definitionScope
,
112 String fieldName
, BitBuffer input
) throws CTFException
{
113 ByteOrder byteOrder
= input
.getByteOrder();
114 input
.setByteOrder(fByteOrder
);
115 double value
= read(input
);
116 input
.setByteOrder(byteOrder
);
117 return new FloatDefinition(this, definitionScope
, fieldName
, value
);
121 public String
toString() {
122 /* Only used for debugging */
123 return "[declaration] float[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
126 private double read(BitBuffer input
) throws CTFException
{
127 /* Offset the buffer position wrt the current alignment */
129 final int exp
= getExponent();
130 final int mant
= getMantissa();
131 double value
= Double
.NaN
;
132 if ((exp
+ mant
) == 32) {
133 value
= readRawFloat32(input
, mant
, exp
);
134 } else if ((exp
+ mant
) == 64) {
135 value
= readRawFloat64(input
, mant
, exp
);
140 private static double readRawFloat32(BitBuffer input
, final int manBits
,
141 final int expBits
) throws CTFException
{
142 long temp
= input
.get(32, false);
143 return createFloat(temp
, manBits
- 1, expBits
);
146 private static double readRawFloat64(BitBuffer input
, final int manBits
,
147 final int expBits
) throws CTFException
{
148 long temp
= input
.get(64, false);
149 return createFloat(temp
, manBits
- 1, expBits
);
153 * Create a float from the raw value, Mathematicians beware.
156 * The raw value( up to 64 bits)
158 * number of bits in the mantissa
160 * number of bits in the exponent
162 private static double createFloat(long rawValue
, final int manBits
,
164 long manShift
= 1L << (manBits
);
165 long manMask
= manShift
- 1;
166 long expMask
= (1L << expBits
) - 1;
168 int exp
= (int) ((rawValue
>> (manBits
)) & expMask
) + 1;
169 long man
= (rawValue
& manMask
);
170 final int offsetExponent
= exp
- (1 << (expBits
- 1));
171 double expPow
= Math
.pow(2.0, offsetExponent
);
172 double ret
= man
* 1.0f
;
180 public int hashCode() {
181 final int prime
= 31;
183 result
= prime
* result
+ (int) (fAlignement ^
(fAlignement
>>> 32));
184 result
= prime
* result
+ fByteOrder
.toString().hashCode(); // don't evaluate object but string
185 result
= prime
* result
+ fExponent
;
186 result
= prime
* result
+ fMantissa
;
191 public boolean equals(@Nullable Object obj
) {
198 if (getClass() != obj
.getClass()) {
201 FloatDeclaration other
= (FloatDeclaration
) obj
;
202 if (fAlignement
!= other
.fAlignement
) {
205 if (!fByteOrder
.equals(other
.fByteOrder
)) {
208 if (fExponent
!= other
.fExponent
) {
211 if (fMantissa
!= other
.fMantissa
) {
218 public boolean isBinaryEquivalent(@Nullable IDeclaration obj
) {