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