1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 Ericsson, École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Matthew Khouzam - Initial API and implementation
11 * Alexandre Montplaisir - Initial API and implementation, extend TmfEventField
12 * Bernd Hufmann - Add Enum field handling
13 * Geneviève Bastien - Add Struct and Variant field handling
14 * Jean-Christian Kouame - Correct handling of unsigned integer fields
15 *******************************************************************************/
17 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Arrays
;
21 import java
.util
.List
;
22 import java
.util
.Map
.Entry
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDeclaration
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDefinition
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.EnumDefinition
;
28 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.FloatDefinition
;
29 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDeclaration
;
30 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
31 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDeclaration
;
32 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDefinition
;
33 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StringDefinition
;
34 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDefinition
;
35 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.VariantDefinition
;
36 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.Messages
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventField
;
41 * The CTF implementation of the TMF event field model
44 * @author Matthew Khouzam
45 * @author Alexandre Montplaisir
47 public abstract class CtfTmfEventField
extends TmfEventField
{
49 // ------------------------------------------------------------------------
51 // ------------------------------------------------------------------------
54 * Standard constructor. Only to be used internally, call parseField() to
55 * generate a new field object.
58 * The name of this field
60 * The value of this field. Its type should match the field type.
62 * The children fields. Useful for composite fields
65 protected CtfTmfEventField(String name
, Object value
, ITmfEventField
[] fields
) {
66 super(/* Strip the underscore from the field name if there is one */
67 name
.startsWith("_") ? name
.substring(1) : name
, //$NON-NLS-1$
72 // ------------------------------------------------------------------------
74 // ------------------------------------------------------------------------
77 * Factory method to instantiate CtfTmfEventField objects.
80 * The CTF Definition of this event field
82 * String The name to assign to this field
83 * @return The resulting CtfTmfEventField object
85 public static CtfTmfEventField
parseField(Definition fieldDef
,
87 CtfTmfEventField field
= null;
89 /* Determine the Definition type */
90 if (fieldDef
instanceof IntegerDefinition
) {
91 IntegerDefinition intDef
= (IntegerDefinition
) fieldDef
;
92 int base
= intDef
.getDeclaration().getBase();
93 field
= new CTFIntegerField(fieldName
, intDef
.getValue(), base
, intDef
.getDeclaration().isSigned());
95 } else if (fieldDef
instanceof EnumDefinition
) {
96 EnumDefinition enumDef
= (EnumDefinition
) fieldDef
;
97 field
= new CTFEnumField(fieldName
, new CtfEnumPair(enumDef
.getValue(), enumDef
.getIntegerValue()));
99 } else if (fieldDef
instanceof StringDefinition
) {
100 field
= new CTFStringField(fieldName
, ((StringDefinition
) fieldDef
).getValue());
102 } else if (fieldDef
instanceof FloatDefinition
) {
103 FloatDefinition floatDef
= (FloatDefinition
) fieldDef
;
104 field
= new CTFFloatField(fieldName
, floatDef
.getValue());
106 } else if (fieldDef
instanceof ArrayDefinition
) {
107 ArrayDefinition arrayDef
= (ArrayDefinition
) fieldDef
;
108 ArrayDeclaration arrayDecl
= arrayDef
.getDeclaration();
110 if (arrayDef
.isString()) {
111 /* This is an array of UTF-8 bytes, a.k.a. a String! */
112 field
= new CTFStringField(fieldName
, fieldDef
.toString());
114 } else if (arrayDecl
.getElementType() instanceof IntegerDeclaration
) {
115 /* This is a an array of CTF Integers */
116 List
<Long
> values
= new ArrayList
<Long
>(arrayDecl
.getLength());
117 for (int i
= 0; i
< arrayDecl
.getLength(); i
++) {
118 values
.add(((IntegerDefinition
) arrayDef
.getElem(i
)).getValue());
120 field
= new CTFIntegerArrayField(fieldName
, values
, ((IntegerDeclaration
) arrayDecl
.getElementType()).getBase(),
121 ((IntegerDeclaration
) arrayDecl
.getElementType()).isSigned());
123 /* Add other types of arrays here */
125 } else if (fieldDef
instanceof SequenceDefinition
) {
126 SequenceDefinition seqDef
= (SequenceDefinition
) fieldDef
;
127 SequenceDeclaration seqDecl
= seqDef
.getDeclaration();
129 if (seqDef
.getLength() == 0) {
130 /* Some sequences have length = 0. Simply use an empty string */
131 field
= new CTFStringField(fieldName
, ""); //$NON-NLS-1$
132 } else if (seqDef
.isString()) {
133 /* Interpret this sequence as a String */
134 field
= new CTFStringField(fieldName
, seqDef
.toString());
135 } else if (seqDecl
.getElementType() instanceof IntegerDeclaration
) {
136 /* Sequence of integers => CTFIntegerArrayField */
137 List
<Long
> values
= new ArrayList
<Long
>(seqDef
.getLength());
138 for (int i
= 0; i
< seqDef
.getLength(); i
++) {
139 values
.add(((IntegerDefinition
) seqDef
.getElem(i
)).getValue());
141 field
= new CTFIntegerArrayField(fieldName
, values
, ((IntegerDeclaration
) seqDecl
.getElementType()).getBase(),
142 ((IntegerDeclaration
) seqDecl
.getElementType()).isSigned());
144 /* Add other Sequence types here */
146 } else if (fieldDef
instanceof StructDefinition
) {
147 StructDefinition strDef
= (StructDefinition
) fieldDef
;
149 String curFieldName
= null;
150 Definition curFieldDef
;
151 CtfTmfEventField curField
;
152 List
<ITmfEventField
> list
= new ArrayList
<ITmfEventField
>();
153 /* Recursively parse the fields */
154 for (Entry
<String
, Definition
> entry
: strDef
.getDefinitions().entrySet()) {
155 curFieldName
= entry
.getKey();
156 curFieldDef
= entry
.getValue();
157 curField
= CtfTmfEventField
.parseField(curFieldDef
, curFieldName
);
160 field
= new CTFStructField(fieldName
, list
.toArray(new CtfTmfEventField
[list
.size()]));
162 } else if (fieldDef
instanceof VariantDefinition
) {
163 VariantDefinition varDef
= (VariantDefinition
) fieldDef
;
165 String curFieldName
= varDef
.getCurrentFieldName();
166 Definition curFieldDef
= varDef
.getDefinitions().get(curFieldName
);
167 if (curFieldDef
!= null) {
168 CtfTmfEventField subField
= CtfTmfEventField
.parseField(curFieldDef
, curFieldName
);
169 field
= new CTFVariantField(fieldName
, subField
);
171 /* A safe-guard, but curFieldDef should never be null */
172 field
= new CTFStringField(curFieldName
, ""); //$NON-NLS-1$
177 * Safe-guard, to avoid null exceptions later, field is expected not
180 field
= new CTFStringField(fieldName
, Messages
.TmfEventField_UnsupportedType
+ fieldDef
.getClass().toString());
186 public String
toString() {
187 return getName() + '=' + getFormattedValue();
192 * The CTF field implementation for integer fields.
196 final class CTFIntegerField
extends CtfTmfEventField
{
198 private final int base
;
199 private final boolean signed
;
202 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
203 * Java parser this is interpreted as a long.
206 * The name of this field
208 * The integer value of this field
210 * Is the value signed or not
212 CTFIntegerField(String name
, long longValue
, int base
, boolean signed
) {
213 super(name
, longValue
, null);
214 this.signed
= signed
;
219 public Long
getValue() {
220 return (Long
) super.getValue();
224 public String
getFormattedValue() {
225 return IntegerDefinition
.formatNumber(getValue(), base
, signed
);
231 * The CTF field implementation for string fields
235 final class CTFStringField
extends CtfTmfEventField
{
238 * Constructor for CTFStringField.
241 * The string value of this field
243 * The name of this field
245 CTFStringField(String name
, String strValue
) {
246 super(name
, strValue
, null);
250 public String
getValue() {
251 return (String
) super.getValue();
256 * CTF field implementation for arrays of integers.
260 final class CTFIntegerArrayField
extends CtfTmfEventField
{
262 private final int base
;
263 private final boolean signed
;
264 private String formattedValue
= null;
267 * Constructor for CTFIntegerArrayField.
270 * The name of this field
272 * The array of integers (as longs) that compose this field's
275 * Are the values in the array signed or not
277 CTFIntegerArrayField(String name
, List
<Long
> longValues
, int base
, boolean signed
) {
278 super(name
, longValues
, null);
280 this.signed
= signed
;
284 public List
<Long
> getValue() {
285 return (List
<Long
>) super.getValue();
289 public String
getFormattedValue() {
290 if (formattedValue
== null) {
291 List
<String
> strings
= new ArrayList
<String
>();
292 for (Long value
: getValue()) {
293 strings
.add(IntegerDefinition
.formatNumber(value
, base
, signed
));
295 formattedValue
= strings
.toString();
297 return formattedValue
;
303 * CTF field implementation for floats.
307 final class CTFFloatField
extends CtfTmfEventField
{
310 * Constructor for CTFFloatField.
313 * The float value (actually a double) of this field
315 * The name of this field
317 protected CTFFloatField(String name
, double value
) {
318 super(name
, value
, null);
322 public Double
getValue() {
323 return (Double
) super.getValue();
328 * The CTF field implementation for Enum fields
330 * @author Bernd Hufmann
332 final class CTFEnumField
extends CtfTmfEventField
{
335 * Constructor for CTFEnumField.
338 * The Enum value consisting of a pair of Enum value name and its
341 * The name of this field
343 CTFEnumField(String name
, CtfEnumPair enumValue
) {
344 super(name
, new CtfEnumPair(enumValue
.getFirst(),
345 enumValue
.getSecond().longValue()), null);
349 public CtfEnumPair
getValue() {
350 return (CtfEnumPair
) super.getValue();
355 * The CTF field implementation for struct fields with sub-fields
359 final class CTFStructField
extends CtfTmfEventField
{
362 * Constructor for CTFStructField.
365 * The children of this field
367 * The name of this field
369 CTFStructField(String name
, CtfTmfEventField
[] fields
) {
370 super(name
, fields
, fields
);
374 public CtfTmfEventField
[] getValue() {
375 return (CtfTmfEventField
[]) super.getValue();
379 public String
getFormattedValue() {
380 return Arrays
.toString(getValue());
386 * The CTF field implementation for variant fields its child
390 final class CTFVariantField
extends CtfTmfEventField
{
393 * Constructor for CTFVariantField.
396 * The field selected for this variant
398 * The name of this field
400 CTFVariantField(String name
, CtfTmfEventField field
) {
401 super(name
, field
, new CtfTmfEventField
[] { field
});
405 public CtfTmfEventField
getValue() {
406 return (CtfTmfEventField
) super.getValue();
411 /* Implement other possible fields types here... */