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 org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDeclaration
;
19 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.ArrayDefinition
;
20 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.EnumDefinition
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.FloatDefinition
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDeclaration
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDeclaration
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.SequenceDefinition
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StringDefinition
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
31 * The CTF implementation of the TMF event field model
34 * @author Matthew Khouzam
35 * @author Alexandre Montplaisir
37 public abstract class CtfTmfEventField
implements ITmfEventField
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
44 protected static final int FIELDTYPE_INTEGER
= 0;
47 protected static final int FIELDTYPE_STRING
= 1;
50 protected static final int FIELDTYPE_INTEGER_ARRAY
= 2;
53 protected static final int FIELDTYPE_FLOAT
= 3;
56 protected static final int FIELDTYPE_ENUM
= 4;
58 // ------------------------------------------------------------------------
60 // ------------------------------------------------------------------------
62 protected final String name
;
64 // ------------------------------------------------------------------------
66 // ------------------------------------------------------------------------
69 * Standard constructor. Only to be used internally, call parseField() to
70 * generate a new field object.
73 * The name of this field
75 protected CtfTmfEventField(String name
) {
76 /* Strip the underscore */
77 if (name
.startsWith("_")) { //$NON-NLS-1$
78 this.name
= name
.substring(1);
84 // ------------------------------------------------------------------------
85 // Getters/Setters/Predicates
86 // ------------------------------------------------------------------------
89 public String
getName() {
93 // ------------------------------------------------------------------------
95 // ------------------------------------------------------------------------
98 * Factory method to instantiate CtfTmfEventField objects.
101 * The CTF Definition of this event field
103 * String The name to assign to this field
104 * @return The resulting CtfTmfEventField object
106 public static CtfTmfEventField
parseField(Definition fieldDef
,
108 CtfTmfEventField field
= null;
110 /* Determine the Definition type */
111 if (fieldDef
instanceof IntegerDefinition
) {
112 IntegerDefinition intDef
= (IntegerDefinition
) fieldDef
;
113 int base
= intDef
.getDeclaration().getBase();
114 field
= new CTFIntegerField(intDef
.getValue(), fieldName
, base
);
116 } else if (fieldDef
instanceof EnumDefinition
) {
117 EnumDefinition enumDef
= (EnumDefinition
) fieldDef
;
118 field
= new CTFEnumField(new CtfEnumPair(enumDef
.getValue(), enumDef
.getIntegerValue()), fieldName
);
120 } else if (fieldDef
instanceof StringDefinition
) {
121 field
= new CTFStringField(
122 ((StringDefinition
) fieldDef
).getValue(), fieldName
);
124 } else if (fieldDef
instanceof ArrayDefinition
) {
125 ArrayDefinition arrayDef
= (ArrayDefinition
) fieldDef
;
126 ArrayDeclaration arrayDecl
= arrayDef
.getDeclaration();
128 if (arrayDef
.isString()) {
129 /* This is an array of UTF-8 bytes, a.k.a. a String! */
130 field
= new CTFStringField(fieldDef
.toString(), fieldName
);
132 } else if (arrayDecl
.getElementType() instanceof IntegerDeclaration
) {
133 /* This is a an array of CTF Integers */
134 long[] values
= new long[arrayDecl
.getLength()];
135 for (int i
= 0; i
< arrayDecl
.getLength(); i
++) {
136 values
[i
] = ((IntegerDefinition
) arrayDef
.getElem(i
))
139 field
= new CTFIntegerArrayField(values
, fieldName
);
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(seqDef
.toString(), fieldName
);
153 } else if (seqDecl
.getElementType() instanceof IntegerDeclaration
) {
154 /* Sequence of integers => CTFIntegerArrayField */
155 long[] values
= new long[seqDef
.getLength()];
156 for (int i
= 0; i
< seqDef
.getLength(); i
++) {
157 values
[i
] = ((IntegerDefinition
) seqDef
.getElem(i
))
160 field
= new CTFIntegerArrayField(values
, fieldName
);
162 /* Add other Sequence types here */
164 } else if (fieldDef
instanceof FloatDefinition
) {
165 FloatDefinition floatDef
= (FloatDefinition
) fieldDef
;
166 field
= new CTFFloatField(floatDef
.getValue(), fieldName
);
173 * Copy factory. Create a new field by (deep-) copying the information in an
177 * The other CtfTmfEventField to copy
178 * @return The new CtfTmfEventField
180 public static CtfTmfEventField
copyFrom(CtfTmfEventField other
) {
181 switch (other
.getFieldType()) {
182 case FIELDTYPE_INTEGER
:
183 CTFIntegerField intOther
= (CTFIntegerField
) other
;
184 return new CTFIntegerField(intOther
.getValue(), intOther
.name
,
186 case FIELDTYPE_STRING
:
187 return new CTFStringField(((CTFStringField
) other
).getValue(),
189 case FIELDTYPE_INTEGER_ARRAY
:
190 return new CTFIntegerArrayField(
191 ((CTFIntegerArrayField
) other
).getValue(), other
.name
);
192 case FIELDTYPE_FLOAT
:
193 return new CTFFloatField(((CTFFloatField
) other
).getValue(),
196 return new CTFEnumField(((CTFEnumField
) other
).getValue(), other
.name
);
203 public CtfTmfEventField
clone() {
204 return CtfTmfEventField
.copyFrom(this);
207 // ------------------------------------------------------------------------
208 // Abstract methods (to be implemented by each specific field type)
209 // ------------------------------------------------------------------------
212 * Return the int representing this field's value type
214 * @return The field type
216 public abstract int getFieldType();
219 * Return this field's value. You can cast it to the correct type depending
220 * on what getFieldType says.
222 * @return The field's value
225 public abstract Object
getValue();
227 // ------------------------------------------------------------------------
228 // Other methods defined by ITmfEventField, but not used here.
229 // CTF fields do not have sub-fields (yet!)
230 // ------------------------------------------------------------------------
233 public String
[] getFieldNames() {
238 public String
getFieldName(int index
) {
243 public ITmfEventField
[] getFields() {
248 public ITmfEventField
getField(String fieldName
) {
253 public ITmfEventField
getField(int index
) {
259 * The CTF field implementation for integer fields.
263 final class CTFIntegerField
extends CtfTmfEventField
{
265 private final long longValue
;
266 private final int base
;
269 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
270 * Java parser this is interpreted as a long.
273 * The integer value of this field
275 * The name of this field
277 CTFIntegerField(long longValue
, String name
, int base
) {
279 this.longValue
= longValue
;
284 * Return the integer's base. (Not made public until it's needed.)
286 * @return The base, usually 10 or 16.
293 public int getFieldType() {
294 return FIELDTYPE_INTEGER
;
298 public Long
getValue() {
299 return this.longValue
;
303 public String
toString() {
304 StringBuilder sb
= new StringBuilder(name
);
307 /* Format the number correctly according to the integer's base */
310 sb
.append("0b"); //$NON-NLS-1$
311 sb
.append(Long
.toBinaryString(longValue
));
315 sb
.append(Long
.toOctalString(longValue
));
318 sb
.append(longValue
);
321 sb
.append("0x"); //$NON-NLS-1$
322 sb
.append(Long
.toHexString(longValue
));
325 /* Non-standard base, we'll just print it as a decimal number */
326 sb
.append(longValue
);
329 return sb
.toString();
334 * The CTF field implementation for string fields
338 final class CTFStringField
extends CtfTmfEventField
{
340 private final String strValue
;
343 * Constructor for CTFStringField.
346 * The string value of this field
348 * The name of this field
350 CTFStringField(String strValue
, String name
) {
352 this.strValue
= strValue
;
356 public int getFieldType() {
357 return FIELDTYPE_STRING
;
361 public String
getValue() {
362 return this.strValue
;
366 public String
toString() {
367 return name
+ '=' + strValue
;
372 * CTF field implementation for arrays of integers.
376 final class CTFIntegerArrayField
extends CtfTmfEventField
{
378 private final long[] longValues
;
381 * Constructor for CTFIntegerArrayField.
384 * The array of integers (as longs) that compose this field's
387 * The name of this field
389 CTFIntegerArrayField(long[] longValues
, String name
) {
391 this.longValues
= longValues
;
395 public int getFieldType() {
396 return FIELDTYPE_INTEGER_ARRAY
;
400 public long[] getValue() {
401 return this.longValues
;
405 public String
toString() {
406 StringBuffer buffer
= new StringBuffer();
407 buffer
.append("{ "); //$NON-NLS-1$
409 buffer
.append(longValues
[0]);
410 for (int i
= 1; i
< longValues
.length
; i
++) {
411 buffer
.append(", " + longValues
[i
]); //$NON-NLS-1$
414 return name
+ '=' + buffer
.toString();
419 * CTF field implementation for floats.
423 final class CTFFloatField
extends CtfTmfEventField
{
425 private final Double value
;
428 * Constructor for CTFFloatField.
431 * The float value (actually a double) of this field
433 * The name of this field
435 protected CTFFloatField(double value
, String name
) {
441 public int getFieldType() {
442 return FIELDTYPE_FLOAT
;
446 public Double
getValue() {
451 public String
toString() {
452 return name
+ '=' + value
;
457 * The CTF field implementation for Enum fields
459 * @author Bernd Hufmann
461 final class CTFEnumField
extends CtfTmfEventField
{
463 private final CtfEnumPair value
;
466 * Constructor for CTFEnumField.
469 * The Enum value consisting of a pair of Enum value name and its long value
471 * The name of this field
473 CTFEnumField(CtfEnumPair enumValue
, String name
) {
475 this.value
= new CtfEnumPair(enumValue
.getFirst(), enumValue
.getSecond().longValue());
479 public int getFieldType() {
480 return FIELDTYPE_ENUM
;
484 public CtfEnumPair
getValue() {
489 public String
toString() {
490 return name
+ '=' + value
.toString();
494 /* Implement other possible fields types here... */