ctf: Make events immutable
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / ArrayDeclaration.java
index 30730c7607c81dfd9b15db8bec5e74bab723cd20..d0d9691c8d4d905a73bb252482bc2b4d9981c9d5 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
 
 package org.eclipse.linuxtools.ctf.core.event.types;
 
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+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;
+
 /**
- * <b><u>ArrayDeclaration</u></b>
+ * A CTF array declaration
+ *
+ * Arrays are fixed-length. Their length is declared in the type declaration
+ * within the meta-data. They contain an array of "inner type" elements, which
+ * can refer to any type not containing the type of the array being declared (no
+ * circular dependency). The length is the number of elements in an array.
+ *
+ * @version 1.0
+ * @author Matthew Khouzam
+ * @author Simon Marchi
  */
-public class ArrayDeclaration implements IDeclaration {
+public class ArrayDeclaration extends Declaration {
 
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
 
-    private final int length;
-    private final IDeclaration elemType;
+    private final int fLength;
+    private final IDeclaration fElemType;
+
+    /**
+     * <pre>
+     * Cache where we can pre-generate the children names
+     * Key&colon; parent name
+     * Value&colon; children names
+     * ex: field &#8594; &lbrace;field&lbrack;0&rbrack;, field&lbrack;1&rbrack;, &hellip; field&lbrack;n&rbrack;&rbrace;
+     * </pre>
+     *
+     * TODO: investigate performance
+     */
+    private final Multimap<String, String> fChildrenNames = ArrayListMultimap.<String, String> create();
 
     // ------------------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------------------
 
+    /**
+     * Constructor
+     *
+     * @param length
+     *            how many elements in the array
+     * @param elemType
+     *            what type of element is in the array
+     */
     public ArrayDeclaration(int length, IDeclaration elemType) {
-        this.length = length;
-        this.elemType = elemType;
+        fLength = length;
+        fElemType = elemType;
     }
 
     // ------------------------------------------------------------------------
     // Getters/Setters/Predicates
     // ------------------------------------------------------------------------
 
+    /**
+     *
+     * @return the type of element in the array
+     */
     public IDeclaration getElementType() {
-        return elemType;
+        return fElemType;
     }
 
+    /**
+     *
+     * @return how many elements in the array
+     */
     public int getLength() {
-        return length;
+        return fLength;
+    }
+
+    /**
+     * Sometimes, strings are encoded as an array of 1-byte integers (each one
+     * being an UTF-8 byte).
+     *
+     * @return true if this array is in fact an UTF-8 string. false if it's a
+     *         "normal" array of generic Definition's.
+     * @since 3.0
+     */
+    public boolean isString() {
+        if (fElemType instanceof IntegerDeclaration) {
+            /*
+             * If the first byte is a "character", we'll consider the whole
+             * array a character string.
+             */
+            IntegerDeclaration elemInt = (IntegerDeclaration) fElemType;
+            if (elemInt.isCharacter()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public long getAlignment() {
+        return getElementType().getAlignment();
     }
 
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * @since 3.0
+     */
     @Override
     public ArrayDefinition createDefinition(IDefinitionScope definitionScope,
-            String fieldName) {
-        return new ArrayDefinition(this, definitionScope, fieldName);
+            @NonNull String fieldName, BitBuffer input) throws CTFReaderException {
+        alignRead(input);
+        List<Definition> definitions = read(input, definitionScope, fieldName);
+        return new ArrayDefinition(this, definitionScope, fieldName, definitions);
     }
 
     @Override
@@ -61,4 +142,34 @@ public class ArrayDeclaration implements IDeclaration {
         return "[declaration] array[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
     }
 
+    @NonNull
+    private List<Definition> read(@NonNull BitBuffer input, IDefinitionScope definitionScope, String fieldName) throws CTFReaderException {
+        Builder<Definition> definitions = new ImmutableList.Builder<>();
+        if (!fChildrenNames.containsKey(fieldName)) {
+            for (int i = 0; i < fLength; i++) {
+                fChildrenNames.put(fieldName, fieldName + '[' + i + ']');
+            }
+        }
+        List<String> elemNames = (List<String>) fChildrenNames.get(fieldName);
+        for (int i = 0; i < fLength; i++) {
+            String name = elemNames.get(i);
+            if (name == null) {
+                throw new IllegalStateException();
+            }
+            definitions.add(fElemType.createDefinition(definitionScope, name, input));
+        }
+        @SuppressWarnings("null")
+        @NonNull ImmutableList<Definition> ret = definitions.build();
+        return ret;
+    }
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public int getMaximumSize() {
+        long val = (long) fLength * fElemType.getMaximumSize();
+        return (int) Math.min(Integer.MAX_VALUE, val);
+    }
+
 }
This page took 0.027186 seconds and 5 git commands to generate.