tmf: Remove getFieldType() method from CTF event fields
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 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 *******************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
17
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.Map.Entry;
22
23 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDeclaration;
24 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
25 import org.eclipse.linuxtools.ctf.core.event.types.Definition;
26 import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition;
27 import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition;
28 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration;
29 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
30 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDeclaration;
31 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDefinition;
32 import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition;
33 import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
34 import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition;
35 import org.eclipse.linuxtools.internal.tmf.core.Messages;
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);
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 ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
108
109 if (arrayDef.isString()) {
110 /* This is an array of UTF-8 bytes, a.k.a. a String! */
111 field = new CTFStringField(fieldName, fieldDef.toString());
112
113 } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
114 /* This is a an array of CTF Integers */
115 List<Long> values = new ArrayList<Long>(arrayDecl.getLength());
116 for (int i = 0; i < arrayDecl.getLength(); i++) {
117 values.add(((IntegerDefinition) arrayDef.getElem(i)).getValue());
118 }
119 field = new CTFIntegerArrayField(fieldName, values, ((IntegerDeclaration) arrayDecl.getElementType()).getBase());
120 }
121 /* Add other types of arrays here */
122
123 } else if (fieldDef instanceof SequenceDefinition) {
124 SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
125 SequenceDeclaration seqDecl = seqDef.getDeclaration();
126
127 if (seqDef.getLength() == 0) {
128 /* Some sequences have length = 0. Simply use an empty string */
129 field = new CTFStringField(fieldName, ""); //$NON-NLS-1$
130 } else if (seqDef.isString()) {
131 /* Interpret this sequence as a String */
132 field = new CTFStringField(fieldName, seqDef.toString());
133 } else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
134 /* Sequence of integers => CTFIntegerArrayField */
135 List<Long> values = new ArrayList<Long>(seqDef.getLength());
136 for (int i = 0; i < seqDef.getLength(); i++) {
137 values.add(((IntegerDefinition) seqDef.getElem(i)).getValue());
138 }
139 field = new CTFIntegerArrayField(fieldName, values, ((IntegerDeclaration) seqDecl.getElementType()).getBase());
140 }
141 /* Add other Sequence types here */
142
143 } else if (fieldDef instanceof StructDefinition) {
144 StructDefinition strDef = (StructDefinition) fieldDef;
145
146 String curFieldName = null;
147 Definition curFieldDef;
148 CtfTmfEventField curField;
149 List<ITmfEventField> list = new ArrayList<ITmfEventField>();
150 /* Recursively parse the fields */
151 for (Entry<String, Definition> entry : strDef.getDefinitions().entrySet()) {
152 curFieldName = entry.getKey();
153 curFieldDef = entry.getValue();
154 curField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
155 list.add(curField);
156 }
157 field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
158
159 } else if (fieldDef instanceof VariantDefinition) {
160 VariantDefinition varDef = (VariantDefinition) fieldDef;
161
162 String curFieldName = varDef.getCurrentFieldName();
163 Definition curFieldDef = varDef.getDefinitions().get(curFieldName);
164 if (curFieldDef != null) {
165 field = CtfTmfEventField.parseField(curFieldDef, curFieldName);
166 } else {
167 /* A safe-guard, but curFieldDef should never be null */
168 field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
169 }
170
171 } else {
172 /* Safe-guard, to avoid null exceptions later, field is expected not to be null */
173 field = new CTFStringField(fieldName, Messages.TmfEventField_UnsupportedType + fieldDef.getClass().toString());
174 }
175 return field;
176 }
177
178 @Override
179 public String toString() {
180 return getName() + '=' + getValue().toString();
181 }
182
183 /**
184 * Print a numeric value as a string in a given base
185 *
186 * @param value
187 * The value to print as string
188 * @param base
189 * The base for this value
190 * @return formatted number string
191 * @since 2.0
192 */
193 protected final static String formatNumber(long value, int base) {
194 String s;
195 /* Format the number correctly according to the integer's base */
196 switch (base) {
197 case 2:
198 s = "0b" + Long.toBinaryString(value); //$NON-NLS-1$
199 break;
200 case 8:
201 s = "0" + Long.toOctalString(value); //$NON-NLS-1$
202 break;
203 case 10:
204 s = Long.toString(value);
205 break;
206 case 16:
207 s = "0x" + Long.toHexString(value); //$NON-NLS-1$
208 break;
209 default:
210 /* Non-standard base, we'll just print it as a decimal number */
211 s = Long.toString(value);
212 break;
213 }
214 return s;
215 }
216
217 }
218
219 /**
220 * The CTF field implementation for integer fields.
221 *
222 * @author alexmont
223 */
224 final class CTFIntegerField extends CtfTmfEventField {
225
226 private final int base;
227
228 /**
229 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
230 * Java parser this is interpreted as a long.
231 *
232 * @param longValue
233 * The integer value of this field
234 * @param name
235 * The name of this field
236 */
237 CTFIntegerField(String name, long longValue, int base) {
238 super(name, longValue, null);
239 this.base = base;
240 }
241
242 @Override
243 public Long getValue() {
244 return (Long) super.getValue();
245 }
246
247 @Override
248 public String getFormattedValue() {
249 return formatNumber(getValue(), base);
250 }
251
252 /**
253 * Custom-format the integer values depending on their base.
254 */
255 @Override
256 public String toString() {
257 return getName() + '=' + formatNumber(getValue(), base);
258 }
259 }
260
261 /**
262 * The CTF field implementation for string fields
263 *
264 * @author alexmont
265 */
266 final class CTFStringField extends CtfTmfEventField {
267
268 /**
269 * Constructor for CTFStringField.
270 *
271 * @param strValue
272 * The string value of this field
273 * @param name
274 * The name of this field
275 */
276 CTFStringField(String name, String strValue) {
277 super(name, strValue, null);
278 }
279
280 @Override
281 public String getValue() {
282 return (String) super.getValue();
283 }
284 }
285
286 /**
287 * CTF field implementation for arrays of integers.
288 *
289 * @author alexmont
290 */
291 final class CTFIntegerArrayField extends CtfTmfEventField {
292
293 private final int base;
294 private String formattedValue = null;
295
296 /**
297 * Constructor for CTFIntegerArrayField.
298 *
299 * @param longValues
300 * The array of integers (as longs) that compose this field's
301 * value
302 * @param name
303 * The name of this field
304 */
305 CTFIntegerArrayField(String name, List<Long> longValues, int base) {
306 super(name, longValues, null);
307 this.base = base;
308 }
309
310 @Override
311 public List<Long> getValue() {
312 return (List<Long>) super.getValue();
313 }
314
315 @Override
316 public String getFormattedValue() {
317 if (formattedValue == null) {
318 List<String> strings = new ArrayList<String>();
319 for (Long value : getValue()) {
320 strings.add(formatNumber(value, base));
321 }
322 formattedValue = strings.toString();
323 }
324 return formattedValue;
325 }
326
327 /**
328 * Custom-format the integer values depending on their base.
329 */
330 @Override
331 public String toString() {
332 return getName() + '=' + getFormattedValue();
333 }
334 }
335
336 /**
337 * CTF field implementation for floats.
338 *
339 * @author emathko
340 */
341 final class CTFFloatField extends CtfTmfEventField {
342
343 /**
344 * Constructor for CTFFloatField.
345 *
346 * @param value
347 * The float value (actually a double) of this field
348 * @param name
349 * The name of this field
350 */
351 protected CTFFloatField(String name, double value) {
352 super(name, value, null);
353 }
354
355 @Override
356 public Double getValue() {
357 return (Double) super.getValue();
358 }
359 }
360
361 /**
362 * The CTF field implementation for Enum fields
363 *
364 * @author Bernd Hufmann
365 */
366 final class CTFEnumField extends CtfTmfEventField {
367
368 /**
369 * Constructor for CTFEnumField.
370 *
371 * @param enumValue
372 * The Enum value consisting of a pair of Enum value name and its long value
373 * @param name
374 * The name of this field
375 */
376 CTFEnumField(String name, CtfEnumPair enumValue) {
377 super(name, new CtfEnumPair(enumValue.getFirst(),
378 enumValue.getSecond().longValue()), null);
379 }
380
381 @Override
382 public CtfEnumPair getValue() {
383 return (CtfEnumPair) super.getValue();
384 }
385 }
386
387 /**
388 * The CTF field implementation for struct fields with sub-types
389 *
390 * @author gbastien
391 */
392 final class CTFStructField extends CtfTmfEventField {
393
394 /**
395 * Constructor for CTFStringField.
396 *
397 * @param strValue
398 * The string value of this field
399 * @param name
400 * The name of this field
401 */
402 CTFStructField(String name, CtfTmfEventField[] fields) {
403 super(name, fields, fields);
404 }
405
406 @Override
407 public CtfTmfEventField[] getValue() {
408 return (CtfTmfEventField[]) super.getValue();
409 }
410
411 @Override
412 public String toString() {
413 return getName() + '=' + Arrays.toString(getValue());
414 }
415 }
416
417 /* Implement other possible fields types here... */
This page took 0.04047 seconds and 6 git commands to generate.