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
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal
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 *
9 * Contributors:
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 * François Doray - Add generic array field type
16 *******************************************************************************/
17
18 package org.eclipse.tracecompass.tmf.ctf.core.event;
19
20 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import org.eclipse.jdt.annotation.NonNull;
27 import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition;
28 import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration;
29 import org.eclipse.tracecompass.ctf.core.event.types.Definition;
30 import org.eclipse.tracecompass.ctf.core.event.types.EnumDefinition;
31 import org.eclipse.tracecompass.ctf.core.event.types.FloatDefinition;
32 import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
33 import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
34 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
35 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration;
36 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
37 import org.eclipse.tracecompass.ctf.core.event.types.StringDefinition;
38 import org.eclipse.tracecompass.ctf.core.event.types.VariantDefinition;
39 import org.eclipse.tracecompass.internal.ctf.core.event.types.ByteArrayDefinition;
40 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
41 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
42 import org.eclipse.tracecompass.tmf.ctf.core.CtfEnumPair;
43
44 /**
45 * The CTF implementation of the TMF event field model
46 *
47 * @version 2.0
48 * @author Matthew Khouzam
49 * @author Alexandre Montplaisir
50 */
51 public abstract class CtfTmfEventField extends TmfEventField {
52
53 // ------------------------------------------------------------------------
54 // Constructor
55 // ------------------------------------------------------------------------
56
57 /**
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
63 * @param value
64 * The value of this field. Its type should match the field type.
65 * @param fields
66 * The children fields. Useful for composite fields
67 */
68 protected CtfTmfEventField(@NonNull String name, Object value, ITmfEventField[] fields) {
69 super(/* Strip the underscore from the field name if there is one */
70 name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$
71 value,
72 fields);
73 }
74
75 // ------------------------------------------------------------------------
76 // Operations
77 // ------------------------------------------------------------------------
78
79 /**
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
87 * @deprecated use {@link CtfTmfEventField#parseField(IDefinition, String)}
88 */
89 @Deprecated
90 public static CtfTmfEventField parseField(Definition fieldDef,
91 @NonNull String fieldName) {
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
103 */
104 public static @NonNull CtfTmfEventField parseField(IDefinition fieldDef,
105 @NonNull String fieldName) {
106 CtfTmfEventField field = null;
107
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, intDef.getDeclaration().isSigned());
113
114 } else if (fieldDef instanceof EnumDefinition) {
115 EnumDefinition enumDef = (EnumDefinition) fieldDef;
116 field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()));
117
118 } else if (fieldDef instanceof StringDefinition) {
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());
124
125 } else if (fieldDef instanceof AbstractArrayDefinition) {
126 AbstractArrayDefinition arrayDef = (AbstractArrayDefinition) fieldDef;
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;
133 elemType = arrDecl.getElementType();
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 }
147 if (elemType instanceof IntegerDeclaration) {
148 /*
149 * Array of integers => CTFIntegerArrayField, unless it's a
150 * CTFStringField
151 */
152 IntegerDeclaration elemIntType = (IntegerDeclaration) elemType;
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 */
159 int size = arrayDef.getLength();
160 long[] values = new long[size];
161 for (int i = 0; i < size; i++) {
162 IDefinition elem = arrayDef.getDefinitions().get(i);
163 if (elem == null) {
164 break;
165 }
166 values[i] = ((IntegerDefinition) elem).getValue();
167 }
168 field = new CTFIntegerArrayField(fieldName, values,
169 elemIntType.getBase(),
170 elemIntType.isSigned());
171 }
172 } else {
173 /* Arrays of elements of any other type */
174 CtfTmfEventField[] elements = new CtfTmfEventField[arrayDef.getLength()];
175 /* Parse the elements of the array. */
176 int i = 0;
177 List<Definition> definitions = arrayDef.getDefinitions();
178 for (IDefinition definition : definitions) {
179 CtfTmfEventField curField = CtfTmfEventField.parseField(
180 definition, fieldName + '[' + i + ']');
181 elements[i] = curField;
182 i++;
183 }
184
185 field = new CTFArrayField(fieldName, elements);
186 }
187 } else if (fieldDef instanceof ICompositeDefinition) {
188 ICompositeDefinition strDef = (ICompositeDefinition) fieldDef;
189
190 List<ITmfEventField> list = new ArrayList<>();
191 /* Recursively parse the fields */
192 for (String fn : strDef.getFieldNames()) {
193 list.add(CtfTmfEventField.parseField((IDefinition) strDef.getDefinition(fn), fn));
194 }
195 field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
196
197 } else if (fieldDef instanceof VariantDefinition) {
198 VariantDefinition varDef = (VariantDefinition) fieldDef;
199
200 String curFieldName = checkNotNull(varDef.getCurrentFieldName());
201 IDefinition curFieldDef = varDef.getCurrentField();
202 if (curFieldDef != null) {
203 CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
204 field = new CTFVariantField(fieldName, subField);
205 } else {
206 /* A safe-guard, but curFieldDef should never be null */
207 field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
208 }
209
210 } else {
211 /*
212 * Safe-guard, to avoid null exceptions later, field is expected not
213 * to be null
214 */
215 field = new CTFStringField(fieldName, Messages.CtfTmfEventField_UnsupportedType + fieldDef.getClass().toString());
216 }
217 return field;
218 }
219
220 @Override
221 public String toString() {
222 return getName() + '=' + getFormattedValue();
223 }
224
225 }
226
227 /**
228 * The CTF field implementation for integer fields.
229 *
230 * @author alexmont
231 */
232 final class CTFIntegerField extends CtfTmfEventField {
233
234 private final int fBase;
235 private final boolean fSigned;
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.
240 *
241 * @param name
242 * The name of this field
243 * @param longValue
244 * The integer value of this field
245 * @param signed
246 * Is the value signed or not
247 */
248 CTFIntegerField(@NonNull String name, long longValue, int base, boolean signed) {
249 super(name, Long.valueOf(longValue), null);
250 fSigned = signed;
251 fBase = base;
252 }
253
254 @Override
255 public Long getValue() {
256 return (Long) super.getValue();
257 }
258
259 @Override
260 public String getFormattedValue() {
261 return IntegerDefinition.formatNumber(getValue(), fBase, fSigned);
262 }
263
264 }
265
266 /**
267 * The CTF field implementation for string fields
268 *
269 * @author alexmont
270 */
271 final class CTFStringField extends CtfTmfEventField {
272
273 /**
274 * Constructor for CTFStringField.
275 *
276 * @param strValue
277 * The string value of this field
278 * @param name
279 * The name of this field
280 */
281 CTFStringField(@NonNull String name, String strValue) {
282 super(name, strValue, null);
283 }
284
285 @Override
286 public String getValue() {
287 return (String) super.getValue();
288 }
289 }
290
291 /**
292 * CTF field implementation for arrays of integers.
293 *
294 * @author alexmont
295 */
296 final class CTFIntegerArrayField extends CtfTmfEventField {
297
298 private final int fBase;
299 private final boolean fSigned;
300 private String fFormattedValue = null;
301
302 /**
303 * Constructor for CTFIntegerArrayField.
304 *
305 * @param name
306 * The name of this field
307 * @param longValues
308 * The array of integers (as longs) that compose this field's
309 * value
310 * @param signed
311 * Are the values in the array signed or not
312 */
313 CTFIntegerArrayField(@NonNull String name, long[] longValues, int base, boolean signed) {
314 super(name, longValues, null);
315 fBase = base;
316 fSigned = signed;
317 }
318
319 @Override
320 public long[] getValue() {
321 return (long[]) super.getValue();
322 }
323
324 @Override
325 public synchronized String getFormattedValue() {
326 if (fFormattedValue == null) {
327 List<String> strings = new ArrayList<>();
328 for (long value : getValue()) {
329 strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned));
330 }
331 fFormattedValue = strings.toString();
332 }
333 return fFormattedValue;
334 }
335
336 }
337
338 /**
339 * CTF field implementation for arrays of arbitrary types.
340 *
341 * @author fdoray
342 */
343 final class CTFArrayField extends CtfTmfEventField {
344
345 private String fFormattedValue = null;
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 */
355 CTFArrayField(@NonNull String name, CtfTmfEventField[] elements) {
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() {
366 if (fFormattedValue == null) {
367 List<String> strings = new ArrayList<>();
368 for (CtfTmfEventField element : getValue()) {
369 strings.add(element.getFormattedValue());
370 }
371 fFormattedValue = strings.toString();
372 }
373 return fFormattedValue;
374 }
375 }
376
377 /**
378 * CTF field implementation for floats.
379 *
380 * @author emathko
381 */
382 final class CTFFloatField extends CtfTmfEventField {
383
384 /**
385 * Constructor for CTFFloatField.
386 *
387 * @param value
388 * The float value (actually a double) of this field
389 * @param name
390 * The name of this field
391 */
392 protected CTFFloatField(@NonNull String name, double value) {
393 super(name, value, null);
394 }
395
396 @Override
397 public Double getValue() {
398 return (Double) super.getValue();
399 }
400 }
401
402 /**
403 * The CTF field implementation for Enum fields
404 *
405 * @author Bernd Hufmann
406 */
407 final class CTFEnumField extends CtfTmfEventField {
408
409 /**
410 * Constructor for CTFEnumField.
411 *
412 * @param enumValue
413 * The Enum value consisting of a pair of Enum value name and its
414 * long value
415 * @param name
416 * The name of this field
417 */
418 CTFEnumField(@NonNull String name, CtfEnumPair enumValue) {
419 super(name, new CtfEnumPair(enumValue.getFirst(),
420 enumValue.getSecond()), null);
421 }
422
423 @Override
424 public CtfEnumPair getValue() {
425 return (CtfEnumPair) super.getValue();
426 }
427 }
428
429 /**
430 * The CTF field implementation for struct fields with sub-fields
431 *
432 * @author gbastien
433 */
434 final class CTFStructField extends CtfTmfEventField {
435
436 /**
437 * Constructor for CTFStructField.
438 *
439 * @param fields
440 * The children of this field
441 * @param name
442 * The name of this field
443 */
444 CTFStructField(@NonNull String name, CtfTmfEventField[] fields) {
445 super(name, fields, fields);
446 }
447
448 @Override
449 public CtfTmfEventField[] getValue() {
450 return (CtfTmfEventField[]) super.getValue();
451 }
452
453 @Override
454 public String getFormattedValue() {
455 return Arrays.toString(getValue());
456 }
457
458 }
459
460 /**
461 * The CTF field implementation for variant fields its child
462 *
463 * @author gbastien
464 */
465 final 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 */
475 CTFVariantField(@NonNull String name, CtfTmfEventField field) {
476 super(name, field, new CtfTmfEventField[] { field });
477 }
478
479 @Override
480 public CtfTmfEventField getValue() {
481 return (CtfTmfEventField) super.getValue();
482 }
483
484 }
485
486 /* Implement other possible fields types here... */
This page took 0.043554 seconds and 5 git commands to generate.