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