ctf: Add support for arrays or any type.
authorFrancois Doray <fdoray.eclipse@gmail.com>
Mon, 2 Dec 2013 06:06:35 +0000 (01:06 -0500)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 4 Dec 2013 14:32:12 +0000 (09:32 -0500)
A null pointer exception occured for events that contained an array
of something else than "int". For example, an array of struct:

fields := struct {
  ...
  struct {
    string arg_name;
    string arg_value;
  } arguments[4];
};

With this fix, all arrays of CTF types are supported.
Sample output in the "Properties" view: http://i.imgur.com/31tqbgG.png

Change-Id: I3f2be314d1fd2bda8c95b208d018227477572fa8
Signed-off-by: François Doray <fdoray.eclipse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/19029
Reviewed-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
IP-Clean: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Tested-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
IP-Clean: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/ctfadaptor/CtfTmfEventFieldTest.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventField.java

index 8f1460b115fce5f893868318b9c8c3dadf03497b..74988791d42842454de47ae777c69718d848311b 100644 (file)
@@ -49,7 +49,12 @@ public class CtfTmfEventFieldTest {
 
     private static final String ROOT = "root";
     private static final String SEQ = "seq";
-    private static final String ARRAY = "array";
+    private static final String ARRAY_STR = "array_str";
+    private static final String ARRAY_FLOAT = "array_float";
+    private static final String ARRAY_INT = "array_int";
+    private static final String ARRAY_STRUCT = "array_struct";
+    private static final String ARRAY_VARIANT = "array_variant";
+    private static final String ARRAY_ENUM = "array_enum";
     private static final String STR = "str";
     private static final String FLOAT = "float";
     private static final String LEN = "len";
@@ -62,6 +67,8 @@ public class CtfTmfEventFieldTest {
     private static final byte TEST_NUMBER = 2;
     private static final String TEST_STRING = "two";
 
+    private static final int ARRAY_SIZE = 2;
+
     private StructDefinition fixture;
 
     /**
@@ -85,28 +92,45 @@ public class CtfTmfEventFieldTest {
                 ByteOrder.BIG_ENDIAN, Encoding.NONE, null, 8);
         FloatDeclaration flDec = new FloatDeclaration(8, 24,
                 ByteOrder.BIG_ENDIAN, 8);
-        ArrayDeclaration arrDec = new ArrayDeclaration(2, intDec);
         SequenceDeclaration seqDec = new SequenceDeclaration(LEN, intDec);
         StructDeclaration structDec = new StructDeclaration(8);
         EnumDeclaration enumDec = new EnumDeclaration(intDec);
         VariantDeclaration varDec = new VariantDeclaration();
+        ArrayDeclaration arrStrDec = new ArrayDeclaration(ARRAY_SIZE, strDec);
+        ArrayDeclaration arrFloatDec = new ArrayDeclaration(ARRAY_SIZE, flDec);
+        ArrayDeclaration arrIntDec = new ArrayDeclaration(ARRAY_SIZE, intDec);
+        ArrayDeclaration arrStructDec = new ArrayDeclaration(ARRAY_SIZE, structDec);
+        ArrayDeclaration arrVariantDec = new ArrayDeclaration(ARRAY_SIZE, varDec);
+        ArrayDeclaration arrEnumDec = new ArrayDeclaration(ARRAY_SIZE, enumDec);
 
         sDec.addField(INT, intDec);
         bb.put(TEST_NUMBER);
 
+        sDec.addField(ARRAY_INT, arrIntDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.put(TEST_NUMBER);
+        }
+
         sDec.addField(LEN, intDec);
         bb.put(TEST_NUMBER);
 
         sDec.addField(FLOAT, flDec);
         bb.putFloat(TEST_NUMBER);
 
+        sDec.addField(ARRAY_FLOAT, arrFloatDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.putFloat(TEST_NUMBER);
+        }
+
         sDec.addField(STR, strDec);
         bb.put(testStringBytes);
         bb.put((byte) 0);
 
-        sDec.addField(ARRAY, arrDec);
-        bb.put(TEST_NUMBER);
-        bb.put(TEST_NUMBER);
+        sDec.addField(ARRAY_STR, arrStrDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.put(testStringBytes);
+            bb.put((byte) 0);
+        }
 
         sDec.addField(SEQ, seqDec);
         bb.put(TEST_NUMBER);
@@ -119,17 +143,34 @@ public class CtfTmfEventFieldTest {
         bb.put((byte) 0);
         bb.put(TEST_NUMBER);
 
+        sDec.addField(ARRAY_STRUCT, arrStructDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.put(testStringBytes);
+            bb.put((byte) 0);
+            bb.put(TEST_NUMBER);
+        }
+
         enumDec.add(0, 1, LEN);
         enumDec.add(2, 3, FLOAT);
         sDec.addField(ENUM, enumDec);
         bb.put(TEST_NUMBER);
 
+        sDec.addField(ARRAY_ENUM, arrEnumDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.put(TEST_NUMBER);
+        }
+
         varDec.addField(LEN, intDec);
         varDec.addField(FLOAT, flDec);
         varDec.setTag(ENUM);
         sDec.addField(VARIANT, varDec);
         bb.putFloat(TEST_NUMBER);
 
+        sDec.addField(ARRAY_VARIANT, arrVariantDec);
+        for (int i = 0; i < ARRAY_SIZE; ++i) {
+            bb.putFloat(TEST_NUMBER);
+        }
+
         fixture = sDec.createDefinition(fixture, ROOT);
 
         bb.position(0);
@@ -147,13 +188,14 @@ public class CtfTmfEventFieldTest {
     }
 
     /**
-     * Run the CtfTmfEventField parseField(Definition,String) method test.
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of floats field.
      */
     @Test
-    public void testParseField_array() {
-        Definition fieldDef = fixture.lookupArray(ARRAY);
+    public void testParseField_array_float() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_FLOAT);
         CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
-        assertEquals("test=[02, 02]", result.toString());
+        assertEquals("test=[2.0, 2.0]", result.toString());
     }
 
     /**
@@ -166,6 +208,17 @@ public class CtfTmfEventFieldTest {
         assertEquals("test=02", result.toString());
     }
 
+    /**
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of integers field.
+     */
+    @Test
+    public void testParseField_array_int() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_INT);
+        CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
+        assertEquals("test=[02, 02]", result.toString());
+    }
+
     /**
      * Run the CtfTmfEventField parseField(Definition,String) method test.
      */
@@ -198,6 +251,17 @@ public class CtfTmfEventFieldTest {
         assertEquals("test=two", result.toString());
     }
 
+    /**
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of strings field.
+     */
+    @Test
+    public void testParseField_array_string() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_STR);
+        CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
+        assertEquals("test=[two, two]", result.toString());
+    }
+
     /**
      * Run the CtfTmfEventField parseField(Definition,String) method test.
      */
@@ -208,6 +272,17 @@ public class CtfTmfEventFieldTest {
         assertEquals("test=[str=two, int=02]", result.toString());
     }
 
+    /**
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of structs field.
+     */
+    @Test
+    public void testParseField_array_struct() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_STRUCT);
+        CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
+        assertEquals("test=[[str=two, int=02], [str=two, int=02]]", result.toString());
+    }
+
     /**
      * Run the CtfTmfEventField parseField(Definition,String) method test.
      */
@@ -218,6 +293,17 @@ public class CtfTmfEventFieldTest {
         assertEquals("test=float", result.toString());
     }
 
+    /**
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of enums field.
+     */
+    @Test
+    public void testParseField_array_enum() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_ENUM);
+        CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
+        assertEquals("test=[float, float]", result.toString());
+    }
+
     /**
      * Run the CtfTmfEventField parseField(Definition,String) method test.
      */
@@ -227,4 +313,15 @@ public class CtfTmfEventFieldTest {
         CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
         assertEquals("test=float=2.0", result.toString());
     }
+
+    /**
+     * Run the CtfTmfEventField parseField(Definition,String) method test for an
+     * array of variants field.
+     */
+    @Test
+    public void testParseField_array_variant() {
+        Definition fieldDef = fixture.lookupArray(ARRAY_VARIANT);
+        CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME);
+        assertEquals("test=[float=2.0, float=2.0]", result.toString());
+    }
 }
index 6277e9535e56845edda56b5659afb8760d78d776..242731eef12aadb9e43c1a21921b94d074611325 100644 (file)
@@ -12,6 +12,7 @@
  *  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;
@@ -21,7 +22,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map.Entry;
 
-import org.eclipse.linuxtools.ctf.core.event.types.ArrayDeclaration;
 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;
@@ -105,24 +105,25 @@ public abstract class CtfTmfEventField extends TmfEventField {
 
         } else if (fieldDef instanceof ArrayDefinition) {
             ArrayDefinition arrayDef = (ArrayDefinition) fieldDef;
-            ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
 
             if (arrayDef.isString()) {
                 /* This is an array of UTF-8 bytes, a.k.a. a String! */
                 field = new CTFStringField(fieldName, fieldDef.toString());
 
-            } 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();
+            } 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(fieldName, values,
-                        ((IntegerDeclaration) arrayDecl.getElementType()).getBase(),
-                        ((IntegerDeclaration) arrayDecl.getElementType()).isSigned());
-            }
-            /* Add other types of arrays here */
 
+                field = new CTFArrayField(fieldName, elements);
+            }
         } else if (fieldDef instanceof SequenceDefinition) {
             SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
             SequenceDeclaration seqDecl = seqDef.getDeclaration();
@@ -290,7 +291,7 @@ final class CTFIntegerArrayField extends CtfTmfEventField {
     }
 
     @Override
-    public String getFormattedValue() {
+    public synchronized String getFormattedValue() {
         if (formattedValue == null) {
             List<String> strings = new ArrayList<String>();
             for (long value : getValue()) {
@@ -303,6 +304,45 @@ final class CTFIntegerArrayField extends CtfTmfEventField {
 
 }
 
+/**
+ * CTF field implementation for arrays of arbitrary types.
+ *
+ * @author fdoray
+ */
+final class CTFArrayField extends CtfTmfEventField {
+
+    private String formattedValue = null;
+
+    /**
+     * Constructor for CTFArrayField.
+     *
+     * @param name
+     *            The name of this field
+     * @param elements
+     *            The array elements of this field
+     */
+    CTFArrayField(String name, CtfTmfEventField[] elements) {
+        super(name, elements, elements);
+    }
+
+    @Override
+    public CtfTmfEventField[] getValue() {
+        return (CtfTmfEventField[]) super.getValue();
+    }
+
+    @Override
+    public synchronized String getFormattedValue() {
+        if (formattedValue == null) {
+            List<String> strings = new ArrayList<String>();
+            for (CtfTmfEventField element : getValue()) {
+                strings.add(element.getFormattedValue());
+            }
+            formattedValue = strings.toString();
+        }
+        return formattedValue;
+    }
+}
+
 /**
  * CTF field implementation for floats.
  *
This page took 0.033539 seconds and 5 git commands to generate.