rcp: Move plugins to their own sub-directory
[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.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 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 @Override
102 public int getMaximumSize() {
103 return fMantissa + fExponent + 1;
104 }
105
106 // ------------------------------------------------------------------------
107 // Operations
108 // ------------------------------------------------------------------------
109
110 @Override
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);
118 }
119
120 @Override
121 public String toString() {
122 /* Only used for debugging */
123 return "[declaration] float[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
124 }
125
126 private double read(BitBuffer input) throws CTFException {
127 /* Offset the buffer position wrt the current alignment */
128 alignRead(input);
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);
136 }
137 return value;
138 }
139
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);
144 }
145
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);
150 }
151
152 /**
153 * Create a float from the raw value, Mathematicians beware.
154 *
155 * @param rawValue
156 * The raw value( up to 64 bits)
157 * @param manBits
158 * number of bits in the mantissa
159 * @param expBits
160 * number of bits in the exponent
161 */
162 private static double createFloat(long rawValue, final int manBits,
163 final int expBits) {
164 long manShift = 1L << (manBits);
165 long manMask = manShift - 1;
166 long expMask = (1L << expBits) - 1;
167
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;
173 ret /= manShift;
174 ret += 1.0;
175 ret *= expPow;
176 return ret;
177 }
178
179 @Override
180 public int hashCode() {
181 final int prime = 31;
182 int result = 1;
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;
187 return result;
188 }
189
190 @Override
191 public boolean equals(@Nullable Object obj) {
192 if (this == obj) {
193 return true;
194 }
195 if (obj == null) {
196 return false;
197 }
198 if (getClass() != obj.getClass()) {
199 return false;
200 }
201 FloatDeclaration other = (FloatDeclaration) obj;
202 if (fAlignement != other.fAlignement) {
203 return false;
204 }
205 if (!fByteOrder.equals(other.fByteOrder)) {
206 return false;
207 }
208 if (fExponent != other.fExponent) {
209 return false;
210 }
211 if (fMantissa != other.fMantissa) {
212 return false;
213 }
214 return true;
215 }
216
217 @Override
218 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
219 return equals(obj);
220 }
221 }
This page took 0.061651 seconds and 5 git commands to generate.