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.
*
* @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
* The element type
*/
public SequenceDeclaration(String lengthName, IDeclaration elemType) {
- this.elemType = elemType;
- this.lengthName = lengthName;
+ fElemType = elemType;
+ fLengthName = lengthName;
}
// ------------------------------------------------------------------------
/**
* 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
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
return "[declaration] sequence[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
}
+ /**
+ * @since 3.0
+ */
+ @Override
+ public int getMaximumSize() {
+ return Integer.MAX_VALUE;
+ }
+
}