ctf: Make events immutable
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / SequenceDeclaration.java
index 66957087b47fce7f43f5914426a6e43569d86f47..811321df5baa7007d0da249a7fed8dafdb988312 100644 (file)
 
 package org.eclipse.linuxtools.ctf.core.event.types;
 
+import java.util.Collection;
+import java.util.List;
+
+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;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.Multimap;
+
 /**
  * A CTF sequence declaration.
  *
@@ -24,14 +34,15 @@ import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
  * @author Matthew Khouzam
  * @author Simon Marchi
  */
-public class SequenceDeclaration implements IDeclaration {
+public class SequenceDeclaration extends Declaration {
 
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
 
-    private final IDeclaration elemType;
-    private final String lengthName;
+    private final IDeclaration fElemType;
+    private final String fLengthName;
+    private final Multimap<String, String> fPaths = ArrayListMultimap.<String, String>create();
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -46,8 +57,8 @@ public class SequenceDeclaration implements IDeclaration {
      *            The element type
      */
     public SequenceDeclaration(String lengthName, IDeclaration elemType) {
-        this.elemType = elemType;
-        this.lengthName = lengthName;
+        fElemType = elemType;
+        fLengthName = lengthName;
     }
 
     // ------------------------------------------------------------------------
@@ -56,18 +67,20 @@ public class SequenceDeclaration implements IDeclaration {
 
     /**
      * Gets the element type
+     *
      * @return the element type
      */
     public IDeclaration getElementType() {
-        return elemType;
+        return fElemType;
     }
 
     /**
      * Gets the name of the length field
+     *
      * @return the name of the length field
      */
     public String getLengthName() {
-        return lengthName;
+        return fLengthName;
     }
 
     @Override
@@ -75,22 +88,70 @@ public class SequenceDeclaration implements IDeclaration {
         return getElementType().getAlignment();
     }
 
+
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * Is the Sequence a string?
+     * @return true, if the elements are chars, false otherwise
+     * @since 3.0
+     */
+    public boolean isString(){
+        IntegerDeclaration elemInt;
+        IDeclaration elementType = getElementType();
+        if (elementType instanceof IntegerDeclaration) {
+            elemInt = (IntegerDeclaration) elementType;
+            if (elemInt.isCharacter()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @since 3.0
+     */
+    @SuppressWarnings("null") // immutablelist
     @Override
     public SequenceDefinition createDefinition(
-            IDefinitionScope definitionScope, String fieldName) {
-        SequenceDefinition ret = null;
-        try {
-            ret = new SequenceDefinition(this, definitionScope, fieldName);
-        } catch (CTFReaderException e) {
-            // Temporarily catch this here, eventually this should be thrown
-            // up the call stack
-            e.printStackTrace();
+            IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFReaderException {
+        Definition lenDef = null;
+
+        if (definitionScope != null) {
+            lenDef = definitionScope.lookupDefinition(getLengthName());
+        }
+
+        if (lenDef == null) {
+            throw new CTFReaderException("Sequence length field not found"); //$NON-NLS-1$
         }
-        return ret;
+
+        if (!(lenDef instanceof IntegerDefinition)) {
+            throw new CTFReaderException("Sequence length field not integer"); //$NON-NLS-1$
+        }
+
+        IntegerDefinition lengthDefinition = (IntegerDefinition) lenDef;
+
+        if (lengthDefinition.getDeclaration().isSigned()) {
+            throw new CTFReaderException("Sequence length must not be signed"); //$NON-NLS-1$
+        }
+
+        long length = lengthDefinition.getValue();
+        if ((length > Integer.MAX_VALUE) || (!input.canRead((int) length * fElemType.getMaximumSize()))) {
+            throw new CTFReaderException("Sequence length too long " + length); //$NON-NLS-1$
+        }
+
+        Collection<String> collection = fPaths.get(fieldName);
+        while (collection.size() < length) {
+            fPaths.put(fieldName, fieldName + '[' + collection.size() + ']');
+        }
+        List<String> paths = (List<String>) fPaths.get(fieldName);
+        Builder<Definition> definitions = new ImmutableList.Builder<>();
+        for (int i = 0; i < length; i++) {
+            definitions.add(fElemType.createDefinition(definitionScope, paths.get(i), input));
+        }
+        return new SequenceDefinition(this, definitionScope, fieldName, definitions.build());
     }
 
     @Override
@@ -99,4 +160,12 @@ public class SequenceDeclaration implements IDeclaration {
         return "[declaration] sequence[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
     }
 
+    /**
+     * @since 3.0
+     */
+    @Override
+    public int getMaximumSize() {
+        return Integer.MAX_VALUE;
+    }
+
 }
This page took 0.028621 seconds and 5 git commands to generate.