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