TMF: Fix for displaying arrays in the events properties
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2011 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
12 * Bernd Hufmann - Add Enum field handling
13 *
14 *******************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDeclaration;
22 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
23 import org.eclipse.linuxtools.ctf.core.event.types.Definition;
24 import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition;
25 import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition;
26 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration;
27 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
28 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDeclaration;
29 import org.eclipse.linuxtools.ctf.core.event.types.SequenceDefinition;
30 import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition;
31 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
32
33 /**
34 * The CTF implementation of the TMF event field model
35 *
36 * @version 2.0
37 * @author Matthew Khouzam
38 * @author Alexandre Montplaisir
39 */
40 public abstract class CtfTmfEventField implements ITmfEventField {
41
42 // ------------------------------------------------------------------------
43 // Class attributes
44 // ------------------------------------------------------------------------
45
46 /** @since 1.2 */
47 protected static final int FIELDTYPE_INTEGER = 0;
48
49 /** @since 1.2 */
50 protected static final int FIELDTYPE_STRING = 1;
51
52 /** @since 1.2 */
53 protected static final int FIELDTYPE_INTEGER_ARRAY = 2;
54
55 /** @since 1.2 */
56 protected static final int FIELDTYPE_FLOAT = 3;
57
58 /** @since 2.0 */
59 protected static final int FIELDTYPE_ENUM = 4;
60
61 // ------------------------------------------------------------------------
62 // Attributes
63 // ------------------------------------------------------------------------
64
65 /** The name of this field */
66 protected final String name;
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 */
79 protected CtfTmfEventField(String name) {
80 /* Strip the underscore */
81 if (name.startsWith("_")) { //$NON-NLS-1$
82 this.name = name.substring(1);
83 } else {
84 this.name = name;
85 }
86 }
87
88 // ------------------------------------------------------------------------
89 // Getters/Setters/Predicates
90 // ------------------------------------------------------------------------
91
92 @Override
93 public String getName() {
94 return this.name;
95 }
96
97 // ------------------------------------------------------------------------
98 // Operations
99 // ------------------------------------------------------------------------
100
101 /**
102 * Factory method to instantiate CtfTmfEventField objects.
103 *
104 * @param fieldDef
105 * The CTF Definition of this event field
106 * @param fieldName
107 * String The name to assign to this field
108 * @return The resulting CtfTmfEventField object
109 */
110 public static CtfTmfEventField parseField(Definition fieldDef,
111 String fieldName) {
112 CtfTmfEventField field = null;
113
114 /* Determine the Definition type */
115 if (fieldDef instanceof IntegerDefinition) {
116 IntegerDefinition intDef = (IntegerDefinition) fieldDef;
117 int base = intDef.getDeclaration().getBase();
118 field = new CTFIntegerField(intDef.getValue(), fieldName, base);
119
120 } else if (fieldDef instanceof EnumDefinition) {
121 EnumDefinition enumDef = (EnumDefinition) fieldDef;
122 field = new CTFEnumField(new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()), fieldName);
123
124 } else if (fieldDef instanceof StringDefinition) {
125 field = new CTFStringField(
126 ((StringDefinition) fieldDef).getValue(), fieldName);
127
128 } else if (fieldDef instanceof ArrayDefinition) {
129 ArrayDefinition arrayDef = (ArrayDefinition) fieldDef;
130 ArrayDeclaration arrayDecl = arrayDef.getDeclaration();
131
132 if (arrayDef.isString()) {
133 /* This is an array of UTF-8 bytes, a.k.a. a String! */
134 field = new CTFStringField(fieldDef.toString(), fieldName);
135
136 } else if (arrayDecl.getElementType() instanceof IntegerDeclaration) {
137 /* This is a an array of CTF Integers */
138 long[] values = new long[arrayDecl.getLength()];
139 for (int i = 0; i < arrayDecl.getLength(); i++) {
140 values[i] = ((IntegerDefinition) arrayDef.getElem(i))
141 .getValue();
142 }
143 field = new CTFIntegerArrayField(values, fieldName);
144 }
145 /* Add other types of arrays here */
146
147 } else if (fieldDef instanceof SequenceDefinition) {
148 SequenceDefinition seqDef = (SequenceDefinition) fieldDef;
149 SequenceDeclaration seqDecl = seqDef.getDeclaration();
150
151 if (seqDef.getLength() == 0) {
152 /* Some sequences have length = 0. Simply use an empty string */
153 field = new CTFStringField("", fieldName); //$NON-NLS-1$
154 } else if (seqDef.isString()) {
155 /* Interpret this sequence as a String */
156 field = new CTFStringField(seqDef.toString(), fieldName);
157 } else if (seqDecl.getElementType() instanceof IntegerDeclaration) {
158 /* Sequence of integers => CTFIntegerArrayField */
159 long[] values = new long[seqDef.getLength()];
160 for (int i = 0; i < seqDef.getLength(); i++) {
161 values[i] = ((IntegerDefinition) seqDef.getElem(i))
162 .getValue();
163 }
164 field = new CTFIntegerArrayField(values, fieldName);
165 }
166 /* Add other Sequence types here */
167
168 } else if (fieldDef instanceof FloatDefinition) {
169 FloatDefinition floatDef = (FloatDefinition) fieldDef;
170 field = new CTFFloatField(floatDef.getValue(), fieldName);
171 }
172
173 return field;
174 }
175
176 /**
177 * Copy factory. Create a new field by (deep-) copying the information in an
178 * existing one.
179 *
180 * @param other
181 * The other CtfTmfEventField to copy
182 * @return The new CtfTmfEventField
183 */
184 public static CtfTmfEventField copyFrom(CtfTmfEventField other) {
185 switch (other.getFieldType()) {
186 case FIELDTYPE_INTEGER:
187 CTFIntegerField intOther = (CTFIntegerField) other;
188 return new CTFIntegerField(intOther.getValue(), intOther.name,
189 intOther.getBase());
190 case FIELDTYPE_STRING:
191 return new CTFStringField(((CTFStringField) other).getValue(),
192 other.name);
193 case FIELDTYPE_INTEGER_ARRAY:
194 return new CTFIntegerArrayField(
195 ((CTFIntegerArrayField) other).getLongValues(), other.name);
196 case FIELDTYPE_FLOAT:
197 return new CTFFloatField(((CTFFloatField) other).getValue(),
198 other.name);
199 case FIELDTYPE_ENUM:
200 return new CTFEnumField(((CTFEnumField) other).getValue(), other.name);
201 default:
202 return null;
203 }
204 }
205
206 @Override
207 public CtfTmfEventField clone() {
208 return CtfTmfEventField.copyFrom(this);
209 }
210
211 // ------------------------------------------------------------------------
212 // Abstract methods (to be implemented by each specific field type)
213 // ------------------------------------------------------------------------
214
215 /**
216 * Return the int representing this field's value type
217 *
218 * @return The field type
219 */
220 public abstract int getFieldType();
221
222 /**
223 * Return this field's value. You can cast it to the correct type depending
224 * on what getFieldType says.
225 *
226 * @return The field's value
227 */
228 @Override
229 public abstract Object getValue();
230
231 // ------------------------------------------------------------------------
232 // Other methods defined by ITmfEventField, but not used here.
233 // CTF fields do not have sub-fields (yet!)
234 // ------------------------------------------------------------------------
235
236 @Override
237 public String[] getFieldNames() {
238 return null;
239 }
240
241 @Override
242 public String getFieldName(int index) {
243 return null;
244 }
245
246 @Override
247 public ITmfEventField[] getFields() {
248 return null;
249 }
250
251 @Override
252 public ITmfEventField getField(String fieldName) {
253 return null;
254 }
255
256 @Override
257 public ITmfEventField getField(int index) {
258 return null;
259 }
260 }
261
262 /**
263 * The CTF field implementation for integer fields.
264 *
265 * @author alexmont
266 */
267 final class CTFIntegerField extends CtfTmfEventField {
268
269 private final long longValue;
270 private final int base;
271
272 /**
273 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
274 * Java parser this is interpreted as a long.
275 *
276 * @param longValue
277 * The integer value of this field
278 * @param name
279 * The name of this field
280 */
281 CTFIntegerField(long longValue, String name, int base) {
282 super(name);
283 this.longValue = longValue;
284 this.base = base;
285 }
286
287 /**
288 * Return the integer's base. (Not made public until it's needed.)
289 *
290 * @return The base, usually 10 or 16.
291 */
292 int getBase() {
293 return base;
294 }
295
296 @Override
297 public int getFieldType() {
298 return FIELDTYPE_INTEGER;
299 }
300
301 @Override
302 public Long getValue() {
303 return this.longValue;
304 }
305
306 @Override
307 public String toString() {
308 StringBuilder sb = new StringBuilder(name);
309 sb.append('=');
310
311 /* Format the number correctly according to the integer's base */
312 switch (base) {
313 case 2:
314 sb.append("0b"); //$NON-NLS-1$
315 sb.append(Long.toBinaryString(longValue));
316 break;
317 case 8:
318 sb.append('0');
319 sb.append(Long.toOctalString(longValue));
320 break;
321 case 10:
322 sb.append(longValue);
323 break;
324 case 16:
325 sb.append("0x"); //$NON-NLS-1$
326 sb.append(Long.toHexString(longValue));
327 break;
328 default:
329 /* Non-standard base, we'll just print it as a decimal number */
330 sb.append(longValue);
331 break;
332 }
333 return sb.toString();
334 }
335 }
336
337 /**
338 * The CTF field implementation for string fields
339 *
340 * @author alexmont
341 */
342 final class CTFStringField extends CtfTmfEventField {
343
344 private final String strValue;
345
346 /**
347 * Constructor for CTFStringField.
348 *
349 * @param strValue
350 * The string value of this field
351 * @param name
352 * The name of this field
353 */
354 CTFStringField(String strValue, String name) {
355 super(name);
356 this.strValue = strValue;
357 }
358
359 @Override
360 public int getFieldType() {
361 return FIELDTYPE_STRING;
362 }
363
364 @Override
365 public String getValue() {
366 return this.strValue;
367 }
368
369 @Override
370 public String toString() {
371 return name + '=' + strValue;
372 }
373 }
374
375 /**
376 * CTF field implementation for arrays of integers.
377 *
378 * @author alexmont
379 */
380 final class CTFIntegerArrayField extends CtfTmfEventField {
381
382 private final long[] longValues;
383
384 /**
385 * Constructor for CTFIntegerArrayField.
386 *
387 * @param longValues
388 * The array of integers (as longs) that compose this field's
389 * value
390 * @param name
391 * The name of this field
392 */
393 CTFIntegerArrayField(long[] longValues, String name) {
394 super(name);
395 this.longValues = longValues;
396 }
397
398 @Override
399 public int getFieldType() {
400 return FIELDTYPE_INTEGER_ARRAY;
401 }
402
403 /**
404 * Gets the values of the array
405 * @return the values in the array
406 *
407 * @since 2.0
408 */
409 long[] getLongValues() {
410 return this.longValues;
411 }
412
413 @Override
414 public List<Long> getValue() {
415 List<Long> retVal = new ArrayList<Long>();
416 for( Long l : longValues){
417 retVal.add(l);
418 }
419 return retVal;
420 }
421
422 @Override
423 public String toString() {
424 StringBuffer buffer = new StringBuffer();
425 buffer.append(name);
426 buffer.append('=');
427 buffer.append(getValue());
428 return buffer.toString();
429 }
430 }
431
432 /**
433 * CTF field implementation for floats.
434 *
435 * @author emathko
436 */
437 final class CTFFloatField extends CtfTmfEventField {
438
439 private final Double value;
440
441 /**
442 * Constructor for CTFFloatField.
443 *
444 * @param value
445 * The float value (actually a double) of this field
446 * @param name
447 * The name of this field
448 */
449 protected CTFFloatField(double value, String name) {
450 super(name);
451 this.value = value;
452 }
453
454 @Override
455 public int getFieldType() {
456 return FIELDTYPE_FLOAT;
457 }
458
459 @Override
460 public Double getValue() {
461 return this.value;
462 }
463
464 @Override
465 public String toString() {
466 return name + '=' + value;
467 }
468 }
469
470 /**
471 * The CTF field implementation for Enum fields
472 *
473 * @author Bernd Hufmann
474 */
475 final class CTFEnumField extends CtfTmfEventField {
476
477 private final CtfEnumPair value;
478
479 /**
480 * Constructor for CTFEnumField.
481 *
482 * @param enumValue
483 * The Enum value consisting of a pair of Enum value name and its long value
484 * @param name
485 * The name of this field
486 */
487 CTFEnumField(CtfEnumPair enumValue, String name) {
488 super(name);
489 this.value = new CtfEnumPair(enumValue.getFirst(), enumValue.getSecond().longValue());
490 }
491
492 @Override
493 public int getFieldType() {
494 return FIELDTYPE_ENUM;
495 }
496
497 @Override
498 public CtfEnumPair getValue() {
499 return this.value;
500 }
501
502 @Override
503 public String toString() {
504 return name + '=' + value.toString();
505 }
506 }
507
508 /* Implement other possible fields types here... */
This page took 0.083697 seconds and 6 git commands to generate.