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