/*******************************************************************************
- * Copyright (c) 2011, 2013 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
* Bernd Hufmann - Add Enum field handling
* Geneviève Bastien - Add Struct and Variant field handling
* Jean-Christian Kouame - Correct handling of unsigned integer fields
+ * François Doray - Add generic array field type
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.ctfadaptor;
-import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
-import org.eclipse.linuxtools.ctf.core.event.types.ArrayDeclaration;
import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.Definition;
import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition;
} else if (fieldDef instanceof ArrayDefinition) {
ArrayDefinition arrayDef = (ArrayDefinition) fieldDef;
- ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
- if (arrayDef.isString()) {
+ if (arrayDef.getDeclaration().isString()) {
/* This is an array of UTF-8 bytes, a.k.a. a String! */
field = new CTFStringField(fieldName, fieldDef.toString());
- } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
- /* This is a an array of CTF Integers */
- List<Long> values = new ArrayList<Long>(arrayDecl.getLength());
- for (int i = 0; i < arrayDecl.getLength(); i++) {
- values.add(((IntegerDefinition) arrayDef.getElem(i)).getValue());
+ } else {
+ /* Arrays of elements of any other type */
+ Definition[] definitions = arrayDef.getDefinitions();
+ CtfTmfEventField[] elements = new CtfTmfEventField[definitions.length];
+
+ /* Parse the elements of the array. */
+ for (int i = 0; i < definitions.length; i++) {
+ CtfTmfEventField curField = CtfTmfEventField.parseField(
+ definitions[i], fieldName + '[' + i + ']');
+ elements[i] = curField;
}
- long[] valuesArray = convertListToArray(values);
- field = new CTFIntegerArrayField(fieldName, valuesArray,
- ((IntegerDeclaration) arrayDecl.getElementType()).getBase(),
- ((IntegerDeclaration) arrayDecl.getElementType()).isSigned());
- }
- /* Add other types of arrays here */
+ field = new CTFArrayField(fieldName, elements);
+ }
} else if (fieldDef instanceof SequenceDefinition) {
SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
SequenceDeclaration seqDecl = seqDef.getDeclaration();
field = new CTFStringField(fieldName, seqDef.toString());
} else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
/* Sequence of integers => CTFIntegerArrayField */
- List<Long> values = new ArrayList<Long>(seqDef.getLength());
+ long[] values = new long[seqDef.getLength()];
for (int i = 0; i < seqDef.getLength(); i++) {
- values.add(((IntegerDefinition) seqDef.getElem(i)).getValue());
+ values[i] = ((IntegerDefinition) seqDef.getElem(i)).getValue();
}
- long[] valuesArray = convertListToArray(values);
- field = new CTFIntegerArrayField(fieldName, valuesArray,
+ field = new CTFIntegerArrayField(fieldName, values,
((IntegerDeclaration) seqDecl.getElementType()).getBase(),
((IntegerDeclaration) seqDecl.getElementType()).isSigned());
+
}
/* Add other Sequence types here */
String curFieldName = null;
Definition curFieldDef;
CtfTmfEventField curField;
- List<ITmfEventField> list = new ArrayList<ITmfEventField>();
+ List<ITmfEventField> list = new ArrayList<>();
/* Recursively parse the fields */
for (Entry<String, Definition> entry : strDef.getDefinitions().entrySet()) {
curFieldName = entry.getKey();
return getName() + '=' + getFormattedValue();
}
- /**
- * Print a numeric value as a string in a given base
- *
- * @param value
- * The value to print as string
- * @param base
- * The base for this value
- * @param signed
- * Is the value signed or not
- * @return formatted number string
- * @since 2.0
- */
- public final static String formatNumber(long value, int base, boolean signed) {
- String s;
-
- /* Format the number correctly according to the integer's base */
- switch (base) {
- case 2:
- s = "0b" + Long.toBinaryString(value); //$NON-NLS-1$
- break;
- case 8:
- s = "0" + Long.toOctalString(value); //$NON-NLS-1$
-
- break;
- case 16:
- s = "0x" + Long.toHexString(value); //$NON-NLS-1$
- break;
- case 10:
- default:
- /* For non-standard base, we'll just print it as a decimal number */
- if (!signed && value < 0) {
- /* Since there are no 'unsigned long', handle this case with BigInteger */
- BigInteger bigInteger = BigInteger.valueOf(value);
- /*
- * powerOfTwo = 2^64 we add 2^64 to the negative number to get
- * the real unsigned value
- */
- BigInteger powerOfTwo = (BigInteger.valueOf(Long.MAX_VALUE)).add(BigInteger.valueOf(1));
- powerOfTwo = powerOfTwo.multiply(BigInteger.valueOf(2));
- bigInteger = bigInteger.add(powerOfTwo);
-
- s = bigInteger.toString();
- } else {
- s = Long.toString(value);
- }
- break;
- }
- return s;
- }
-
- /**
- * We cannot use List.toArray(T[]) for primitives types, so do it manually.
- */
- private static long[] convertListToArray(List<Long> list) {
- long[] array = new long[list.size()];
- for (int i = 0; i < list.size(); i++) {
- array[i] = list.get(i);
- }
- return array;
- }
-
}
/**
*/
final class CTFIntegerField extends CtfTmfEventField {
- private final int base;
- private final boolean signed;
+ private final int fBase;
+ private final boolean fSigned;
/**
* A CTF "IntegerDefinition" can be an integer of any byte size, so in the
*/
CTFIntegerField(String name, long longValue, int base, boolean signed) {
super(name, longValue, null);
- this.signed = signed;
- this.base = base;
+ fSigned = signed;
+ fBase = base;
}
@Override
@Override
public String getFormattedValue() {
- return formatNumber(getValue(), base, signed);
+ return IntegerDefinition.formatNumber(getValue(), fBase, fSigned);
}
}
*/
final class CTFIntegerArrayField extends CtfTmfEventField {
- private final int base;
- private final boolean signed;
- private String formattedValue = null;
+ private final int fBase;
+ private final boolean fSigned;
+ private String fFormattedValue = null;
/**
* Constructor for CTFIntegerArrayField.
*/
CTFIntegerArrayField(String name, long[] longValues, int base, boolean signed) {
super(name, longValues, null);
- this.base = base;
- this.signed = signed;
+ fBase = base;
+ fSigned = signed;
}
@Override
}
@Override
- public String getFormattedValue() {
- if (formattedValue == null) {
- List<String> strings = new ArrayList<String>();
+ public synchronized String getFormattedValue() {
+ if (fFormattedValue == null) {
+ List<String> strings = new ArrayList<>();
for (long value : getValue()) {
- strings.add(formatNumber(value, base, signed));
+ strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned));
}
- formattedValue = strings.toString();
+ fFormattedValue = strings.toString();
}
- return formattedValue;
+ return fFormattedValue;
}
}
+/**
+ * CTF field implementation for arrays of arbitrary types.
+ *
+ * @author fdoray
+ */
+final class CTFArrayField extends CtfTmfEventField {
+
+ private String fFormattedValue = null;
+
+ /**
+ * Constructor for CTFArrayField.
+ *
+ * @param name
+ * The name of this field
+ * @param elements
+ * The array elements of this field
+ */
+ CTFArrayField(String name, CtfTmfEventField[] elements) {
+ super(name, elements, elements);
+ }
+
+ @Override
+ public CtfTmfEventField[] getValue() {
+ return (CtfTmfEventField[]) super.getValue();
+ }
+
+ @Override
+ public synchronized String getFormattedValue() {
+ if (fFormattedValue == null) {
+ List<String> strings = new ArrayList<>();
+ for (CtfTmfEventField element : getValue()) {
+ strings.add(element.getFormattedValue());
+ }
+ fFormattedValue = strings.toString();
+ }
+ return fFormattedValue;
+ }
+}
+
/**
* CTF field implementation for floats.
*
*/
CTFEnumField(String name, CtfEnumPair enumValue) {
super(name, new CtfEnumPair(enumValue.getFirst(),
- enumValue.getSecond().longValue()), null);
+ enumValue.getSecond()), null);
}
@Override