Commit | Line | Data |
---|---|---|
53047a66 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2011, 2013 Ericsson, Ecole Polytechnique de Montreal and others |
53047a66 MK |
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 | *******************************************************************************/ | |
fd74e6c1 | 11 | |
53047a66 MK |
12 | package org.eclipse.linuxtools.ctf.core.event.types; |
13 | ||
14 | import java.nio.ByteOrder; | |
15 | ||
a4fa4e36 MK |
16 | import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; |
17 | import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope; | |
18 | import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; | |
19 | ||
9ac2eb62 | 20 | /** |
d37aaa7f | 21 | * A CTF float declaration. |
056ebaf1 | 22 | * |
d37aaa7f | 23 | * The declaration of a floating point basic data type. |
9ac2eb62 | 24 | * |
d37aaa7f | 25 | * @version 1.0 |
9ac2eb62 | 26 | * @author Matthew Khouzam |
9ac2eb62 | 27 | */ |
a4fa4e36 | 28 | public final class FloatDeclaration extends Declaration { |
53047a66 MK |
29 | |
30 | // ------------------------------------------------------------------------ | |
31 | // Attributes | |
32 | // ------------------------------------------------------------------------ | |
33 | ||
a4fa4e36 MK |
34 | private final int fMantissa; |
35 | private final int fExponent; | |
36 | private final ByteOrder fByteOrder; | |
37 | private final long fAlignement; | |
53047a66 MK |
38 | |
39 | // ------------------------------------------------------------------------ | |
40 | // Constructors | |
41 | // ------------------------------------------------------------------------ | |
42 | ||
9ac2eb62 MK |
43 | /** |
44 | * Constructor | |
056ebaf1 AM |
45 | * |
46 | * @param exponent | |
47 | * The exponent size in bits | |
48 | * @param mantissa | |
49 | * The mantissa size in bits (+1 for sign) (see CTF spec) | |
50 | * @param byteOrder | |
51 | * The byte order | |
52 | * @param alignment | |
ab04fc6b | 53 | * The alignment. Should be ≥ 1 |
9ac2eb62 | 54 | */ |
53047a66 | 55 | public FloatDeclaration(int exponent, int mantissa, ByteOrder byteOrder, |
07002e0a | 56 | long alignment) { |
a4fa4e36 MK |
57 | fMantissa = mantissa; |
58 | fExponent = exponent; | |
59 | fByteOrder = byteOrder; | |
60 | fAlignement = Math.max(alignment, 1); | |
53047a66 MK |
61 | |
62 | } | |
63 | ||
64 | // ------------------------------------------------------------------------ | |
a511da0d | 65 | // Getters/Setters/Predicates |
53047a66 MK |
66 | // ------------------------------------------------------------------------ |
67 | ||
53047a66 MK |
68 | /** |
69 | * @return the mant | |
70 | */ | |
71 | public int getMantissa() { | |
a4fa4e36 | 72 | return fMantissa; |
53047a66 MK |
73 | } |
74 | ||
75 | /** | |
76 | * @return the exp | |
77 | */ | |
78 | public int getExponent() { | |
a4fa4e36 | 79 | return fExponent; |
53047a66 MK |
80 | } |
81 | ||
82 | /** | |
83 | * @return the byteOrder | |
84 | */ | |
85 | public ByteOrder getByteOrder() { | |
a4fa4e36 | 86 | return fByteOrder; |
53047a66 MK |
87 | } |
88 | ||
81c8e6f7 | 89 | @Override |
fd74e6c1 | 90 | public long getAlignment() { |
a4fa4e36 MK |
91 | return fAlignement; |
92 | } | |
93 | ||
94 | /** | |
95 | * @since 3.0 | |
96 | */ | |
97 | @Override | |
98 | public int getMaximumSize() { | |
99 | return fMantissa + fExponent + 1; | |
fd74e6c1 MK |
100 | } |
101 | ||
53047a66 MK |
102 | // ------------------------------------------------------------------------ |
103 | // Operations | |
104 | // ------------------------------------------------------------------------ | |
105 | ||
a4fa4e36 MK |
106 | /** |
107 | * @since 3.0 | |
108 | */ | |
53047a66 | 109 | @Override |
81c8e6f7 | 110 | public FloatDefinition createDefinition(IDefinitionScope definitionScope, |
a4fa4e36 MK |
111 | String fieldName, BitBuffer input) throws CTFReaderException { |
112 | alignRead(input); | |
113 | double value = read(input); | |
114 | return new FloatDefinition(this, definitionScope, fieldName, value); | |
53047a66 MK |
115 | } |
116 | ||
117 | @Override | |
118 | public String toString() { | |
119 | /* Only used for debugging */ | |
120 | return "[declaration] float[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$ | |
121 | } | |
a4fa4e36 MK |
122 | |
123 | private double read(BitBuffer input) throws CTFReaderException { | |
124 | /* Offset the buffer position wrt the current alignment */ | |
125 | alignRead(input); | |
126 | final int exp = getExponent(); | |
127 | final int mant = getMantissa(); | |
128 | double value = Double.NaN; | |
129 | if ((exp + mant) == 32) { | |
130 | value = readRawFloat32(input, mant, exp); | |
131 | } else if ((exp + mant) == 64) { | |
132 | value = readRawFloat64(input, mant, exp); | |
133 | } | |
134 | return value; | |
135 | } | |
136 | ||
137 | private static double readRawFloat32(BitBuffer input, final int manBits, | |
138 | final int expBits) throws CTFReaderException { | |
139 | long temp = input.get(32, false); | |
140 | return createFloat(temp, manBits - 1, expBits); | |
141 | } | |
142 | ||
143 | private static double readRawFloat64(BitBuffer input, final int manBits, | |
144 | final int expBits) throws CTFReaderException { | |
145 | long temp = input.get(64, false); | |
146 | return createFloat(temp, manBits - 1, expBits); | |
147 | } | |
148 | ||
149 | /** | |
150 | * Create a float from the raw value, Mathematicians beware. | |
151 | * | |
152 | * @param rawValue | |
153 | * The raw value( up to 64 bits) | |
154 | * @param manBits | |
155 | * number of bits in the mantissa | |
156 | * @param expBits | |
157 | * number of bits in the exponent | |
158 | */ | |
159 | private static double createFloat(long rawValue, final int manBits, | |
160 | final int expBits) { | |
161 | long manShift = 1L << (manBits); | |
162 | long manMask = manShift - 1; | |
163 | long expMask = (1L << expBits) - 1; | |
164 | ||
165 | int exp = (int) ((rawValue >> (manBits)) & expMask) + 1; | |
166 | long man = (rawValue & manMask); | |
167 | final int offsetExponent = exp - (1 << (expBits - 1)); | |
168 | double expPow = Math.pow(2.0, offsetExponent); | |
169 | double ret = man * 1.0f; | |
170 | ret /= manShift; | |
171 | ret += 1.0; | |
172 | ret *= expPow; | |
173 | return ret; | |
174 | } | |
53047a66 | 175 | } |