Commit | Line | Data |
---|---|---|
53047a66 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2011-2012 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.linuxtools.ctf.core.event.types; | |
13 | ||
486efb2e | 14 | import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; |
db8e8f7d | 15 | import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; |
53047a66 | 16 | |
9ac2eb62 | 17 | /** |
d37aaa7f | 18 | * A CTF float definition. |
486efb2e | 19 | * |
d37aaa7f FC |
20 | * The definition of a floating point basic data type. It will take the data |
21 | * from a trace and store it (and make it fit) as a double. | |
9ac2eb62 | 22 | * |
d37aaa7f FC |
23 | * @version 1.0 |
24 | * @author Matthew Khouzam | |
25 | * @author Simon Marchi | |
9ac2eb62 | 26 | */ |
53047a66 MK |
27 | public class FloatDefinition extends Definition { |
28 | // ------------------------------------------------------------------------ | |
29 | // Attributes | |
30 | // ------------------------------------------------------------------------ | |
31 | ||
32 | private final FloatDeclaration declaration; | |
33 | private double value; | |
34 | ||
35 | // ------------------------------------------------------------------------ | |
a511da0d | 36 | // Constructors |
53047a66 MK |
37 | // ------------------------------------------------------------------------ |
38 | ||
9ac2eb62 MK |
39 | /** |
40 | * Constructor | |
41 | * | |
42 | * @param declaration | |
43 | * the parent declaration | |
44 | * @param definitionScope | |
45 | * the parent scope | |
46 | * @param fieldName | |
47 | * the field name | |
48 | */ | |
53047a66 MK |
49 | public FloatDefinition(FloatDeclaration declaration, |
50 | IDefinitionScope definitionScope, String fieldName) { | |
51 | super(definitionScope, fieldName); | |
52 | this.declaration = declaration; | |
53 | } | |
07002e0a | 54 | |
53047a66 | 55 | // ------------------------------------------------------------------------ |
a511da0d | 56 | // Getters/Setters/Predicates |
53047a66 MK |
57 | // ------------------------------------------------------------------------ |
58 | ||
9ac2eb62 | 59 | /** |
a511da0d | 60 | * The value of a float stored, fit into a double. This should be extended |
9ac2eb62 MK |
61 | * for exotic floats if this is necessary. |
62 | * | |
63 | * @return the value of the float field fit into a double. | |
64 | */ | |
53047a66 MK |
65 | public double getValue() { |
66 | return value; | |
67 | } | |
68 | ||
9ac2eb62 MK |
69 | /** |
70 | * Sets the value of the float | |
71 | * | |
72 | * @param val | |
73 | * the value of the float | |
74 | */ | |
53047a66 MK |
75 | public void setValue(double val) { |
76 | value = val; | |
77 | } | |
78 | ||
9ac2eb62 | 79 | @Override |
53047a66 MK |
80 | public FloatDeclaration getDeclaration() { |
81 | return declaration; | |
82 | } | |
83 | ||
84 | // ------------------------------------------------------------------------ | |
85 | // Operations | |
86 | // ------------------------------------------------------------------------ | |
87 | ||
53047a66 | 88 | @Override |
db8e8f7d | 89 | public void read(BitBuffer input) throws CTFReaderException { |
9722444c | 90 | /* Offset the buffer position wrt the current alignment */ |
d6205f97 | 91 | alignRead(input, this.declaration); |
9722444c AM |
92 | final int exp = declaration.getExponent(); |
93 | final int mant = declaration.getMantissa(); | |
94 | ||
07002e0a MK |
95 | if ((exp + mant) == 32) { |
96 | value = readRawFloat32(input, mant, exp); | |
97 | } else if ((exp + mant) == 64) { | |
98 | value = readRawFloat64(input, mant, exp); | |
99 | } else { | |
53047a66 MK |
100 | value = Double.NaN; |
101 | } | |
102 | } | |
103 | ||
07002e0a | 104 | private static double readRawFloat64(BitBuffer input, final int manBits, |
db8e8f7d | 105 | final int expBits) throws CTFReaderException { |
07002e0a MK |
106 | long low = input.getInt(32, false); |
107 | low = low & 0x00000000FFFFFFFFL; | |
108 | long high = input.getInt(32, false); | |
109 | high = high & 0x00000000FFFFFFFFL; | |
110 | long temp = (high << 32) | low; | |
111 | return createFloat(temp, manBits - 1, expBits); | |
53047a66 MK |
112 | } |
113 | ||
114 | /** | |
115 | * @param rawValue | |
116 | * @param manBits | |
117 | * @param expBits | |
118 | */ | |
07002e0a MK |
119 | private static double createFloat(long rawValue, final int manBits, |
120 | final int expBits) { | |
fd74e6c1 MK |
121 | long manShift = 1L << (manBits); |
122 | long manMask = manShift - 1; | |
123 | long expMask = (1L << expBits) - 1; | |
124 | ||
07002e0a | 125 | int exp = (int) ((rawValue >> (manBits)) & expMask) + 1; |
fd74e6c1 | 126 | long man = (rawValue & manMask); |
d6205f97 MK |
127 | final int offsetExponent = exp - (1 << (expBits - 1)); |
128 | double expPow = Math.pow(2.0, offsetExponent); | |
fd74e6c1 MK |
129 | double ret = man * 1.0f; |
130 | ret /= manShift; | |
131 | ret += 1.0; | |
132 | ret *= expPow; | |
133 | return ret; | |
53047a66 MK |
134 | } |
135 | ||
fd74e6c1 | 136 | private static double readRawFloat32(BitBuffer input, final int manBits, |
db8e8f7d | 137 | final int expBits) throws CTFReaderException { |
53047a66 | 138 | long temp = input.getInt(32, false); |
07002e0a | 139 | return createFloat(temp, manBits - 1, expBits); |
53047a66 MK |
140 | } |
141 | ||
142 | @Override | |
143 | public String toString() { | |
144 | return String.valueOf(value); | |
145 | } | |
146 | } |