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