ctf: Explicitly create a Long object for Integer fields
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.tmf.ctf.core / src / org / eclipse / tracecompass / tmf / ctf / core / event / CtfTmfEventField.java
CommitLineData
a3fc8213 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal
a3fc8213
AM
3 *
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
8 *
d4a8d935
BH
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
404b264a 11 * Alexandre Montplaisir - Initial API and implementation, extend TmfEventField
d4a8d935 12 * Bernd Hufmann - Add Enum field handling
404b264a 13 * Geneviève Bastien - Add Struct and Variant field handling
459f705b 14 * Jean-Christian Kouame - Correct handling of unsigned integer fields
4591bed9 15 * François Doray - Add generic array field type
a3fc8213
AM
16 *******************************************************************************/
17
9722e5d7 18package org.eclipse.tracecompass.tmf.ctf.core.event;
a3fc8213 19
fafdd006
AM
20import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
21
a6223d74 22import java.util.ArrayList;
7a6cee1a 23import java.util.Arrays;
a6223d74
MK
24import java.util.List;
25
fafdd006 26import org.eclipse.jdt.annotation.NonNull;
15f6223a 27import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition;
f357bcd4
AM
28import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration;
29import org.eclipse.tracecompass.ctf.core.event.types.Definition;
30import org.eclipse.tracecompass.ctf.core.event.types.EnumDefinition;
31import org.eclipse.tracecompass.ctf.core.event.types.FloatDefinition;
32import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
33import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
34import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
35import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration;
36import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
37import org.eclipse.tracecompass.ctf.core.event.types.StringDefinition;
38import org.eclipse.tracecompass.ctf.core.event.types.VariantDefinition;
45261b3b 39import org.eclipse.tracecompass.internal.ctf.core.event.types.ByteArrayDefinition;
2bdf0193
AM
40import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
41import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
9722e5d7 42import org.eclipse.tracecompass.tmf.ctf.core.CtfEnumPair;
a3fc8213
AM
43
44/**
7558a1e1
AM
45 * The CTF implementation of the TMF event field model
46 *
d4a8d935 47 * @version 2.0
7558a1e1 48 * @author Matthew Khouzam
d09f973b 49 * @author Alexandre Montplaisir
a3fc8213 50 */
68b18f2f 51public abstract class CtfTmfEventField extends TmfEventField {
a3fc8213 52
a3fc8213 53 // ------------------------------------------------------------------------
7558a1e1 54 // Constructor
a3fc8213
AM
55 // ------------------------------------------------------------------------
56
b1baa808 57 /**
7558a1e1
AM
58 * Standard constructor. Only to be used internally, call parseField() to
59 * generate a new field object.
60 *
61 * @param name
62 * The name of this field
68b18f2f
AM
63 * @param value
64 * The value of this field. Its type should match the field type.
81ed27a8
MK
65 * @param fields
66 * The children fields. Useful for composite fields
b1baa808 67 */
fafdd006 68 protected CtfTmfEventField(@NonNull String name, Object value, ITmfEventField[] fields) {
68b18f2f 69 super(/* Strip the underscore from the field name if there is one */
0b1ac3e2 70 name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$
68b18f2f 71 value,
81ed27a8 72 fields);
a3fc8213
AM
73 }
74
75 // ------------------------------------------------------------------------
76 // Operations
77 // ------------------------------------------------------------------------
78
b1baa808 79 /**
7558a1e1
AM
80 * Factory method to instantiate CtfTmfEventField objects.
81 *
82 * @param fieldDef
83 * The CTF Definition of this event field
84 * @param fieldName
85 * String The name to assign to this field
86 * @return The resulting CtfTmfEventField object
cc98c947 87 * @deprecated use {@link CtfTmfEventField#parseField(IDefinition, String)}
b1baa808 88 */
cc98c947 89 @Deprecated
a3fc8213 90 public static CtfTmfEventField parseField(Definition fieldDef,
fafdd006 91 @NonNull String fieldName) {
cc98c947
MK
92 return parseField((IDefinition) fieldDef, fieldName);
93 }
94
95 /**
96 * Factory method to instantiate CtfTmfEventField objects.
97 *
98 * @param fieldDef
99 * The CTF Definition of this event field
100 * @param fieldName
101 * String The name to assign to this field
102 * @return The resulting CtfTmfEventField object
cc98c947 103 */
aa353506 104 public static @NonNull CtfTmfEventField parseField(IDefinition fieldDef,
fafdd006 105 @NonNull String fieldName) {
a3fc8213
AM
106 CtfTmfEventField field = null;
107
108 /* Determine the Definition type */
109 if (fieldDef instanceof IntegerDefinition) {
367bcd2b
AM
110 IntegerDefinition intDef = (IntegerDefinition) fieldDef;
111 int base = intDef.getDeclaration().getBase();
459f705b 112 field = new CTFIntegerField(fieldName, intDef.getValue(), base, intDef.getDeclaration().isSigned());
a3fc8213 113
21fb02fa
MK
114 } else if (fieldDef instanceof EnumDefinition) {
115 EnumDefinition enumDef = (EnumDefinition) fieldDef;
68b18f2f 116 field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()));
21fb02fa 117
a3fc8213 118 } else if (fieldDef instanceof StringDefinition) {
68b18f2f
AM
119 field = new CTFStringField(fieldName, ((StringDefinition) fieldDef).getValue());
120
121 } else if (fieldDef instanceof FloatDefinition) {
122 FloatDefinition floatDef = (FloatDefinition) fieldDef;
123 field = new CTFFloatField(fieldName, floatDef.getValue());
a3fc8213 124
15f6223a
MK
125 } else if (fieldDef instanceof AbstractArrayDefinition) {
126 AbstractArrayDefinition arrayDef = (AbstractArrayDefinition) fieldDef;
7b4f13e6
MK
127 IDeclaration decl = arrayDef.getDeclaration();
128 if (!(decl instanceof CompoundDeclaration)) {
129 throw new IllegalArgumentException("Array definitions should only come from sequence or array declarations"); //$NON-NLS-1$
130 }
131 CompoundDeclaration arrDecl = (CompoundDeclaration) decl;
132 IDeclaration elemType = null;
7b4f13e6 133 elemType = arrDecl.getElementType();
45261b3b
MK
134 if (arrayDef instanceof ByteArrayDefinition) {
135 ByteArrayDefinition byteArrayDefinition = (ByteArrayDefinition) arrayDef;
136 /* it's a CTFIntegerArrayField */
137 int size = arrayDef.getLength();
138 long[] values = new long[size];
139 for (int i = 0; i < size; i++) {
140 values[i] = Byte.toUnsignedLong(byteArrayDefinition.getByte(i));
141 }
142 field = new CTFIntegerArrayField(fieldName, values,
143 16,
144 false);
145
146 }
7b4f13e6 147 if (elemType instanceof IntegerDeclaration) {
15f6223a
MK
148 /*
149 * Array of integers => CTFIntegerArrayField, unless it's a
150 * CTFStringField
151 */
7b4f13e6 152 IntegerDeclaration elemIntType = (IntegerDeclaration) elemType;
373af311
MK
153 /* Are the integers characters and encoded? */
154 if (elemIntType.isCharacter()) {
155 /* it's a CTFStringField */
156 field = new CTFStringField(fieldName, arrayDef.toString());
157 } else {
158 /* it's a CTFIntegerArrayField */
45261b3b 159 int size = arrayDef.getLength();
15f6223a
MK
160 long[] values = new long[size];
161 for (int i = 0; i < size; i++) {
373af311
MK
162 IDefinition elem = arrayDef.getDefinitions().get(i);
163 if (elem == null) {
164 break;
165 }
166 values[i] = ((IntegerDefinition) elem).getValue();
7b4f13e6 167 }
373af311
MK
168 field = new CTFIntegerArrayField(fieldName, values,
169 elemIntType.getBase(),
170 elemIntType.isSigned());
7b4f13e6 171 }
4591bed9
FD
172 } else {
173 /* Arrays of elements of any other type */
7b4f13e6 174 CtfTmfEventField[] elements = new CtfTmfEventField[arrayDef.getLength()];
4591bed9 175 /* Parse the elements of the array. */
7b4f13e6 176 int i = 0;
45261b3b 177 List<Definition> definitions = arrayDef.getDefinitions();
cc98c947 178 for (IDefinition definition : definitions) {
4591bed9 179 CtfTmfEventField curField = CtfTmfEventField.parseField(
7b4f13e6 180 definition, fieldName + '[' + i + ']');
4591bed9 181 elements[i] = curField;
7b4f13e6 182 i++;
a3fc8213 183 }
a3fc8213 184
4591bed9
FD
185 field = new CTFArrayField(fieldName, elements);
186 }
009883d7
MK
187 } else if (fieldDef instanceof ICompositeDefinition) {
188 ICompositeDefinition strDef = (ICompositeDefinition) fieldDef;
7a6cee1a 189
a4524c1b 190 List<ITmfEventField> list = new ArrayList<>();
7a6cee1a 191 /* Recursively parse the fields */
0e4f957e 192 for (String fn : strDef.getFieldNames()) {
fafdd006 193 list.add(CtfTmfEventField.parseField((IDefinition) strDef.getDefinition(fn), fn));
7a6cee1a
GB
194 }
195 field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
a0e9eac8 196
404b264a
GB
197 } else if (fieldDef instanceof VariantDefinition) {
198 VariantDefinition varDef = (VariantDefinition) fieldDef;
199
fafdd006 200 String curFieldName = checkNotNull(varDef.getCurrentFieldName());
cc98c947 201 IDefinition curFieldDef = varDef.getCurrentField();
404b264a 202 if (curFieldDef != null) {
51cc7ef4
GB
203 CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
204 field = new CTFVariantField(fieldName, subField);
404b264a
GB
205 } else {
206 /* A safe-guard, but curFieldDef should never be null */
207 field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
208 }
209
210 } else {
459f705b
JCK
211 /*
212 * Safe-guard, to avoid null exceptions later, field is expected not
213 * to be null
214 */
91e7f946 215 field = new CTFStringField(fieldName, Messages.CtfTmfEventField_UnsupportedType + fieldDef.getClass().toString());
a3fc8213 216 }
a3fc8213
AM
217 return field;
218 }
219
a3fc8213 220 @Override
68b18f2f 221 public String toString() {
51cc7ef4 222 return getName() + '=' + getFormattedValue();
a3fc8213
AM
223 }
224
a3fc8213
AM
225}
226
227/**
7558a1e1
AM
228 * The CTF field implementation for integer fields.
229 *
230 * @author alexmont
a3fc8213
AM
231 */
232final class CTFIntegerField extends CtfTmfEventField {
233
6fc4ce56
MK
234 private final int fBase;
235 private final boolean fSigned;
a3fc8213
AM
236
237 /**
238 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
239 * Java parser this is interpreted as a long.
7558a1e1 240 *
7558a1e1
AM
241 * @param name
242 * The name of this field
459f705b
JCK
243 * @param longValue
244 * The integer value of this field
245 * @param signed
246 * Is the value signed or not
a3fc8213 247 */
fafdd006 248 CTFIntegerField(@NonNull String name, long longValue, int base, boolean signed) {
905a5e84 249 super(name, Long.valueOf(longValue), null);
6fc4ce56
MK
250 fSigned = signed;
251 fBase = base;
367bcd2b
AM
252 }
253
a3fc8213
AM
254 @Override
255 public Long getValue() {
68b18f2f 256 return (Long) super.getValue();
a3fc8213
AM
257 }
258
8f86c552
GB
259 @Override
260 public String getFormattedValue() {
6fc4ce56 261 return IntegerDefinition.formatNumber(getValue(), fBase, fSigned);
8f86c552
GB
262 }
263
a3fc8213
AM
264}
265
266/**
7558a1e1
AM
267 * The CTF field implementation for string fields
268 *
269 * @author alexmont
a3fc8213
AM
270 */
271final class CTFStringField extends CtfTmfEventField {
272
b1baa808
MK
273 /**
274 * Constructor for CTFStringField.
7558a1e1
AM
275 *
276 * @param strValue
277 * The string value of this field
278 * @param name
279 * The name of this field
b1baa808 280 */
fafdd006 281 CTFStringField(@NonNull String name, String strValue) {
81ed27a8 282 super(name, strValue, null);
a3fc8213
AM
283 }
284
a3fc8213
AM
285 @Override
286 public String getValue() {
68b18f2f 287 return (String) super.getValue();
a3fc8213
AM
288 }
289}
290
291/**
7558a1e1
AM
292 * CTF field implementation for arrays of integers.
293 *
294 * @author alexmont
a3fc8213
AM
295 */
296final class CTFIntegerArrayField extends CtfTmfEventField {
297
6fc4ce56
MK
298 private final int fBase;
299 private final boolean fSigned;
300 private String fFormattedValue = null;
404b264a 301
b1baa808
MK
302 /**
303 * Constructor for CTFIntegerArrayField.
7558a1e1 304 *
459f705b
JCK
305 * @param name
306 * The name of this field
7558a1e1
AM
307 * @param longValues
308 * The array of integers (as longs) that compose this field's
309 * value
459f705b
JCK
310 * @param signed
311 * Are the values in the array signed or not
b1baa808 312 */
fafdd006 313 CTFIntegerArrayField(@NonNull String name, long[] longValues, int base, boolean signed) {
81ed27a8 314 super(name, longValues, null);
6fc4ce56
MK
315 fBase = base;
316 fSigned = signed;
a3fc8213
AM
317 }
318
a6223d74 319 @Override
cefe3edf
AM
320 public long[] getValue() {
321 return (long[]) super.getValue();
a3fc8213 322 }
404b264a 323
8f86c552 324 @Override
4591bed9 325 public synchronized String getFormattedValue() {
6fc4ce56 326 if (fFormattedValue == null) {
a4524c1b 327 List<String> strings = new ArrayList<>();
cefe3edf 328 for (long value : getValue()) {
6fc4ce56 329 strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned));
8f86c552 330 }
6fc4ce56 331 fFormattedValue = strings.toString();
8f86c552 332 }
6fc4ce56 333 return fFormattedValue;
8f86c552
GB
334 }
335
a3fc8213
AM
336}
337
4591bed9
FD
338/**
339 * CTF field implementation for arrays of arbitrary types.
340 *
341 * @author fdoray
342 */
343final class CTFArrayField extends CtfTmfEventField {
344
6fc4ce56 345 private String fFormattedValue = null;
4591bed9
FD
346
347 /**
348 * Constructor for CTFArrayField.
349 *
350 * @param name
351 * The name of this field
352 * @param elements
353 * The array elements of this field
354 */
fafdd006 355 CTFArrayField(@NonNull String name, CtfTmfEventField[] elements) {
4591bed9
FD
356 super(name, elements, elements);
357 }
358
359 @Override
360 public CtfTmfEventField[] getValue() {
361 return (CtfTmfEventField[]) super.getValue();
362 }
363
364 @Override
365 public synchronized String getFormattedValue() {
6fc4ce56 366 if (fFormattedValue == null) {
a4524c1b 367 List<String> strings = new ArrayList<>();
4591bed9
FD
368 for (CtfTmfEventField element : getValue()) {
369 strings.add(element.getFormattedValue());
370 }
6fc4ce56 371 fFormattedValue = strings.toString();
4591bed9 372 }
6fc4ce56 373 return fFormattedValue;
4591bed9
FD
374 }
375}
376
b1baa808 377/**
7558a1e1
AM
378 * CTF field implementation for floats.
379 *
380 * @author emathko
b1baa808 381 */
a04464b1
MK
382final class CTFFloatField extends CtfTmfEventField {
383
b1baa808
MK
384 /**
385 * Constructor for CTFFloatField.
7558a1e1
AM
386 *
387 * @param value
388 * The float value (actually a double) of this field
389 * @param name
390 * The name of this field
b1baa808 391 */
fafdd006 392 protected CTFFloatField(@NonNull String name, double value) {
81ed27a8 393 super(name, value, null);
a04464b1
MK
394 }
395
a04464b1 396 @Override
81c8e6f7 397 public Double getValue() {
68b18f2f 398 return (Double) super.getValue();
a04464b1 399 }
a04464b1 400}
7558a1e1 401
d4a8d935
BH
402/**
403 * The CTF field implementation for Enum fields
404 *
405 * @author Bernd Hufmann
406 */
407final class CTFEnumField extends CtfTmfEventField {
408
d4a8d935
BH
409 /**
410 * Constructor for CTFEnumField.
411 *
412 * @param enumValue
459f705b
JCK
413 * The Enum value consisting of a pair of Enum value name and its
414 * long value
d4a8d935
BH
415 * @param name
416 * The name of this field
417 */
fafdd006 418 CTFEnumField(@NonNull String name, CtfEnumPair enumValue) {
68b18f2f 419 super(name, new CtfEnumPair(enumValue.getFirst(),
0126a8ca 420 enumValue.getSecond()), null);
d4a8d935
BH
421 }
422
d4a8d935 423 @Override
68b18f2f
AM
424 public CtfEnumPair getValue() {
425 return (CtfEnumPair) super.getValue();
d4a8d935
BH
426 }
427}
428
7a6cee1a 429/**
51cc7ef4 430 * The CTF field implementation for struct fields with sub-fields
7a6cee1a
GB
431 *
432 * @author gbastien
433 */
434final class CTFStructField extends CtfTmfEventField {
435
436 /**
51cc7ef4 437 * Constructor for CTFStructField.
7a6cee1a 438 *
51cc7ef4
GB
439 * @param fields
440 * The children of this field
7a6cee1a
GB
441 * @param name
442 * The name of this field
443 */
fafdd006 444 CTFStructField(@NonNull String name, CtfTmfEventField[] fields) {
81ed27a8 445 super(name, fields, fields);
7a6cee1a
GB
446 }
447
7a6cee1a
GB
448 @Override
449 public CtfTmfEventField[] getValue() {
450 return (CtfTmfEventField[]) super.getValue();
451 }
452
453 @Override
51cc7ef4
GB
454 public String getFormattedValue() {
455 return Arrays.toString(getValue());
7a6cee1a 456 }
51cc7ef4
GB
457
458}
459
460/**
461 * The CTF field implementation for variant fields its child
462 *
463 * @author gbastien
464 */
465final class CTFVariantField extends CtfTmfEventField {
466
467 /**
468 * Constructor for CTFVariantField.
469 *
470 * @param field
471 * The field selected for this variant
472 * @param name
473 * The name of this field
474 */
fafdd006 475 CTFVariantField(@NonNull String name, CtfTmfEventField field) {
459f705b 476 super(name, field, new CtfTmfEventField[] { field });
51cc7ef4
GB
477 }
478
479 @Override
480 public CtfTmfEventField getValue() {
481 return (CtfTmfEventField) super.getValue();
482 }
483
7a6cee1a
GB
484}
485
a3fc8213 486/* Implement other possible fields types here... */
This page took 0.116511 seconds and 5 git commands to generate.