btf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / FloatDeclaration.java
index 293528f2769e27a48ecaac028304fb2843ff35af..084cae691fd4be44e1ef9e1f94fafea8b320ba43 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
+ * Copyright (c) 2011, 2013 Ericsson, Ecole Polytechnique de Montreal and others
  *
  * All rights reserved. This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License v1.0 which
@@ -13,69 +13,107 @@ package org.eclipse.linuxtools.ctf.core.event.types;
 
 import java.nio.ByteOrder;
 
+import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
+import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope;
+import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
 
-public class FloatDeclaration implements IDeclaration {
+/**
+ * A CTF float declaration.
+ *
+ * The declaration of a floating point basic data type.
+ *
+ * @version 1.0
+ * @author Matthew Khouzam
+ */
+public final class FloatDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
 
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
 
-    private final int mant;
-    private final int exp;
-    private final ByteOrder byteOrder;
-    private final long alignment;
+    private final int fMantissa;
+    private final int fExponent;
+    private final ByteOrder fByteOrder;
+    private final long fAlignement;
 
     // ------------------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------------------
 
+    /**
+     * Constructor
+     *
+     * @param exponent
+     *            The exponent size in bits
+     * @param mantissa
+     *            The mantissa size in bits (+1 for sign) (see CTF spec)
+     * @param byteOrder
+     *            The byte order
+     * @param alignment
+     *            The alignment. Should be ≥ 1
+     */
     public FloatDeclaration(int exponent, int mantissa, ByteOrder byteOrder,
             long alignment) {
-        mant = mantissa;
-        exp = exponent;
-        this.byteOrder = byteOrder;
-        this.alignment = alignment;
+        fMantissa = mantissa;
+        fExponent = exponent;
+        fByteOrder = byteOrder;
+        fAlignement = Math.max(alignment, 1);
 
     }
 
     // ------------------------------------------------------------------------
-    // Gettters/Setters/Predicates
+    // Getters/Setters/Predicates
     // ------------------------------------------------------------------------
 
     /**
      * @return the mant
      */
     public int getMantissa() {
-        return mant;
+        return fMantissa;
     }
 
     /**
      * @return the exp
      */
     public int getExponent() {
-        return exp;
+        return fExponent;
     }
 
     /**
      * @return the byteOrder
      */
     public ByteOrder getByteOrder() {
-        return byteOrder;
+        return fByteOrder;
     }
 
     @Override
     public long getAlignment() {
-        return alignment;
+        return fAlignement;
+    }
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public int getMaximumSize() {
+        return fMantissa + fExponent + 1;
     }
 
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * @since 3.0
+     */
     @Override
     public FloatDefinition createDefinition(IDefinitionScope definitionScope,
-            String fieldName) {
-        return new FloatDefinition(this, definitionScope, fieldName);
+            String fieldName, BitBuffer input) throws CTFReaderException {
+        ByteOrder byteOrder = input.getByteOrder();
+        input.setByteOrder(fByteOrder);
+        double value = read(input);
+        input.setByteOrder(byteOrder);
+        return new FloatDefinition(this, definitionScope, fieldName, value);
     }
 
     @Override
@@ -83,4 +121,57 @@ public class FloatDeclaration implements IDeclaration {
         /* Only used for debugging */
         return "[declaration] float[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
     }
+
+    private double read(BitBuffer input) throws CTFReaderException {
+        /* Offset the buffer position wrt the current alignment */
+        alignRead(input);
+        final int exp = getExponent();
+        final int mant = getMantissa();
+        double value = Double.NaN;
+        if ((exp + mant) == 32) {
+            value = readRawFloat32(input, mant, exp);
+        } else if ((exp + mant) == 64) {
+            value = readRawFloat64(input, mant, exp);
+        }
+        return value;
+    }
+
+    private static double readRawFloat32(BitBuffer input, final int manBits,
+            final int expBits) throws CTFReaderException {
+        long temp = input.get(32, false);
+        return createFloat(temp, manBits - 1, expBits);
+    }
+
+    private static double readRawFloat64(BitBuffer input, final int manBits,
+            final int expBits) throws CTFReaderException {
+        long temp = input.get(64, false);
+        return createFloat(temp, manBits - 1, expBits);
+    }
+
+    /**
+     * Create a float from the raw value, Mathematicians beware.
+     *
+     * @param rawValue
+     *            The raw value( up to 64 bits)
+     * @param manBits
+     *            number of bits in the mantissa
+     * @param expBits
+     *            number of bits in the exponent
+     */
+    private static double createFloat(long rawValue, final int manBits,
+            final int expBits) {
+        long manShift = 1L << (manBits);
+        long manMask = manShift - 1;
+        long expMask = (1L << expBits) - 1;
+
+        int exp = (int) ((rawValue >> (manBits)) & expMask) + 1;
+        long man = (rawValue & manMask);
+        final int offsetExponent = exp - (1 << (expBits - 1));
+        double expPow = Math.pow(2.0, offsetExponent);
+        double ret = man * 1.0f;
+        ret /= manShift;
+        ret += 1.0;
+        ret *= expPow;
+        return ret;
+    }
 }
This page took 0.026619 seconds and 5 git commands to generate.