btf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / StructDeclaration.java
index 1772c9076b9ebc4c311aeb581ed6f83a26d0d56a..a356e8650ad8f395c9e7afcae9f5502d71a77d4c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
+ * Copyright (c) 2011, 2014 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.HashMap;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
+import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope;
+import org.eclipse.linuxtools.ctf.core.event.scope.LexicalScope;
+import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
 
 /**
- * <b><u>StructDeclaration</u></b>
+ * A CTF structure declaration.
+ *
+ * A structure is similar to a C structure, it is a compound data type that
+ * contains other datatypes in fields. they are stored in an hashmap and indexed
+ * by names which are strings.
+ *
+ * @version 1.0
+ * @author Matthew Khouzam
+ * @author Simon Marchi
  */
-public class StructDeclaration implements IDeclaration {
+public class StructDeclaration extends Declaration {
 
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
 
-    private final HashMap<String, IDeclaration> fields = new HashMap<String, IDeclaration>();
-    private final List<String> fieldsList = new LinkedList<String>();
-    private long maxAlign;
+    /** linked list of field names. So fieldName->fieldValue */
+    private final @NonNull Map<String, IDeclaration> fFieldMap = new LinkedHashMap<>();
+
+    /** maximum bit alignment */
+    private long fMaxAlign;
 
     // ------------------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------------------
 
+    /**
+     * The struct declaration, add fields later
+     *
+     * @param align
+     *            the minimum alignment of the struct. (if a struct is 8bit
+     *            aligned and has a 32 bit aligned field, the struct becomes 32
+     *            bit aligned.
+     */
     public StructDeclaration(long align) {
-        this.maxAlign = Math.max(align, 1);
+        fMaxAlign = Math.max(align, 1);
+    }
+
+    /**
+     * Struct declaration constructor
+     *
+     * @param names
+     *            the names of all the fields
+     * @param declarations
+     *            all the fields
+     * @since 3.0
+     */
+    public StructDeclaration(String[] names, Declaration[] declarations) {
+        fMaxAlign = 1;
+
+        for (int i = 0; i < names.length; i++) {
+            addField(names[i], declarations[i]);
+        }
     }
 
     // ------------------------------------------------------------------------
     // Getters/Setters/Predicates
     // ------------------------------------------------------------------------
 
+    /**
+     * Get current alignment
+     *
+     * @return the alignment of the struct and all its fields
+     */
     public long getMaxAlign() {
-        return maxAlign;
+        return fMaxAlign;
     }
 
+    /**
+     * Query if the struct has a given field
+     *
+     * @param name
+     *            the name of the field, scopeless please
+     * @return does the field exist?
+     */
     public boolean hasField(String name) {
-        return this.fields.containsKey(name);
+        return fFieldMap.containsKey(name);
+    }
+
+    /**
+     * Get the fields of the struct as a map.
+     *
+     * @return a Map of the fields (key is the name)
+     * @since 2.0
+     */
+    public Map<String, IDeclaration> getFields() {
+        return fFieldMap;
     }
 
-    public HashMap<String, IDeclaration> getFields() {
-        return this.fields;
+    /**
+     * Get the field declaration corresponding to a field name.
+     *
+     * @param fieldName
+     *            The field name
+     * @return The declaration of the field, or null if there is no such field.
+     * @since 3.1
+     */
+    @Nullable
+    public IDeclaration getField(String fieldName) {
+        return fFieldMap.get(fieldName);
     }
 
-    public List<String> getFieldsList() {
-        return this.fieldsList;
+    /**
+     * Gets the field list. Very important since the map of fields does not
+     * retain the order of the fields.
+     *
+     * @return the field list.
+     * @since 3.0
+     */
+    public Iterable<String> getFieldsList() {
+        return fFieldMap.keySet();
     }
 
     @Override
     public long getAlignment() {
-        return this.maxAlign;
+        return this.fMaxAlign;
     }
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public int getMaximumSize() {
+        int maxSize = 0;
+        for (IDeclaration field : fFieldMap.values()) {
+            maxSize += field.getMaximumSize();
+        }
+        return Math.min(maxSize, Integer.MAX_VALUE);
+    }
+
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * @since 3.0
+     */
     @Override
     public StructDefinition createDefinition(IDefinitionScope definitionScope,
-            String fieldName) {
-        return new StructDefinition(this, definitionScope, fieldName);
+            String fieldName, BitBuffer input) throws CTFReaderException {
+        alignRead(input);
+        final Definition[] myFields = new Definition[fFieldMap.size()];
+        StructDefinition structDefinition = new StructDefinition(this, definitionScope, fieldName, fFieldMap.keySet(), myFields);
+        fillStruct(input, myFields, structDefinition);
+        return structDefinition;
+    }
+
+    /**
+     * Create a definition from this declaration. This is a faster constructor
+     * as it has a lexical scope and this does not need to look it up.
+     *
+     * @param definitionScope
+     *            the definition scope, the parent where the definition will be
+     *            placed
+     * @param fieldScope
+     *            the scope of the definition
+     * @param input
+     *            a bitbuffer to read from
+     * @return a reference to the definition
+     * @throws CTFReaderException
+     *             error in reading
+     * @since 3.1
+     */
+    public StructDefinition createDefinition(IDefinitionScope definitionScope,
+            LexicalScope fieldScope, @NonNull BitBuffer input) throws CTFReaderException {
+        alignRead(input);
+        final Definition[] myFields = new Definition[fFieldMap.size()];
+        /*
+         * Key set is NOT null
+         */
+        @SuppressWarnings("null")
+        StructDefinition structDefinition = new StructDefinition(this, definitionScope, fieldScope, fieldScope.getName(), fFieldMap.keySet(), myFields);
+        fillStruct(input, myFields, structDefinition);
+        return structDefinition;
     }
 
+    /**
+     * Add a field to the struct
+     *
+     * @param name
+     *            the name of the field, scopeless
+     * @param declaration
+     *            the declaration of the field
+     */
     public void addField(String name, IDeclaration declaration) {
-        this.fields.put(name, declaration);
-        this.fieldsList.add(name);
-        maxAlign = Math.max(maxAlign, declaration.getAlignment());
-        if( maxAlign == 1 )
-        {
-            maxAlign =1;
+        fFieldMap.put(name, declaration);
+        fMaxAlign = Math.max(fMaxAlign, declaration.getAlignment());
+    }
+
+    @SuppressWarnings("null")
+    private void fillStruct(@NonNull BitBuffer input, final Definition[] myFields, StructDefinition structDefinition) throws CTFReaderException {
+        Iterator<Map.Entry<String, IDeclaration>> iter = fFieldMap.entrySet().iterator();
+        for (int i = 0; i < fFieldMap.size(); i++) {
+            Map.Entry<String, IDeclaration> entry = iter.next();
+            myFields[i] = entry.getValue().createDefinition(structDefinition, entry.getKey(), input);
         }
     }
 
@@ -87,22 +228,15 @@ public class StructDeclaration implements IDeclaration {
         return "[declaration] struct[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
     }
 
-    /* (non-Javadoc)
-     * @see java.lang.Object#hashCode()
-     */
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = (prime * result)
-                + ((fieldsList == null) ? 0 : fieldsList.hashCode());
-        result = (prime * result) + (int) (maxAlign ^ (maxAlign >>> 32));
+        result = (prime * result) + fFieldMap.entrySet().hashCode();
+        result = (prime * result) + (int) (fMaxAlign ^ (fMaxAlign >>> 32));
         return result;
     }
 
-    /* (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -115,14 +249,10 @@ public class StructDeclaration implements IDeclaration {
             return false;
         }
         StructDeclaration other = (StructDeclaration) obj;
-        if (fieldsList == null) {
-            if (other.fieldsList != null) {
-                return false;
-            }
-        } else if (!fieldsList.equals(other.fieldsList)) {
+        if (!fFieldMap.entrySet().equals(other.fFieldMap.entrySet())) {
             return false;
         }
-        if (maxAlign != other.maxAlign) {
+        if (fMaxAlign != other.fMaxAlign) {
             return false;
         }
         return true;
This page took 0.028141 seconds and 5 git commands to generate.