ctf/tmf: allow multiple traces to be open with name clashing events
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfEventField.java
index 6e5353ccbbc8b873839cad896ac926ac88f1b508..6e77376bdd5085ce2112c123c189d9a4792025d1 100644 (file)
@@ -1,68 +1,72 @@
 /*******************************************************************************
- * Copyright (c) 2011 Ericsson
+ * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License v1.0 which
  * accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
- * Contributors: Matthew Khouzam - Initial API and implementation
- * Contributors: Alexendre Montplaisir - Initial API and implementation
+ * Contributors:
+ *  Matthew Khouzam - Initial API and implementation
+ *  Alexandre Montplaisir - Initial API and implementation, extend TmfEventField
+ *  Bernd Hufmann - Add Enum field handling
+ *  Geneviève Bastien - Add Struct and Variant field handling
+ *  Jean-Christian Kouame - Correct handling of unsigned integer fields
+ *  François Doray - Add generic array field type
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
 
-import org.eclipse.linuxtools.ctf.core.event.types.ArrayDeclaration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map.Entry;
+
 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.Definition;
+import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration;
 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDeclaration;
 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition;
+import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
+import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition;
+import org.eclipse.linuxtools.internal.tmf.core.Messages;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
 
 /**
- * <b><u>CTFEventField</u></b>
+ * The CTF implementation of the TMF event field model
+ *
+ * @version 2.0
+ * @author Matthew Khouzam
+ * @author Alexandre Montplaisir
  */
-public abstract class CtfTmfEventField implements ITmfEventField {
-
-    // ------------------------------------------------------------------------
-    // Attributes
-    // ------------------------------------------------------------------------
-
-    protected final String name;
+public abstract class CtfTmfEventField extends TmfEventField {
 
     // ------------------------------------------------------------------------
-    // Constructors
+    // Constructor
     // ------------------------------------------------------------------------
 
     /**
-     * Constructor for CtfTmfEventField.
-     * @param name String
-     */
-    protected CtfTmfEventField(String name) {
-        /* Strip the damn underscores, screw you CTF */
-        if ( name.startsWith("_") ) { //$NON-NLS-1$
-            this.name = name.substring(1);
-        } else {
-            this.name = name;
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Getters/Setters/Predicates
-    // ------------------------------------------------------------------------
-
-    /**
-     * Method getName.
-     * @return String
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getName()
+     * Standard constructor. Only to be used internally, call parseField() to
+     * generate a new field object.
+     *
+     * @param name
+     *            The name of this field
+     * @param value
+     *            The value of this field. Its type should match the field type.
+     * @param fields
+     *            The children fields. Useful for composite fields
+     * @since 2.0
      */
-    @Override
-    public String getName() {
-        return this.name;
+    protected CtfTmfEventField(String name, Object value, ITmfEventField[] fields) {
+        super(/* Strip the underscore from the field name if there is one */
+                name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$
+                value,
+                fields);
     }
 
     // ------------------------------------------------------------------------
@@ -70,10 +74,13 @@ public abstract class CtfTmfEventField implements ITmfEventField {
     // ------------------------------------------------------------------------
 
     /**
-     * Method parseField.
-     * @param fieldDef Definition
-     * @param fieldName String
-     * @return CtfTmfEventField
+     * Factory method to instantiate CtfTmfEventField objects.
+     *
+     * @param fieldDef
+     *            The CTF Definition of this event field
+     * @param fieldName
+     *            String The name to assign to this field
+     * @return The resulting CtfTmfEventField object
      */
     public static CtfTmfEventField parseField(Definition fieldDef,
             String fieldName) {
@@ -81,363 +88,368 @@ public abstract class CtfTmfEventField implements ITmfEventField {
 
         /* Determine the Definition type */
         if (fieldDef instanceof IntegerDefinition) {
-            field = new CTFIntegerField(
-                    ((IntegerDefinition) fieldDef).getValue(), fieldName);
+            IntegerDefinition intDef = (IntegerDefinition) fieldDef;
+            int base = intDef.getDeclaration().getBase();
+            field = new CTFIntegerField(fieldName, intDef.getValue(), base, intDef.getDeclaration().isSigned());
+
+        } else if (fieldDef instanceof EnumDefinition) {
+            EnumDefinition enumDef = (EnumDefinition) fieldDef;
+            field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()));
 
         } else if (fieldDef instanceof StringDefinition) {
-            field = new CTFStringField(
-                    ((StringDefinition) fieldDef).getValue(), fieldName);
+            field = new CTFStringField(fieldName, ((StringDefinition) fieldDef).getValue());
+
+        } else if (fieldDef instanceof FloatDefinition) {
+            FloatDefinition floatDef = (FloatDefinition) fieldDef;
+            field = new CTFFloatField(fieldName, floatDef.getValue());
 
         } else if (fieldDef instanceof ArrayDefinition) {
             ArrayDefinition arrayDef = (ArrayDefinition) fieldDef;
-            ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
 
-            if (arrayDef.isString()) {
+            if (arrayDef.getDeclaration().isString()) {
                 /* This is an array of UTF-8 bytes, a.k.a. a String! */
-                field = new CTFStringField(fieldDef.toString(), fieldName);
-
-            } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
-                /* This is a an array of CTF Integers */
-                long[] values = new long[arrayDecl.getLength()];
-                for (int i = 0; i < arrayDecl.getLength(); i++) {
-                    values[i] = ((IntegerDefinition) arrayDef.getElem(i)).getValue();
+                field = new CTFStringField(fieldName, fieldDef.toString());
+
+            } else {
+                /* Arrays of elements of any other type */
+                Definition[] definitions = arrayDef.getDefinitions();
+                CtfTmfEventField[] elements = new CtfTmfEventField[definitions.length];
+
+                /* Parse the elements of the array. */
+                for (int i = 0; i < definitions.length; i++) {
+                    CtfTmfEventField curField = CtfTmfEventField.parseField(
+                            definitions[i], fieldName + '[' + i + ']');
+                    elements[i] = curField;
                 }
-                field = new CTFIntegerArrayField(values, fieldName);
-            }
-            /* Add other types of arrays here */
 
+                field = new CTFArrayField(fieldName, elements);
+            }
         } else if (fieldDef instanceof SequenceDefinition) {
             SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
             SequenceDeclaration seqDecl = seqDef.getDeclaration();
 
             if (seqDef.getLength() == 0) {
                 /* Some sequences have length = 0. Simply use an empty string */
-                field = new CTFStringField("", fieldName); //$NON-NLS-1$
+                field = new CTFStringField(fieldName, ""); //$NON-NLS-1$
             } else if (seqDef.isString()) {
                 /* Interpret this sequence as a String */
-                field = new CTFStringField(seqDef.toString(), fieldName);
+                field = new CTFStringField(fieldName, seqDef.toString());
             } else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
                 /* Sequence of integers => CTFIntegerArrayField */
                 long[] values = new long[seqDef.getLength()];
                 for (int i = 0; i < seqDef.getLength(); i++) {
                     values[i] = ((IntegerDefinition) seqDef.getElem(i)).getValue();
                 }
-                field = new CTFIntegerArrayField(values, fieldName);
+                field = new CTFIntegerArrayField(fieldName, values,
+                        ((IntegerDeclaration) seqDecl.getElementType()).getBase(),
+                        ((IntegerDeclaration) seqDecl.getElementType()).isSigned());
+
             }
             /* Add other Sequence types here */
-        } else if (fieldDef instanceof FloatDefinition){
-            FloatDefinition floatDef = (FloatDefinition) fieldDef;
-            field = new CTFFloatField( floatDef.getValue(), fieldName);
-        }
 
+        } else if (fieldDef instanceof StructDefinition) {
+            StructDefinition strDef = (StructDefinition) fieldDef;
+
+            String curFieldName = null;
+            Definition curFieldDef;
+            CtfTmfEventField curField;
+            List<ITmfEventField> list = new ArrayList<>();
+            /* Recursively parse the fields */
+            for (Entry<String, Definition> entry : strDef.getDefinitions().entrySet()) {
+                curFieldName = entry.getKey();
+                curFieldDef = entry.getValue();
+                curField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
+                list.add(curField);
+            }
+            field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
+
+        } else if (fieldDef instanceof VariantDefinition) {
+            VariantDefinition varDef = (VariantDefinition) fieldDef;
+
+            String curFieldName = varDef.getCurrentFieldName();
+            Definition curFieldDef = varDef.getDefinitions().get(curFieldName);
+            if (curFieldDef != null) {
+                CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
+                field = new CTFVariantField(fieldName, subField);
+            } else {
+                /* A safe-guard, but curFieldDef should never be null */
+                field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
+            }
 
-        return field;
-    }
-
-    /**
-     * Method copyFrom.
-     * @param other CtfTmfEventField
-     * @return CtfTmfEventField
-     */
-    public static CtfTmfEventField copyFrom(CtfTmfEventField other) {
-        switch (other.getFieldType()) {
-        case 0:
-            return new CTFIntegerField(((CTFIntegerField) other).getValue(),
-                    other.name);
-        case 1:
-            return new CTFStringField(((CTFStringField) other).getValue(),
-                    other.name);
-        case 2:
-            return new CTFIntegerArrayField(
-                    ((CTFIntegerArrayField) other).getValue(), other.name);
-        default:
-            return null;
+        } else {
+            /*
+             * Safe-guard, to avoid null exceptions later, field is expected not
+             * to be null
+             */
+            field = new CTFStringField(fieldName, Messages.TmfEventField_UnsupportedType + fieldDef.getClass().toString());
         }
+        return field;
     }
 
-    /**
-     * Method clone.
-     * @return CtfTmfEventField
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#clone()
-     */
     @Override
-    public CtfTmfEventField clone() {
-        return CtfTmfEventField.copyFrom(this);
+    public String toString() {
+        return getName() + '=' + getFormattedValue();
     }
 
-    /**
-     * Return the int representing this field's value type
-     *
-    
-     * @return the field type */
-    public abstract int getFieldType();
+}
 
-    /**
-     * Return this field's value. You can cast it to the correct type depending
-     * on what getFieldType says.
-     *
-    
-     * @return the field value * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
-     */
-    @Override
-    public abstract Object getValue();
+/**
+ * The CTF field implementation for integer fields.
+ *
+ * @author alexmont
+ */
+final class CTFIntegerField extends CtfTmfEventField {
+
+    private final int fBase;
+    private final boolean fSigned;
 
     /**
-     * Other methods defined by ITmfEventField, but not used here: the CTF
-     *       fields do not have sub-fields (yet!)
+     * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
+     * Java parser this is interpreted as a long.
      *
-    
-     * @return the field names * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldNames()
+     * @param name
+     *            The name of this field
+     * @param longValue
+     *            The integer value of this field
+     * @param signed
+     *            Is the value signed or not
      */
-    @Override
-    public String[] getFieldNames() {
-        return null;
+    CTFIntegerField(String name, long longValue, int base, boolean signed) {
+        super(name, longValue, null);
+        fSigned = signed;
+        fBase = base;
     }
 
-    /**
-     * Method getFieldName.
-     * @param index int
-     * @return String
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldName(int)
-     */
-    @SuppressWarnings("unused")
     @Override
-    public String getFieldName(int index) {
-        return null;
+    public Long getValue() {
+        return (Long) super.getValue();
     }
 
-    /**
-     * Method getFields.
-     * @return ITmfEventField[]
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFields()
-     */
     @Override
-    public ITmfEventField[] getFields() {
-        return null;
+    public String getFormattedValue() {
+        return IntegerDefinition.formatNumber(getValue(), fBase, fSigned);
     }
 
+}
+
+/**
+ * The CTF field implementation for string fields
+ *
+ * @author alexmont
+ */
+final class CTFStringField extends CtfTmfEventField {
+
     /**
-     * Method getField.
-     * @param fieldName String
-     * @return ITmfEventField
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(String)
+     * Constructor for CTFStringField.
+     *
+     * @param strValue
+     *            The string value of this field
+     * @param name
+     *            The name of this field
      */
-    @SuppressWarnings("unused")
-    @Override
-    public ITmfEventField getField(String fieldName) {
-        return null;
+    CTFStringField(String name, String strValue) {
+        super(name, strValue, null);
     }
 
-    /**
-     * Method getField.
-     * @param index int
-     * @return ITmfEventField
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(int)
-     */
-    @SuppressWarnings("unused")
     @Override
-    public ITmfEventField getField(int index) {
-        return null;
+    public String getValue() {
+        return (String) super.getValue();
     }
 }
 
 /**
- * <b><u>CTFIntegerField</u></b>
- * @author ematkho
- * @version $Revision: 1.0 $
+ * CTF field implementation for arrays of integers.
+ *
+ * @author alexmont
  */
-final class CTFIntegerField extends CtfTmfEventField {
+final class CTFIntegerArrayField extends CtfTmfEventField {
 
-    private final long longValue;
+    private final int fBase;
+    private final boolean fSigned;
+    private String fFormattedValue = null;
 
     /**
-     * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
-     * Java parser this is interpreted as a long.
-     * @param longValue long
-     * @param name String
+     * Constructor for CTFIntegerArrayField.
+     *
+     * @param name
+     *            The name of this field
+     * @param longValues
+     *            The array of integers (as longs) that compose this field's
+     *            value
+     * @param signed
+     *            Are the values in the array signed or not
      */
-    CTFIntegerField(long longValue, String name) {
-        super(name);
-        this.longValue = longValue;
+    CTFIntegerArrayField(String name, long[] longValues, int base, boolean signed) {
+        super(name, longValues, null);
+        fBase = base;
+        fSigned = signed;
     }
 
-    /**
-     * Method getFieldType.
-     * @return int
-     */
     @Override
-    public int getFieldType() {
-        return 0;
+    public long[] getValue() {
+        return (long[]) super.getValue();
     }
 
-    /**
-     * Method getValue.
-     * @return Long
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
-     */
     @Override
-    public Long getValue() {
-        return this.longValue;
+    public synchronized String getFormattedValue() {
+        if (fFormattedValue == null) {
+            List<String> strings = new ArrayList<>();
+            for (long value : getValue()) {
+                strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned));
+            }
+            fFormattedValue = strings.toString();
+        }
+        return fFormattedValue;
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return name + '=' + longValue;
-    }
 }
 
 /**
- * <b><u>CTFStringField</u></b>
- * @author ematkho
- * @version $Revision: 1.0 $
+ * CTF field implementation for arrays of arbitrary types.
+ *
+ * @author fdoray
  */
-final class CTFStringField extends CtfTmfEventField {
+final class CTFArrayField extends CtfTmfEventField {
 
-    private final String strValue;
+    private String fFormattedValue = null;
 
     /**
-     * Constructor for CTFStringField.
-     * @param strValue String
-     * @param name String
-     */
-    CTFStringField(String strValue, String name) {
-        super(name);
-        this.strValue = strValue;
-    }
-
-    /**
-     * Method getFieldType.
-     * @return int
+     * Constructor for CTFArrayField.
+     *
+     * @param name
+     *            The name of this field
+     * @param elements
+     *            The array elements of this field
      */
-    @Override
-    public int getFieldType() {
-        return 1;
+    CTFArrayField(String name, CtfTmfEventField[] elements) {
+        super(name, elements, elements);
     }
 
-    /**
-     * Method getValue.
-     * @return String
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
-     */
     @Override
-    public String getValue() {
-        return this.strValue;
+    public CtfTmfEventField[] getValue() {
+        return (CtfTmfEventField[]) super.getValue();
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Object#toString()
-     */
     @Override
-    public String toString() {
-        return name + '=' + strValue;
+    public synchronized String getFormattedValue() {
+        if (fFormattedValue == null) {
+            List<String> strings = new ArrayList<>();
+            for (CtfTmfEventField element : getValue()) {
+                strings.add(element.getFormattedValue());
+            }
+            fFormattedValue = strings.toString();
+        }
+        return fFormattedValue;
     }
 }
 
 /**
- * <b><u>CTFIntegerArrayField</u></b>
- * @author ematkho
- * @version $Revision: 1.0 $
+ * CTF field implementation for floats.
+ *
+ * @author emathko
  */
-final class CTFIntegerArrayField extends CtfTmfEventField {
-
-    private final long[] longValues;
+final class CTFFloatField extends CtfTmfEventField {
 
     /**
-     * Constructor for CTFIntegerArrayField.
-     * @param longValues long[]
-     * @param name String
+     * Constructor for CTFFloatField.
+     *
+     * @param value
+     *            The float value (actually a double) of this field
+     * @param name
+     *            The name of this field
      */
-    CTFIntegerArrayField(long[] longValues, String name) {
-        super(name);
-        this.longValues = longValues;
+    protected CTFFloatField(String name, double value) {
+        super(name, value, null);
     }
 
-    /**
-     * Method getFieldType.
-     * @return int
-     */
     @Override
-    public int getFieldType() {
-        return 2;
+    public Double getValue() {
+        return (Double) super.getValue();
     }
+}
+
+/**
+ * The CTF field implementation for Enum fields
+ *
+ * @author Bernd Hufmann
+ */
+final class CTFEnumField extends CtfTmfEventField {
 
     /**
-     * Method getValue.
-     * @return long[]
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
+     * Constructor for CTFEnumField.
+     *
+     * @param enumValue
+     *            The Enum value consisting of a pair of Enum value name and its
+     *            long value
+     * @param name
+     *            The name of this field
      */
-    @Override
-    public long[] getValue() {
-        return this.longValues;
+    CTFEnumField(String name, CtfEnumPair enumValue) {
+        super(name, new CtfEnumPair(enumValue.getFirst(),
+                enumValue.getSecond()), null);
     }
 
-    /**
-     * Method toString.
-     * @return String
-     */
     @Override
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-        buffer.append("{ "); //$NON-NLS-1$
-
-        buffer.append(longValues[0]);
-        for (int i = 1; i < longValues.length; i++) {
-            buffer.append(", " + longValues[i]); //$NON-NLS-1$
-        }
-        buffer.append('}');
-        return name + '=' + buffer.toString();
+    public CtfEnumPair getValue() {
+        return (CtfEnumPair) super.getValue();
     }
 }
 
 /**
+ * The CTF field implementation for struct fields with sub-fields
+ *
+ * @author gbastien
  */
-final class CTFFloatField extends CtfTmfEventField {
+final class CTFStructField extends CtfTmfEventField {
 
-    Double value;
     /**
-     * Constructor for CTFFloatField.
-     * @param value double
-     * @param name String
+     * Constructor for CTFStructField.
+     *
+     * @param fields
+     *            The children of this field
+     * @param name
+     *            The name of this field
      */
-    protected CTFFloatField(double value ,String name) {
-        super(name);
-        this.value = value;
+    CTFStructField(String name, CtfTmfEventField[] fields) {
+        super(name, fields, fields);
     }
 
-    /**
-     * Method getFieldType.
-     * @return int
-     */
     @Override
-    public int getFieldType() {
-        return 3;
+    public CtfTmfEventField[] getValue() {
+        return (CtfTmfEventField[]) super.getValue();
     }
 
-    /**
-     * Method getValue.
-     * @return Object
-     * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
-     */
     @Override
-    public Object getValue() {
-        return this.value;
+    public String getFormattedValue() {
+        return Arrays.toString(getValue());
     }
 
+}
+
+/**
+ * The CTF field implementation for variant fields its child
+ *
+ * @author gbastien
+ */
+final class CTFVariantField extends CtfTmfEventField {
+
     /**
-     * Method toString.
-     * @return String
+     * Constructor for CTFVariantField.
+     *
+     * @param field
+     *            The field selected for this variant
+     * @param name
+     *            The name of this field
      */
+    CTFVariantField(String name, CtfTmfEventField field) {
+        super(name, field, new CtfTmfEventField[] { field });
+    }
+
     @Override
-    public String toString(){
-        return name + '=' + value;
+    public CtfTmfEventField getValue() {
+        return (CtfTmfEventField) super.getValue();
     }
 
 }
+
 /* Implement other possible fields types here... */
This page took 0.03257 seconds and 5 git commands to generate.