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