X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=org.eclipse.linuxtools.ctf.core%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Fctf%2Fcore%2Fevent%2Ftypes%2FArrayDeclaration.java;h=d0d9691c8d4d905a73bb252482bc2b4d9981c9d5;hb=a4fa4e3606484778f4ea4ba3e42944c4c78430b2;hp=30730c7607c81dfd9b15db8bec5e74bab723cd20;hpb=941b76a5e23185d063b1697a0a5dfc73e6771c7b;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/ArrayDeclaration.java b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/ArrayDeclaration.java index 30730c7607..d0d9691c8d 100644 --- a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/ArrayDeclaration.java +++ b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/ArrayDeclaration.java @@ -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 @@ -12,47 +12,128 @@ 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; + /** - * ArrayDeclaration + * 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; + + /** + *
+     * Cache where we can pre-generate the children names
+     * Key: parent name
+     * Value: children names
+     * ex: field → {field[0], field[1], … field[n]}
+     * 
+ * + * TODO: investigate performance + */ + private final Multimap fChildrenNames = ArrayListMultimap. 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 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 read(@NonNull BitBuffer input, IDefinitionScope definitionScope, String fieldName) throws CTFReaderException { + Builder definitions = new ImmutableList.Builder<>(); + if (!fChildrenNames.containsKey(fieldName)) { + for (int i = 0; i < fLength; i++) { + fChildrenNames.put(fieldName, fieldName + '[' + i + ']'); + } + } + List elemNames = (List) 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 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); + } + }