1 /*******************************************************************************
2 * Copyright (c) 2011-2013 Ericsson
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 * Alexendre Montplaisir - Initial API and implementation, extend TmfEventField
12 * Bernd Hufmann - Add Enum field handling
13 * Geneviève Bastien - Add support for Struct fields
14 *******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Arrays
;
20 import java
.util
.List
;
21 import java
.util
.Map
.Entry
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDeclaration
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDefinition
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.EnumDefinition
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.FloatDefinition
;
28 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDeclaration
;
29 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
30 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDeclaration
;
31 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDefinition
;
32 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StringDefinition
;
33 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDefinition
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventField
;
38 * The CTF implementation of the TMF event field model
41 * @author Matthew Khouzam
42 * @author Alexandre Montplaisir
44 public abstract class CtfTmfEventField
extends TmfEventField
{
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
51 protected static final int FIELDTYPE_INTEGER
= 0;
54 protected static final int FIELDTYPE_STRING
= 1;
57 protected static final int FIELDTYPE_INTEGER_ARRAY
= 2;
60 protected static final int FIELDTYPE_FLOAT
= 3;
63 protected static final int FIELDTYPE_ENUM
= 4;
66 protected static final int FIELDTYPE_STRUCT
= 5;
68 // ------------------------------------------------------------------------
70 // ------------------------------------------------------------------------
73 * Standard constructor. Only to be used internally, call parseField() to
74 * generate a new field object.
77 * The name of this field
79 * The value of this field. Its type should match the field type.
81 * The children fields. Useful for composite fields
84 protected CtfTmfEventField(String name
, Object value
, ITmfEventField
[] fields
) {
85 super(/* Strip the underscore from the field name if there is one */
86 name
.startsWith("_") ? name
.substring(1) : name
, //$NON-NLS-1$
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
96 * Factory method to instantiate CtfTmfEventField objects.
99 * The CTF Definition of this event field
101 * String The name to assign to this field
102 * @return The resulting CtfTmfEventField object
104 public static CtfTmfEventField
parseField(Definition fieldDef
,
106 CtfTmfEventField field
= null;
108 /* Determine the Definition type */
109 if (fieldDef
instanceof IntegerDefinition
) {
110 IntegerDefinition intDef
= (IntegerDefinition
) fieldDef
;
111 int base
= intDef
.getDeclaration().getBase();
112 field
= new CTFIntegerField(fieldName
, intDef
.getValue(), base
);
114 } else if (fieldDef
instanceof EnumDefinition
) {
115 EnumDefinition enumDef
= (EnumDefinition
) fieldDef
;
116 field
= new CTFEnumField(fieldName
, new CtfEnumPair(enumDef
.getValue(), enumDef
.getIntegerValue()));
118 } else if (fieldDef
instanceof StringDefinition
) {
119 field
= new CTFStringField(fieldName
, ((StringDefinition
) fieldDef
).getValue());
121 } else if (fieldDef
instanceof FloatDefinition
) {
122 FloatDefinition floatDef
= (FloatDefinition
) fieldDef
;
123 field
= new CTFFloatField(fieldName
, floatDef
.getValue());
125 } else if (fieldDef
instanceof ArrayDefinition
) {
126 ArrayDefinition arrayDef
= (ArrayDefinition
) fieldDef
;
127 ArrayDeclaration arrayDecl
= arrayDef
.getDeclaration();
129 if (arrayDef
.isString()) {
130 /* This is an array of UTF-8 bytes, a.k.a. a String! */
131 field
= new CTFStringField(fieldName
, fieldDef
.toString());
133 } else if (arrayDecl
.getElementType() instanceof IntegerDeclaration
) {
134 /* This is a an array of CTF Integers */
135 List
<Long
> values
= new ArrayList
<Long
>(arrayDecl
.getLength());
136 for (int i
= 0; i
< arrayDecl
.getLength(); i
++) {
137 values
.add(((IntegerDefinition
) arrayDef
.getElem(i
)).getValue());
139 field
= new CTFIntegerArrayField(fieldName
, values
);
141 /* Add other types of arrays here */
143 } else if (fieldDef
instanceof SequenceDefinition
) {
144 SequenceDefinition seqDef
= (SequenceDefinition
) fieldDef
;
145 SequenceDeclaration seqDecl
= seqDef
.getDeclaration();
147 if (seqDef
.getLength() == 0) {
148 /* Some sequences have length = 0. Simply use an empty string */
149 field
= new CTFStringField(fieldName
, ""); //$NON-NLS-1$
150 } else if (seqDef
.isString()) {
151 /* Interpret this sequence as a String */
152 field
= new CTFStringField(fieldName
, seqDef
.toString());
153 } else if (seqDecl
.getElementType() instanceof IntegerDeclaration
) {
154 /* Sequence of integers => CTFIntegerArrayField */
155 List
<Long
> values
= new ArrayList
<Long
>(seqDef
.getLength());
156 for (int i
= 0; i
< seqDef
.getLength(); i
++) {
157 values
.add(((IntegerDefinition
) seqDef
.getElem(i
)).getValue());
159 field
= new CTFIntegerArrayField(fieldName
, values
);
161 /* Add other Sequence types here */
163 } else if (fieldDef
instanceof StructDefinition
) {
164 StructDefinition strDef
= (StructDefinition
) fieldDef
;
166 String curFieldName
= null;
167 Definition curFieldDef
;
168 CtfTmfEventField curField
;
169 List
<ITmfEventField
> list
= new ArrayList
<ITmfEventField
>();
170 /* Recursively parse the fields */
171 for (Entry
<String
, Definition
> entry
: strDef
.getDefinitions().entrySet()) {
172 curFieldName
= entry
.getKey();
173 curFieldDef
= entry
.getValue();
174 curField
= CtfTmfEventField
.parseField(curFieldDef
, curFieldName
);
177 field
= new CTFStructField(fieldName
, list
.toArray(new CtfTmfEventField
[list
.size()]));
183 public String
toString() {
184 return getName() + '=' + getValue().toString();
187 // ------------------------------------------------------------------------
188 // Abstract methods (to be implemented by each specific field type)
189 // ------------------------------------------------------------------------
192 * Return the int representing this field's value type
194 * @return The field type
196 public abstract int getFieldType();
201 * The CTF field implementation for integer fields.
205 final class CTFIntegerField
extends CtfTmfEventField
{
207 private final int base
;
210 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
211 * Java parser this is interpreted as a long.
214 * The integer value of this field
216 * The name of this field
218 CTFIntegerField(String name
, long longValue
, int base
) {
219 super(name
, longValue
, null);
224 public int getFieldType() {
225 return FIELDTYPE_INTEGER
;
229 public Long
getValue() {
230 return (Long
) super.getValue();
234 * Custom-format the integer values depending on their base.
237 public String
toString() {
238 StringBuilder sb
= new StringBuilder(getName());
241 /* Format the number correctly according to the integer's base */
244 sb
.append("0b"); //$NON-NLS-1$
245 sb
.append(Long
.toBinaryString(getValue()));
249 sb
.append(Long
.toOctalString(getValue()));
252 sb
.append(getValue());
255 sb
.append("0x"); //$NON-NLS-1$
256 sb
.append(Long
.toHexString(getValue()));
259 /* Non-standard base, we'll just print it as a decimal number */
260 sb
.append(getValue().toString());
263 return sb
.toString();
268 * The CTF field implementation for string fields
272 final class CTFStringField
extends CtfTmfEventField
{
275 * Constructor for CTFStringField.
278 * The string value of this field
280 * The name of this field
282 CTFStringField(String name
, String strValue
) {
283 super(name
, strValue
, null);
287 public int getFieldType() {
288 return FIELDTYPE_STRING
;
292 public String
getValue() {
293 return (String
) super.getValue();
298 * CTF field implementation for arrays of integers.
302 final class CTFIntegerArrayField
extends CtfTmfEventField
{
305 * Constructor for CTFIntegerArrayField.
308 * The array of integers (as longs) that compose this field's
311 * The name of this field
313 CTFIntegerArrayField(String name
, List
<Long
> longValues
) {
314 super(name
, longValues
, null);
318 public int getFieldType() {
319 return FIELDTYPE_INTEGER_ARRAY
;
323 public List
<Long
> getValue() {
324 return (List
<Long
>) super.getValue();
329 * CTF field implementation for floats.
333 final class CTFFloatField
extends CtfTmfEventField
{
336 * Constructor for CTFFloatField.
339 * The float value (actually a double) of this field
341 * The name of this field
343 protected CTFFloatField(String name
, double value
) {
344 super(name
, value
, null);
348 public int getFieldType() {
349 return FIELDTYPE_FLOAT
;
353 public Double
getValue() {
354 return (Double
) super.getValue();
359 * The CTF field implementation for Enum fields
361 * @author Bernd Hufmann
363 final class CTFEnumField
extends CtfTmfEventField
{
366 * Constructor for CTFEnumField.
369 * The Enum value consisting of a pair of Enum value name and its long value
371 * The name of this field
373 CTFEnumField(String name
, CtfEnumPair enumValue
) {
374 super(name
, new CtfEnumPair(enumValue
.getFirst(),
375 enumValue
.getSecond().longValue()), null);
379 public int getFieldType() {
380 return FIELDTYPE_ENUM
;
384 public CtfEnumPair
getValue() {
385 return (CtfEnumPair
) super.getValue();
390 * The CTF field implementation for struct fields with sub-types
394 final class CTFStructField
extends CtfTmfEventField
{
397 * Constructor for CTFStringField.
400 * The string value of this field
402 * The name of this field
404 CTFStructField(String name
, CtfTmfEventField
[] fields
) {
405 super(name
, fields
, fields
);
409 public int getFieldType() {
410 return FIELDTYPE_STRUCT
;
414 public CtfTmfEventField
[] getValue() {
415 return (CtfTmfEventField
[]) super.getValue();
419 public String
toString() {
420 return getName() + '=' + Arrays
.toString(getValue());
424 /* Implement other possible fields types here... */