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