Tmf: improve validation in GDB traces and externalize strings
[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
a3fc8213 48 // ------------------------------------------------------------------------
7558a1e1 49 // Constructor
a3fc8213
AM
50 // ------------------------------------------------------------------------
51
b1baa808 52 /**
7558a1e1
AM
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
68b18f2f
AM
58 * @param value
59 * The value of this field. Its type should match the field type.
81ed27a8
MK
60 * @param fields
61 * The children fields. Useful for composite fields
68b18f2f 62 * @since 2.0
b1baa808 63 */
81ed27a8 64 protected CtfTmfEventField(String name, Object value, ITmfEventField[] fields) {
68b18f2f
AM
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,
81ed27a8 68 fields);
a3fc8213
AM
69 }
70
71 // ------------------------------------------------------------------------
72 // Operations
73 // ------------------------------------------------------------------------
74
b1baa808 75 /**
7558a1e1
AM
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
b1baa808 83 */
a3fc8213
AM
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) {
367bcd2b
AM
90 IntegerDefinition intDef = (IntegerDefinition) fieldDef;
91 int base = intDef.getDeclaration().getBase();
68b18f2f 92 field = new CTFIntegerField(fieldName, intDef.getValue(), base);
a3fc8213 93
21fb02fa
MK
94 } else if (fieldDef instanceof EnumDefinition) {
95 EnumDefinition enumDef = (EnumDefinition) fieldDef;
68b18f2f 96 field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()));
21fb02fa 97
a3fc8213 98 } else if (fieldDef instanceof StringDefinition) {
68b18f2f
AM
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());
a3fc8213
AM
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! */
68b18f2f 111 field = new CTFStringField(fieldName, fieldDef.toString());
a3fc8213
AM
112
113 } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
114 /* This is a an array of CTF Integers */
68b18f2f 115 List<Long> values = new ArrayList<Long>(arrayDecl.getLength());
a3fc8213 116 for (int i = 0; i < arrayDecl.getLength(); i++) {
68b18f2f 117 values.add(((IntegerDefinition) arrayDef.getElem(i)).getValue());
a3fc8213 118 }
404b264a 119 field = new CTFIntegerArrayField(fieldName, values, ((IntegerDeclaration) arrayDecl.getElementType()).getBase());
a3fc8213
AM
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 */
68b18f2f 129 field = new CTFStringField(fieldName, ""); //$NON-NLS-1$
a3fc8213
AM
130 } else if (seqDef.isString()) {
131 /* Interpret this sequence as a String */
68b18f2f 132 field = new CTFStringField(fieldName, seqDef.toString());
a3fc8213
AM
133 } else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
134 /* Sequence of integers => CTFIntegerArrayField */
68b18f2f 135 List<Long> values = new ArrayList<Long>(seqDef.getLength());
a3fc8213 136 for (int i = 0; i < seqDef.getLength(); i++) {
68b18f2f 137 values.add(((IntegerDefinition) seqDef.getElem(i)).getValue());
a3fc8213 138 }
404b264a 139 field = new CTFIntegerArrayField(fieldName, values, ((IntegerDeclaration) seqDecl.getElementType()).getBase());
a3fc8213
AM
140 }
141 /* Add other Sequence types here */
367bcd2b 142
7a6cee1a
GB
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()]));
a0e9eac8 158
404b264a
GB
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) {
51cc7ef4
GB
165 CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
166 field = new CTFVariantField(fieldName, subField);
404b264a
GB
167 } else {
168 /* A safe-guard, but curFieldDef should never be null */
169 field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
170 }
171
172 } else {
173 /* Safe-guard, to avoid null exceptions later, field is expected not to be null */
174 field = new CTFStringField(fieldName, Messages.TmfEventField_UnsupportedType + fieldDef.getClass().toString());
a3fc8213 175 }
a3fc8213
AM
176 return field;
177 }
178
a3fc8213 179 @Override
68b18f2f 180 public String toString() {
51cc7ef4 181 return getName() + '=' + getFormattedValue();
a3fc8213
AM
182 }
183
404b264a
GB
184 /**
185 * Print a numeric value as a string in a given base
186 *
187 * @param value
188 * The value to print as string
189 * @param base
190 * The base for this value
191 * @return formatted number string
192 * @since 2.0
193 */
194 protected final static String formatNumber(long value, int base) {
195 String s;
196 /* Format the number correctly according to the integer's base */
197 switch (base) {
198 case 2:
199 s = "0b" + Long.toBinaryString(value); //$NON-NLS-1$
200 break;
201 case 8:
202 s = "0" + Long.toOctalString(value); //$NON-NLS-1$
203 break;
204 case 10:
205 s = Long.toString(value);
206 break;
207 case 16:
208 s = "0x" + Long.toHexString(value); //$NON-NLS-1$
209 break;
210 default:
211 /* Non-standard base, we'll just print it as a decimal number */
212 s = Long.toString(value);
213 break;
214 }
215 return s;
216 }
217
a3fc8213
AM
218}
219
220/**
7558a1e1
AM
221 * The CTF field implementation for integer fields.
222 *
223 * @author alexmont
a3fc8213
AM
224 */
225final class CTFIntegerField extends CtfTmfEventField {
226
367bcd2b 227 private final int base;
a3fc8213
AM
228
229 /**
230 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
231 * Java parser this is interpreted as a long.
7558a1e1
AM
232 *
233 * @param longValue
234 * The integer value of this field
235 * @param name
236 * The name of this field
a3fc8213 237 */
68b18f2f 238 CTFIntegerField(String name, long longValue, int base) {
81ed27a8 239 super(name, longValue, null);
367bcd2b
AM
240 this.base = base;
241 }
242
a3fc8213
AM
243 @Override
244 public Long getValue() {
68b18f2f 245 return (Long) super.getValue();
a3fc8213
AM
246 }
247
8f86c552
GB
248 @Override
249 public String getFormattedValue() {
250 return formatNumber(getValue(), base);
251 }
252
a3fc8213
AM
253}
254
255/**
7558a1e1
AM
256 * The CTF field implementation for string fields
257 *
258 * @author alexmont
a3fc8213
AM
259 */
260final class CTFStringField extends CtfTmfEventField {
261
b1baa808
MK
262 /**
263 * Constructor for CTFStringField.
7558a1e1
AM
264 *
265 * @param strValue
266 * The string value of this field
267 * @param name
268 * The name of this field
b1baa808 269 */
68b18f2f 270 CTFStringField(String name, String strValue) {
81ed27a8 271 super(name, strValue, null);
a3fc8213
AM
272 }
273
a3fc8213
AM
274 @Override
275 public String getValue() {
68b18f2f 276 return (String) super.getValue();
a3fc8213
AM
277 }
278}
279
280/**
7558a1e1
AM
281 * CTF field implementation for arrays of integers.
282 *
283 * @author alexmont
a3fc8213
AM
284 */
285final class CTFIntegerArrayField extends CtfTmfEventField {
286
404b264a 287 private final int base;
8f86c552 288 private String formattedValue = null;
404b264a 289
b1baa808
MK
290 /**
291 * Constructor for CTFIntegerArrayField.
7558a1e1
AM
292 *
293 * @param longValues
294 * The array of integers (as longs) that compose this field's
295 * value
296 * @param name
297 * The name of this field
b1baa808 298 */
404b264a 299 CTFIntegerArrayField(String name, List<Long> longValues, int base) {
81ed27a8 300 super(name, longValues, null);
404b264a 301 this.base = base;
a3fc8213
AM
302 }
303
a6223d74
MK
304 @Override
305 public List<Long> getValue() {
68b18f2f 306 return (List<Long>) super.getValue();
a3fc8213 307 }
404b264a 308
8f86c552
GB
309 @Override
310 public String getFormattedValue() {
311 if (formattedValue == null) {
312 List<String> strings = new ArrayList<String>();
313 for (Long value : getValue()) {
314 strings.add(formatNumber(value, base));
315 }
316 formattedValue = strings.toString();
317 }
318 return formattedValue;
319 }
320
a3fc8213
AM
321}
322
b1baa808 323/**
7558a1e1
AM
324 * CTF field implementation for floats.
325 *
326 * @author emathko
b1baa808 327 */
a04464b1
MK
328final class CTFFloatField extends CtfTmfEventField {
329
b1baa808
MK
330 /**
331 * Constructor for CTFFloatField.
7558a1e1
AM
332 *
333 * @param value
334 * The float value (actually a double) of this field
335 * @param name
336 * The name of this field
b1baa808 337 */
68b18f2f 338 protected CTFFloatField(String name, double value) {
81ed27a8 339 super(name, value, null);
a04464b1
MK
340 }
341
a04464b1 342 @Override
81c8e6f7 343 public Double getValue() {
68b18f2f 344 return (Double) super.getValue();
a04464b1 345 }
a04464b1 346}
7558a1e1 347
d4a8d935
BH
348/**
349 * The CTF field implementation for Enum fields
350 *
351 * @author Bernd Hufmann
352 */
353final class CTFEnumField extends CtfTmfEventField {
354
d4a8d935
BH
355 /**
356 * Constructor for CTFEnumField.
357 *
358 * @param enumValue
359 * The Enum value consisting of a pair of Enum value name and its long value
360 * @param name
361 * The name of this field
362 */
68b18f2f
AM
363 CTFEnumField(String name, CtfEnumPair enumValue) {
364 super(name, new CtfEnumPair(enumValue.getFirst(),
81ed27a8 365 enumValue.getSecond().longValue()), null);
d4a8d935
BH
366 }
367
d4a8d935 368 @Override
68b18f2f
AM
369 public CtfEnumPair getValue() {
370 return (CtfEnumPair) super.getValue();
d4a8d935
BH
371 }
372}
373
7a6cee1a 374/**
51cc7ef4 375 * The CTF field implementation for struct fields with sub-fields
7a6cee1a
GB
376 *
377 * @author gbastien
378 */
379final class CTFStructField extends CtfTmfEventField {
380
381 /**
51cc7ef4 382 * Constructor for CTFStructField.
7a6cee1a 383 *
51cc7ef4
GB
384 * @param fields
385 * The children of this field
7a6cee1a
GB
386 * @param name
387 * The name of this field
388 */
389 CTFStructField(String name, CtfTmfEventField[] fields) {
81ed27a8 390 super(name, fields, fields);
7a6cee1a
GB
391 }
392
7a6cee1a
GB
393 @Override
394 public CtfTmfEventField[] getValue() {
395 return (CtfTmfEventField[]) super.getValue();
396 }
397
398 @Override
51cc7ef4
GB
399 public String getFormattedValue() {
400 return Arrays.toString(getValue());
7a6cee1a 401 }
51cc7ef4
GB
402
403}
404
405/**
406 * The CTF field implementation for variant fields its child
407 *
408 * @author gbastien
409 */
410final class CTFVariantField extends CtfTmfEventField {
411
412 /**
413 * Constructor for CTFVariantField.
414 *
415 * @param field
416 * The field selected for this variant
417 * @param name
418 * The name of this field
419 */
420 CTFVariantField(String name, CtfTmfEventField field) {
421 super(name, field, new CtfTmfEventField[]{ field });
422 }
423
424 @Override
425 public CtfTmfEventField getValue() {
426 return (CtfTmfEventField) super.getValue();
427 }
428
7a6cee1a
GB
429}
430
a3fc8213 431/* Implement other possible fields types here... */
This page took 0.063782 seconds and 5 git commands to generate.