1 /*******************************************************************************
2 * Copyright (c) 2011 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
12 * Bernd Hufmann - Add Enum field handling
14 *******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDeclaration
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDefinition
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.EnumDefinition
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.FloatDefinition
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDeclaration
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
28 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDeclaration
;
29 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDefinition
;
30 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StringDefinition
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
34 * The CTF implementation of the TMF event field model
37 * @author Matthew Khouzam
38 * @author Alexandre Montplaisir
40 public abstract class CtfTmfEventField
implements ITmfEventField
{
42 // ------------------------------------------------------------------------
44 // ------------------------------------------------------------------------
47 protected static final int FIELDTYPE_INTEGER
= 0;
50 protected static final int FIELDTYPE_STRING
= 1;
53 protected static final int FIELDTYPE_INTEGER_ARRAY
= 2;
56 protected static final int FIELDTYPE_FLOAT
= 3;
59 protected static final int FIELDTYPE_ENUM
= 4;
61 // ------------------------------------------------------------------------
63 // ------------------------------------------------------------------------
65 /** The name of this field */
66 protected final String name
;
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 protected CtfTmfEventField(String name
) {
80 /* Strip the underscore */
81 if (name
.startsWith("_")) { //$NON-NLS-1$
82 this.name
= name
.substring(1);
88 // ------------------------------------------------------------------------
89 // Getters/Setters/Predicates
90 // ------------------------------------------------------------------------
93 public String
getName() {
97 // ------------------------------------------------------------------------
99 // ------------------------------------------------------------------------
102 * Factory method to instantiate CtfTmfEventField objects.
105 * The CTF Definition of this event field
107 * String The name to assign to this field
108 * @return The resulting CtfTmfEventField object
110 public static CtfTmfEventField
parseField(Definition fieldDef
,
112 CtfTmfEventField field
= null;
114 /* Determine the Definition type */
115 if (fieldDef
instanceof IntegerDefinition
) {
116 IntegerDefinition intDef
= (IntegerDefinition
) fieldDef
;
117 int base
= intDef
.getDeclaration().getBase();
118 field
= new CTFIntegerField(intDef
.getValue(), fieldName
, base
);
120 } else if (fieldDef
instanceof EnumDefinition
) {
121 EnumDefinition enumDef
= (EnumDefinition
) fieldDef
;
122 field
= new CTFEnumField(new CtfEnumPair(enumDef
.getValue(), enumDef
.getIntegerValue()), fieldName
);
124 } else if (fieldDef
instanceof StringDefinition
) {
125 field
= new CTFStringField(
126 ((StringDefinition
) fieldDef
).getValue(), fieldName
);
128 } else if (fieldDef
instanceof ArrayDefinition
) {
129 ArrayDefinition arrayDef
= (ArrayDefinition
) fieldDef
;
130 ArrayDeclaration arrayDecl
= arrayDef
.getDeclaration();
132 if (arrayDef
.isString()) {
133 /* This is an array of UTF-8 bytes, a.k.a. a String! */
134 field
= new CTFStringField(fieldDef
.toString(), fieldName
);
136 } else if (arrayDecl
.getElementType() instanceof IntegerDeclaration
) {
137 /* This is a an array of CTF Integers */
138 long[] values
= new long[arrayDecl
.getLength()];
139 for (int i
= 0; i
< arrayDecl
.getLength(); i
++) {
140 values
[i
] = ((IntegerDefinition
) arrayDef
.getElem(i
))
143 field
= new CTFIntegerArrayField(values
, fieldName
);
145 /* Add other types of arrays here */
147 } else if (fieldDef
instanceof SequenceDefinition
) {
148 SequenceDefinition seqDef
= (SequenceDefinition
) fieldDef
;
149 SequenceDeclaration seqDecl
= seqDef
.getDeclaration();
151 if (seqDef
.getLength() == 0) {
152 /* Some sequences have length = 0. Simply use an empty string */
153 field
= new CTFStringField("", fieldName
); //$NON-NLS-1$
154 } else if (seqDef
.isString()) {
155 /* Interpret this sequence as a String */
156 field
= new CTFStringField(seqDef
.toString(), fieldName
);
157 } else if (seqDecl
.getElementType() instanceof IntegerDeclaration
) {
158 /* Sequence of integers => CTFIntegerArrayField */
159 long[] values
= new long[seqDef
.getLength()];
160 for (int i
= 0; i
< seqDef
.getLength(); i
++) {
161 values
[i
] = ((IntegerDefinition
) seqDef
.getElem(i
))
164 field
= new CTFIntegerArrayField(values
, fieldName
);
166 /* Add other Sequence types here */
168 } else if (fieldDef
instanceof FloatDefinition
) {
169 FloatDefinition floatDef
= (FloatDefinition
) fieldDef
;
170 field
= new CTFFloatField(floatDef
.getValue(), fieldName
);
177 * Copy factory. Create a new field by (deep-) copying the information in an
181 * The other CtfTmfEventField to copy
182 * @return The new CtfTmfEventField
184 public static CtfTmfEventField
copyFrom(CtfTmfEventField other
) {
185 switch (other
.getFieldType()) {
186 case FIELDTYPE_INTEGER
:
187 CTFIntegerField intOther
= (CTFIntegerField
) other
;
188 return new CTFIntegerField(intOther
.getValue(), intOther
.name
,
190 case FIELDTYPE_STRING
:
191 return new CTFStringField(((CTFStringField
) other
).getValue(),
193 case FIELDTYPE_INTEGER_ARRAY
:
194 return new CTFIntegerArrayField(
195 ((CTFIntegerArrayField
) other
).getLongValues(), other
.name
);
196 case FIELDTYPE_FLOAT
:
197 return new CTFFloatField(((CTFFloatField
) other
).getValue(),
200 return new CTFEnumField(((CTFEnumField
) other
).getValue(), other
.name
);
207 public CtfTmfEventField
clone() {
208 return CtfTmfEventField
.copyFrom(this);
211 // ------------------------------------------------------------------------
212 // Abstract methods (to be implemented by each specific field type)
213 // ------------------------------------------------------------------------
216 * Return the int representing this field's value type
218 * @return The field type
220 public abstract int getFieldType();
223 * Return this field's value. You can cast it to the correct type depending
224 * on what getFieldType says.
226 * @return The field's value
229 public abstract Object
getValue();
231 // ------------------------------------------------------------------------
232 // Other methods defined by ITmfEventField, but not used here.
233 // CTF fields do not have sub-fields (yet!)
234 // ------------------------------------------------------------------------
237 public String
[] getFieldNames() {
242 public String
getFieldName(int index
) {
247 public ITmfEventField
[] getFields() {
252 public ITmfEventField
getField(String fieldName
) {
257 public ITmfEventField
getField(int index
) {
263 * The CTF field implementation for integer fields.
267 final class CTFIntegerField
extends CtfTmfEventField
{
269 private final long longValue
;
270 private final int base
;
273 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
274 * Java parser this is interpreted as a long.
277 * The integer value of this field
279 * The name of this field
281 CTFIntegerField(long longValue
, String name
, int base
) {
283 this.longValue
= longValue
;
288 * Return the integer's base. (Not made public until it's needed.)
290 * @return The base, usually 10 or 16.
297 public int getFieldType() {
298 return FIELDTYPE_INTEGER
;
302 public Long
getValue() {
303 return this.longValue
;
307 public String
toString() {
308 StringBuilder sb
= new StringBuilder(name
);
311 /* Format the number correctly according to the integer's base */
314 sb
.append("0b"); //$NON-NLS-1$
315 sb
.append(Long
.toBinaryString(longValue
));
319 sb
.append(Long
.toOctalString(longValue
));
322 sb
.append(longValue
);
325 sb
.append("0x"); //$NON-NLS-1$
326 sb
.append(Long
.toHexString(longValue
));
329 /* Non-standard base, we'll just print it as a decimal number */
330 sb
.append(longValue
);
333 return sb
.toString();
338 * The CTF field implementation for string fields
342 final class CTFStringField
extends CtfTmfEventField
{
344 private final String strValue
;
347 * Constructor for CTFStringField.
350 * The string value of this field
352 * The name of this field
354 CTFStringField(String strValue
, String name
) {
356 this.strValue
= strValue
;
360 public int getFieldType() {
361 return FIELDTYPE_STRING
;
365 public String
getValue() {
366 return this.strValue
;
370 public String
toString() {
371 return name
+ '=' + strValue
;
376 * CTF field implementation for arrays of integers.
380 final class CTFIntegerArrayField
extends CtfTmfEventField
{
382 private final long[] longValues
;
385 * Constructor for CTFIntegerArrayField.
388 * The array of integers (as longs) that compose this field's
391 * The name of this field
393 CTFIntegerArrayField(long[] longValues
, String name
) {
395 this.longValues
= longValues
;
399 public int getFieldType() {
400 return FIELDTYPE_INTEGER_ARRAY
;
404 * Gets the values of the array
405 * @return the values in the array
409 long[] getLongValues() {
410 return this.longValues
;
414 public List
<Long
> getValue() {
415 List
<Long
> retVal
= new ArrayList
<Long
>();
416 for( Long l
: longValues
){
423 public String
toString() {
424 StringBuffer buffer
= new StringBuffer();
427 buffer
.append(getValue());
428 return buffer
.toString();
433 * CTF field implementation for floats.
437 final class CTFFloatField
extends CtfTmfEventField
{
439 private final Double value
;
442 * Constructor for CTFFloatField.
445 * The float value (actually a double) of this field
447 * The name of this field
449 protected CTFFloatField(double value
, String name
) {
455 public int getFieldType() {
456 return FIELDTYPE_FLOAT
;
460 public Double
getValue() {
465 public String
toString() {
466 return name
+ '=' + value
;
471 * The CTF field implementation for Enum fields
473 * @author Bernd Hufmann
475 final class CTFEnumField
extends CtfTmfEventField
{
477 private final CtfEnumPair value
;
480 * Constructor for CTFEnumField.
483 * The Enum value consisting of a pair of Enum value name and its long value
485 * The name of this field
487 CTFEnumField(CtfEnumPair enumValue
, String name
) {
489 this.value
= new CtfEnumPair(enumValue
.getFirst(), enumValue
.getSecond().longValue());
493 public int getFieldType() {
494 return FIELDTYPE_ENUM
;
498 public CtfEnumPair
getValue() {
503 public String
toString() {
504 return name
+ '=' + value
.toString();
508 /* Implement other possible fields types here... */