[CTF] Fix Struct toString fields in CtfTmfEventFields
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2011-2013 Ericsson
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 * Alexendre Montplaisir - Initial API and implementation, extend TmfEventField
12 * Bernd Hufmann - Add Enum field handling
13 * Geneviève Bastien - Add support for Struct fields
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.tmf.core.event.ITmfEventField;
35 import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
36
37 /**
38 * The CTF implementation of the TMF event field model
39 *
40 * @version 2.0
41 * @author Matthew Khouzam
42 * @author Alexandre Montplaisir
43 */
44 public abstract class CtfTmfEventField extends TmfEventField {
45
46 // ------------------------------------------------------------------------
47 // Class attributes
48 // ------------------------------------------------------------------------
49
50 /** @since 1.2 */
51 protected static final int FIELDTYPE_INTEGER = 0;
52
53 /** @since 1.2 */
54 protected static final int FIELDTYPE_STRING = 1;
55
56 /** @since 1.2 */
57 protected static final int FIELDTYPE_INTEGER_ARRAY = 2;
58
59 /** @since 1.2 */
60 protected static final int FIELDTYPE_FLOAT = 3;
61
62 /** @since 2.0 */
63 protected static final int FIELDTYPE_ENUM = 4;
64
65 /** @since 2.0 */
66 protected static final int FIELDTYPE_STRUCT = 5;
67
68 // ------------------------------------------------------------------------
69 // Constructor
70 // ------------------------------------------------------------------------
71
72 /**
73 * Standard constructor. Only to be used internally, call parseField() to
74 * generate a new field object.
75 *
76 * @param name
77 * The name of this field
78 * @param value
79 * The value of this field. Its type should match the field type.
80 * @param fields
81 * The children fields. Useful for composite fields
82 * @since 2.0
83 */
84 protected CtfTmfEventField(String name, Object value, ITmfEventField[] fields) {
85 super(/* Strip the underscore from the field name if there is one */
86 name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$
87 value,
88 fields);
89 }
90
91 // ------------------------------------------------------------------------
92 // Operations
93 // ------------------------------------------------------------------------
94
95 /**
96 * Factory method to instantiate CtfTmfEventField objects.
97 *
98 * @param fieldDef
99 * The CTF Definition of this event field
100 * @param fieldName
101 * String The name to assign to this field
102 * @return The resulting CtfTmfEventField object
103 */
104 public static CtfTmfEventField parseField(Definition 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);
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 ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
128
129 if (arrayDef.isString()) {
130 /* This is an array of UTF-8 bytes, a.k.a. a String! */
131 field = new CTFStringField(fieldName, fieldDef.toString());
132
133 } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
134 /* This is a an array of CTF Integers */
135 List<Long> values = new ArrayList<Long>(arrayDecl.getLength());
136 for (int i = 0; i < arrayDecl.getLength(); i++) {
137 values.add(((IntegerDefinition) arrayDef.getElem(i)).getValue());
138 }
139 field = new CTFIntegerArrayField(fieldName, values);
140 }
141 /* Add other types of arrays here */
142
143 } else if (fieldDef instanceof SequenceDefinition) {
144 SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
145 SequenceDeclaration seqDecl = seqDef.getDeclaration();
146
147 if (seqDef.getLength() == 0) {
148 /* Some sequences have length = 0. Simply use an empty string */
149 field = new CTFStringField(fieldName, ""); //$NON-NLS-1$
150 } else if (seqDef.isString()) {
151 /* Interpret this sequence as a String */
152 field = new CTFStringField(fieldName, seqDef.toString());
153 } else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
154 /* Sequence of integers => CTFIntegerArrayField */
155 List<Long> values = new ArrayList<Long>(seqDef.getLength());
156 for (int i = 0; i < seqDef.getLength(); i++) {
157 values.add(((IntegerDefinition) seqDef.getElem(i)).getValue());
158 }
159 field = new CTFIntegerArrayField(fieldName, values);
160 }
161 /* Add other Sequence types here */
162
163 } else if (fieldDef instanceof StructDefinition) {
164 StructDefinition strDef = (StructDefinition) fieldDef;
165
166 String curFieldName = null;
167 Definition curFieldDef;
168 CtfTmfEventField curField;
169 List<ITmfEventField> list = new ArrayList<ITmfEventField>();
170 /* Recursively parse the fields */
171 for (Entry<String, Definition> entry : strDef.getDefinitions().entrySet()) {
172 curFieldName = entry.getKey();
173 curFieldDef = entry.getValue();
174 curField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
175 list.add(curField);
176 }
177 field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
178 }
179 return field;
180 }
181
182 @Override
183 public String toString() {
184 return getName() + '=' + getValue().toString();
185 }
186
187 // ------------------------------------------------------------------------
188 // Abstract methods (to be implemented by each specific field type)
189 // ------------------------------------------------------------------------
190
191 /**
192 * Return the int representing this field's value type
193 *
194 * @return The field type
195 */
196 public abstract int getFieldType();
197
198 }
199
200 /**
201 * The CTF field implementation for integer fields.
202 *
203 * @author alexmont
204 */
205 final class CTFIntegerField extends CtfTmfEventField {
206
207 private final int base;
208
209 /**
210 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
211 * Java parser this is interpreted as a long.
212 *
213 * @param longValue
214 * The integer value of this field
215 * @param name
216 * The name of this field
217 */
218 CTFIntegerField(String name, long longValue, int base) {
219 super(name, longValue, null);
220 this.base = base;
221 }
222
223 @Override
224 public int getFieldType() {
225 return FIELDTYPE_INTEGER;
226 }
227
228 @Override
229 public Long getValue() {
230 return (Long) super.getValue();
231 }
232
233 /**
234 * Custom-format the integer values depending on their base.
235 */
236 @Override
237 public String toString() {
238 StringBuilder sb = new StringBuilder(getName());
239 sb.append('=');
240
241 /* Format the number correctly according to the integer's base */
242 switch (base) {
243 case 2:
244 sb.append("0b"); //$NON-NLS-1$
245 sb.append(Long.toBinaryString(getValue()));
246 break;
247 case 8:
248 sb.append('0');
249 sb.append(Long.toOctalString(getValue()));
250 break;
251 case 10:
252 sb.append(getValue());
253 break;
254 case 16:
255 sb.append("0x"); //$NON-NLS-1$
256 sb.append(Long.toHexString(getValue()));
257 break;
258 default:
259 /* Non-standard base, we'll just print it as a decimal number */
260 sb.append(getValue().toString());
261 break;
262 }
263 return sb.toString();
264 }
265 }
266
267 /**
268 * The CTF field implementation for string fields
269 *
270 * @author alexmont
271 */
272 final class CTFStringField extends CtfTmfEventField {
273
274 /**
275 * Constructor for CTFStringField.
276 *
277 * @param strValue
278 * The string value of this field
279 * @param name
280 * The name of this field
281 */
282 CTFStringField(String name, String strValue) {
283 super(name, strValue, null);
284 }
285
286 @Override
287 public int getFieldType() {
288 return FIELDTYPE_STRING;
289 }
290
291 @Override
292 public String getValue() {
293 return (String) super.getValue();
294 }
295 }
296
297 /**
298 * CTF field implementation for arrays of integers.
299 *
300 * @author alexmont
301 */
302 final class CTFIntegerArrayField extends CtfTmfEventField {
303
304 /**
305 * Constructor for CTFIntegerArrayField.
306 *
307 * @param longValues
308 * The array of integers (as longs) that compose this field's
309 * value
310 * @param name
311 * The name of this field
312 */
313 CTFIntegerArrayField(String name, List<Long> longValues) {
314 super(name, longValues, null);
315 }
316
317 @Override
318 public int getFieldType() {
319 return FIELDTYPE_INTEGER_ARRAY;
320 }
321
322 @Override
323 public List<Long> getValue() {
324 return (List<Long>) super.getValue();
325 }
326 }
327
328 /**
329 * CTF field implementation for floats.
330 *
331 * @author emathko
332 */
333 final class CTFFloatField extends CtfTmfEventField {
334
335 /**
336 * Constructor for CTFFloatField.
337 *
338 * @param value
339 * The float value (actually a double) of this field
340 * @param name
341 * The name of this field
342 */
343 protected CTFFloatField(String name, double value) {
344 super(name, value, null);
345 }
346
347 @Override
348 public int getFieldType() {
349 return FIELDTYPE_FLOAT;
350 }
351
352 @Override
353 public Double getValue() {
354 return (Double) super.getValue();
355 }
356 }
357
358 /**
359 * The CTF field implementation for Enum fields
360 *
361 * @author Bernd Hufmann
362 */
363 final class CTFEnumField extends CtfTmfEventField {
364
365 /**
366 * Constructor for CTFEnumField.
367 *
368 * @param enumValue
369 * The Enum value consisting of a pair of Enum value name and its long value
370 * @param name
371 * The name of this field
372 */
373 CTFEnumField(String name, CtfEnumPair enumValue) {
374 super(name, new CtfEnumPair(enumValue.getFirst(),
375 enumValue.getSecond().longValue()), null);
376 }
377
378 @Override
379 public int getFieldType() {
380 return FIELDTYPE_ENUM;
381 }
382
383 @Override
384 public CtfEnumPair getValue() {
385 return (CtfEnumPair) super.getValue();
386 }
387 }
388
389 /**
390 * The CTF field implementation for struct fields with sub-types
391 *
392 * @author gbastien
393 */
394 final class CTFStructField extends CtfTmfEventField {
395
396 /**
397 * Constructor for CTFStringField.
398 *
399 * @param strValue
400 * The string value of this field
401 * @param name
402 * The name of this field
403 */
404 CTFStructField(String name, CtfTmfEventField[] fields) {
405 super(name, fields, fields);
406 }
407
408 @Override
409 public int getFieldType() {
410 return FIELDTYPE_STRUCT;
411 }
412
413 @Override
414 public CtfTmfEventField[] getValue() {
415 return (CtfTmfEventField[]) super.getValue();
416 }
417
418 @Override
419 public String toString() {
420 return getName() + '=' + Arrays.toString(getValue());
421 }
422 }
423
424 /* Implement other possible fields types here... */
This page took 0.043954 seconds and 6 git commands to generate.