Commit | Line | Data |
---|---|---|
a3fc8213 AM |
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 | * | |
d4a8d935 BH |
9 | * Contributors: |
10 | * Matthew Khouzam - Initial API and implementation | |
11 | * Alexendre Montplaisir - Initial API and implementation | |
12 | * Bernd Hufmann - Add Enum field handling | |
13 | * | |
a3fc8213 AM |
14 | *******************************************************************************/ |
15 | ||
16 | package org.eclipse.linuxtools.tmf.core.ctfadaptor; | |
17 | ||
a6223d74 MK |
18 | import java.util.ArrayList; |
19 | import java.util.List; | |
20 | ||
a3fc8213 AM |
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; | |
21fb02fa | 24 | import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition; |
a04464b1 | 25 | import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition; |
a3fc8213 AM |
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 | /** | |
7558a1e1 AM |
34 | * The CTF implementation of the TMF event field model |
35 | * | |
d4a8d935 | 36 | * @version 2.0 |
7558a1e1 | 37 | * @author Matthew Khouzam |
d09f973b | 38 | * @author Alexandre Montplaisir |
a3fc8213 AM |
39 | */ |
40 | public abstract class CtfTmfEventField implements ITmfEventField { | |
41 | ||
a1c6baa7 AM |
42 | // ------------------------------------------------------------------------ |
43 | // Class attributes | |
44 | // ------------------------------------------------------------------------ | |
45 | ||
77c4a6df | 46 | /** @since 1.2 */ |
a1c6baa7 AM |
47 | protected static final int FIELDTYPE_INTEGER = 0; |
48 | ||
77c4a6df | 49 | /** @since 1.2 */ |
a1c6baa7 AM |
50 | protected static final int FIELDTYPE_STRING = 1; |
51 | ||
77c4a6df | 52 | /** @since 1.2 */ |
a1c6baa7 AM |
53 | protected static final int FIELDTYPE_INTEGER_ARRAY = 2; |
54 | ||
77c4a6df | 55 | /** @since 1.2 */ |
a1c6baa7 AM |
56 | protected static final int FIELDTYPE_FLOAT = 3; |
57 | ||
d4a8d935 BH |
58 | /** @since 2.0 */ |
59 | protected static final int FIELDTYPE_ENUM = 4; | |
60 | ||
a3fc8213 AM |
61 | // ------------------------------------------------------------------------ |
62 | // Attributes | |
63 | // ------------------------------------------------------------------------ | |
64 | ||
6f4e8ec0 | 65 | /** The name of this field */ |
a3fc8213 AM |
66 | protected final String name; |
67 | ||
68 | // ------------------------------------------------------------------------ | |
7558a1e1 | 69 | // Constructor |
a3fc8213 AM |
70 | // ------------------------------------------------------------------------ |
71 | ||
b1baa808 | 72 | /** |
7558a1e1 AM |
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 | |
b1baa808 | 78 | */ |
a3fc8213 | 79 | protected CtfTmfEventField(String name) { |
7558a1e1 | 80 | /* Strip the underscore */ |
21fb02fa | 81 | if (name.startsWith("_")) { //$NON-NLS-1$ |
f13dfe18 AM |
82 | this.name = name.substring(1); |
83 | } else { | |
84 | this.name = name; | |
85 | } | |
a3fc8213 AM |
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 | ||
b1baa808 | 101 | /** |
7558a1e1 AM |
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 | |
b1baa808 | 109 | */ |
a3fc8213 AM |
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) { | |
367bcd2b AM |
116 | IntegerDefinition intDef = (IntegerDefinition) fieldDef; |
117 | int base = intDef.getDeclaration().getBase(); | |
118 | field = new CTFIntegerField(intDef.getValue(), fieldName, base); | |
a3fc8213 | 119 | |
21fb02fa MK |
120 | } else if (fieldDef instanceof EnumDefinition) { |
121 | EnumDefinition enumDef = (EnumDefinition) fieldDef; | |
d4a8d935 | 122 | field = new CTFEnumField(new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()), fieldName); |
21fb02fa | 123 | |
a3fc8213 AM |
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++) { | |
21fb02fa MK |
140 | values[i] = ((IntegerDefinition) arrayDef.getElem(i)) |
141 | .getValue(); | |
a3fc8213 AM |
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++) { | |
21fb02fa MK |
161 | values[i] = ((IntegerDefinition) seqDef.getElem(i)) |
162 | .getValue(); | |
a3fc8213 AM |
163 | } |
164 | field = new CTFIntegerArrayField(values, fieldName); | |
165 | } | |
166 | /* Add other Sequence types here */ | |
367bcd2b | 167 | |
21fb02fa | 168 | } else if (fieldDef instanceof FloatDefinition) { |
a04464b1 | 169 | FloatDefinition floatDef = (FloatDefinition) fieldDef; |
21fb02fa | 170 | field = new CTFFloatField(floatDef.getValue(), fieldName); |
a3fc8213 | 171 | } |
a04464b1 | 172 | |
a3fc8213 AM |
173 | return field; |
174 | } | |
175 | ||
b1baa808 | 176 | /** |
7558a1e1 AM |
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 | |
b1baa808 | 183 | */ |
a3fc8213 AM |
184 | public static CtfTmfEventField copyFrom(CtfTmfEventField other) { |
185 | switch (other.getFieldType()) { | |
a1c6baa7 | 186 | case FIELDTYPE_INTEGER: |
367bcd2b | 187 | CTFIntegerField intOther = (CTFIntegerField) other; |
21fb02fa MK |
188 | return new CTFIntegerField(intOther.getValue(), intOther.name, |
189 | intOther.getBase()); | |
a1c6baa7 | 190 | case FIELDTYPE_STRING: |
21fb02fa MK |
191 | return new CTFStringField(((CTFStringField) other).getValue(), |
192 | other.name); | |
a1c6baa7 | 193 | case FIELDTYPE_INTEGER_ARRAY: |
21fb02fa | 194 | return new CTFIntegerArrayField( |
a6223d74 | 195 | ((CTFIntegerArrayField) other).getLongValues(), other.name); |
a1c6baa7 | 196 | case FIELDTYPE_FLOAT: |
21fb02fa MK |
197 | return new CTFFloatField(((CTFFloatField) other).getValue(), |
198 | other.name); | |
d4a8d935 BH |
199 | case FIELDTYPE_ENUM: |
200 | return new CTFEnumField(((CTFEnumField) other).getValue(), other.name); | |
a3fc8213 AM |
201 | default: |
202 | return null; | |
203 | } | |
204 | } | |
205 | ||
206 | @Override | |
207 | public CtfTmfEventField clone() { | |
208 | return CtfTmfEventField.copyFrom(this); | |
209 | } | |
210 | ||
7558a1e1 AM |
211 | // ------------------------------------------------------------------------ |
212 | // Abstract methods (to be implemented by each specific field type) | |
213 | // ------------------------------------------------------------------------ | |
214 | ||
a3fc8213 AM |
215 | /** |
216 | * Return the int representing this field's value type | |
ce2388e0 | 217 | * |
7558a1e1 AM |
218 | * @return The field type |
219 | */ | |
a3fc8213 AM |
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. | |
ce2388e0 | 225 | * |
7558a1e1 | 226 | * @return The field's value |
a3fc8213 AM |
227 | */ |
228 | @Override | |
229 | public abstract Object getValue(); | |
230 | ||
7558a1e1 AM |
231 | // ------------------------------------------------------------------------ |
232 | // Other methods defined by ITmfEventField, but not used here. | |
233 | // CTF fields do not have sub-fields (yet!) | |
234 | // ------------------------------------------------------------------------ | |
81c8e6f7 | 235 | |
a3fc8213 AM |
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 | /** | |
7558a1e1 AM |
263 | * The CTF field implementation for integer fields. |
264 | * | |
265 | * @author alexmont | |
a3fc8213 AM |
266 | */ |
267 | final class CTFIntegerField extends CtfTmfEventField { | |
268 | ||
269 | private final long longValue; | |
367bcd2b | 270 | private final int base; |
a3fc8213 AM |
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. | |
7558a1e1 AM |
275 | * |
276 | * @param longValue | |
277 | * The integer value of this field | |
278 | * @param name | |
279 | * The name of this field | |
a3fc8213 | 280 | */ |
367bcd2b | 281 | CTFIntegerField(long longValue, String name, int base) { |
a3fc8213 AM |
282 | super(name); |
283 | this.longValue = longValue; | |
367bcd2b AM |
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; | |
a3fc8213 AM |
294 | } |
295 | ||
296 | @Override | |
297 | public int getFieldType() { | |
a1c6baa7 | 298 | return FIELDTYPE_INTEGER; |
a3fc8213 AM |
299 | } |
300 | ||
301 | @Override | |
302 | public Long getValue() { | |
303 | return this.longValue; | |
304 | } | |
305 | ||
a3fc8213 AM |
306 | @Override |
307 | public String toString() { | |
367bcd2b AM |
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(); | |
a3fc8213 AM |
334 | } |
335 | } | |
336 | ||
337 | /** | |
7558a1e1 AM |
338 | * The CTF field implementation for string fields |
339 | * | |
340 | * @author alexmont | |
a3fc8213 AM |
341 | */ |
342 | final class CTFStringField extends CtfTmfEventField { | |
343 | ||
344 | private final String strValue; | |
345 | ||
b1baa808 MK |
346 | /** |
347 | * Constructor for CTFStringField. | |
7558a1e1 AM |
348 | * |
349 | * @param strValue | |
350 | * The string value of this field | |
351 | * @param name | |
352 | * The name of this field | |
b1baa808 | 353 | */ |
a3fc8213 AM |
354 | CTFStringField(String strValue, String name) { |
355 | super(name); | |
356 | this.strValue = strValue; | |
357 | } | |
358 | ||
359 | @Override | |
360 | public int getFieldType() { | |
a1c6baa7 | 361 | return FIELDTYPE_STRING; |
a3fc8213 AM |
362 | } |
363 | ||
364 | @Override | |
365 | public String getValue() { | |
366 | return this.strValue; | |
367 | } | |
368 | ||
a3fc8213 AM |
369 | @Override |
370 | public String toString() { | |
371 | return name + '=' + strValue; | |
372 | } | |
373 | } | |
374 | ||
375 | /** | |
7558a1e1 AM |
376 | * CTF field implementation for arrays of integers. |
377 | * | |
378 | * @author alexmont | |
a3fc8213 AM |
379 | */ |
380 | final class CTFIntegerArrayField extends CtfTmfEventField { | |
381 | ||
382 | private final long[] longValues; | |
383 | ||
b1baa808 MK |
384 | /** |
385 | * Constructor for CTFIntegerArrayField. | |
7558a1e1 AM |
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 | |
b1baa808 | 392 | */ |
a3fc8213 AM |
393 | CTFIntegerArrayField(long[] longValues, String name) { |
394 | super(name); | |
395 | this.longValues = longValues; | |
396 | } | |
397 | ||
398 | @Override | |
399 | public int getFieldType() { | |
a1c6baa7 | 400 | return FIELDTYPE_INTEGER_ARRAY; |
a3fc8213 AM |
401 | } |
402 | ||
a6223d74 MK |
403 | /** |
404 | * Gets the values of the array | |
405 | * @return the values in the array | |
406 | * | |
407 | * @since 2.0 | |
408 | */ | |
409 | long[] getLongValues() { | |
a3fc8213 AM |
410 | return this.longValues; |
411 | } | |
412 | ||
a6223d74 MK |
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 | ||
a3fc8213 AM |
422 | @Override |
423 | public String toString() { | |
424 | StringBuffer buffer = new StringBuffer(); | |
a6223d74 MK |
425 | buffer.append(name); |
426 | buffer.append('='); | |
427 | buffer.append(getValue()); | |
428 | return buffer.toString(); | |
a3fc8213 AM |
429 | } |
430 | } | |
431 | ||
b1baa808 | 432 | /** |
7558a1e1 AM |
433 | * CTF field implementation for floats. |
434 | * | |
435 | * @author emathko | |
b1baa808 | 436 | */ |
a04464b1 MK |
437 | final class CTFFloatField extends CtfTmfEventField { |
438 | ||
7558a1e1 AM |
439 | private final Double value; |
440 | ||
b1baa808 MK |
441 | /** |
442 | * Constructor for CTFFloatField. | |
7558a1e1 AM |
443 | * |
444 | * @param value | |
445 | * The float value (actually a double) of this field | |
446 | * @param name | |
447 | * The name of this field | |
b1baa808 | 448 | */ |
21fb02fa | 449 | protected CTFFloatField(double value, String name) { |
a04464b1 MK |
450 | super(name); |
451 | this.value = value; | |
452 | } | |
453 | ||
454 | @Override | |
455 | public int getFieldType() { | |
a1c6baa7 | 456 | return FIELDTYPE_FLOAT; |
a04464b1 MK |
457 | } |
458 | ||
459 | @Override | |
81c8e6f7 | 460 | public Double getValue() { |
a04464b1 MK |
461 | return this.value; |
462 | } | |
463 | ||
464 | @Override | |
21fb02fa | 465 | public String toString() { |
a04464b1 MK |
466 | return name + '=' + value; |
467 | } | |
a04464b1 | 468 | } |
7558a1e1 | 469 | |
d4a8d935 BH |
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 | ||
a3fc8213 | 508 | /* Implement other possible fields types here... */ |