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