btf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / IntegerDeclaration.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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 * Simon Marchi - Initial API and implementation
12 * Marc-Andre Laperle - Add min/maximum for validation
13 *******************************************************************************/
14
15 package org.eclipse.linuxtools.ctf.core.event.types;
16
17 import java.math.BigInteger;
18 import java.nio.ByteOrder;
19
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
24 import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope;
25 import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
26
27 /**
28 * A CTF integer declaration.
29 *
30 * The declaration of a integer basic data type.
31 *
32 * @version 1.0
33 * @author Matthew Khouzam
34 * @author Simon Marchi
35 */
36 @NonNullByDefault
37 public class IntegerDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
38
39 // ------------------------------------------------------------------------
40 // Helpers
41 // ------------------------------------------------------------------------
42
43 /**
44 * unsigned int 32 bits big endian
45 *
46 * @since 3.0
47 */
48 public static final IntegerDeclaration UINT_32B_DECL = new IntegerDeclaration(32, false, ByteOrder.BIG_ENDIAN);
49 /**
50 * unsigned int 32 bits little endian
51 *
52 * @since 3.0
53 */
54 public static final IntegerDeclaration UINT_32L_DECL = new IntegerDeclaration(32, false, ByteOrder.LITTLE_ENDIAN);
55 /**
56 * signed int 32 bits big endian
57 *
58 * @since 3.0
59 */
60 public static final IntegerDeclaration INT_32B_DECL = new IntegerDeclaration(32, true, ByteOrder.BIG_ENDIAN);
61 /**
62 * signed int 32 bits little endian
63 *
64 * @since 3.0
65 */
66 public static final IntegerDeclaration INT_32L_DECL = new IntegerDeclaration(32, true, ByteOrder.LITTLE_ENDIAN);
67 /**
68 * unsigned int 32 bits big endian
69 *
70 * @since 3.0
71 */
72 public static final IntegerDeclaration UINT_64B_DECL = new IntegerDeclaration(64, false, ByteOrder.BIG_ENDIAN);
73 /**
74 * unsigned int 64 bits little endian
75 *
76 * @since 3.0
77 */
78 public static final IntegerDeclaration UINT_64L_DECL = new IntegerDeclaration(64, false, ByteOrder.LITTLE_ENDIAN);
79 /**
80 * signed int 64 bits big endian
81 *
82 * @since 3.0
83 */
84 public static final IntegerDeclaration INT_64B_DECL = new IntegerDeclaration(64, true, ByteOrder.BIG_ENDIAN);
85 /**
86 * signed int 64 bits little endian
87 *
88 * @since 3.0
89 */
90 public static final IntegerDeclaration INT_64L_DECL = new IntegerDeclaration(64, true, ByteOrder.LITTLE_ENDIAN);
91 /**
92 * unsigned 8 bit int endianness doesn't matter since it's 8 bits (byte)
93 *
94 * @since 3.0
95 */
96 public static final IntegerDeclaration UINT_8_DECL = new IntegerDeclaration(8, false, ByteOrder.BIG_ENDIAN);
97 /**
98 * signed 8 bit int endianness doesn't matter since it's 8 bits (char)
99 *
100 * @since 3.0
101 */
102 public static final IntegerDeclaration INT_8_DECL = new IntegerDeclaration(8, true, ByteOrder.BIG_ENDIAN);
103 /**
104 * Unsigned 5 bit int, used for event headers
105 *
106 * @since 3.1
107 */
108 public static final IntegerDeclaration UINT_5B_DECL = new IntegerDeclaration(5, false, ByteOrder.BIG_ENDIAN);
109 /**
110 * Unsigned 5 bit int, used for event headers
111 *
112 * @since 3.1
113 */
114 public static final IntegerDeclaration UINT_5L_DECL = new IntegerDeclaration(5, false, ByteOrder.LITTLE_ENDIAN);
115 /**
116 * Unsigned 5 bit int, used for event headers
117 *
118 * @since 3.1
119 */
120 public static final IntegerDeclaration UINT_27B_DECL = new IntegerDeclaration(27, false, ByteOrder.BIG_ENDIAN);
121 /**
122 * Unsigned 5 bit int, used for event headers
123 *
124 * @since 3.1
125 */
126 public static final IntegerDeclaration UINT_27L_DECL = new IntegerDeclaration(27, false, ByteOrder.LITTLE_ENDIAN);
127 /**
128 * Unsigned 16 bit int, used for event headers
129 *
130 * @since 3.1
131 */
132 public static final IntegerDeclaration UINT_16B_DECL = new IntegerDeclaration(16, false, ByteOrder.BIG_ENDIAN);
133 /**
134 * Unsigned 16 bit int, used for event headers
135 *
136 * @since 3.1
137 */
138 public static final IntegerDeclaration UINT_16L_DECL = new IntegerDeclaration(16, false, ByteOrder.LITTLE_ENDIAN);
139 // ------------------------------------------------------------------------
140 // Attributes
141 // ------------------------------------------------------------------------
142
143 private final int fLength;
144 private final boolean fSigned;
145 private final int fBase;
146 private final ByteOrder fByteOrder;
147 private final Encoding fEncoding;
148 private final long fAlignment;
149 private final String fClock;
150
151 // ------------------------------------------------------------------------
152 // Constructors
153 // ------------------------------------------------------------------------
154
155 /**
156 * Factory, some common types cached
157 *
158 * @param len
159 * The length in bits
160 * @param signed
161 * Is the integer signed? false == unsigned
162 * @param base
163 * The base (10-16 are most common)
164 * @param byteOrder
165 * Big-endian little-endian or other
166 * @param encoding
167 * ascii, utf8 or none.
168 * @param clock
169 * The clock path, can be null
170 * @param alignment
171 * The minimum alignment. Should be >= 1
172 * @return the integer declaration
173 * @since 3.0
174 */
175 public static IntegerDeclaration createDeclaration(int len, boolean signed, int base,
176 @Nullable ByteOrder byteOrder, Encoding encoding, String clock, long alignment) {
177 if (encoding.equals(Encoding.NONE) && (alignment == 8) && (clock.equals("")) && base == 10) { //$NON-NLS-1$
178 switch (len) {
179 case 5:
180 if (!signed) {
181 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
182 return UINT_5B_DECL;
183 }
184 return UINT_5L_DECL;
185 }
186 break;
187 case 8:
188 return signed ? INT_8_DECL : UINT_8_DECL;
189 case 16:
190 if (!signed) {
191 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
192 return UINT_16B_DECL;
193 }
194 return UINT_16L_DECL;
195 }
196 break;
197 case 27:
198 if (!signed) {
199 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
200 return UINT_27B_DECL;
201 }
202 return UINT_27L_DECL;
203 }
204 break;
205 case 32:
206 if (signed) {
207 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
208 return INT_32B_DECL;
209 }
210 return INT_32L_DECL;
211 }
212 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
213 return UINT_32B_DECL;
214 }
215 return UINT_32L_DECL;
216 case 64:
217 if (signed) {
218 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
219 return INT_64B_DECL;
220 }
221 return INT_64L_DECL;
222 }
223 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
224 return UINT_64B_DECL;
225 }
226 return UINT_64L_DECL;
227 default:
228 }
229 }
230 return new IntegerDeclaration(len, signed, base, byteOrder, encoding, clock, alignment);
231 }
232
233 /**
234 * Constructor
235 *
236 * @param len
237 * The length in bits
238 * @param signed
239 * Is the integer signed? false == unsigned
240 * @param base
241 * The base (10-16 are most common)
242 * @param byteOrder
243 * Big-endian little-endian or other
244 * @param encoding
245 * ascii, utf8 or none.
246 * @param clock
247 * The clock path, can be null
248 * @param alignment
249 * The minimum alignment. Should be ≥ 1
250 */
251 private IntegerDeclaration(int len, boolean signed, int base,
252 @Nullable ByteOrder byteOrder, Encoding encoding, String clock, long alignment) {
253 if (len <= 0 || len == 1 && signed) {
254 throw new IllegalArgumentException();
255 }
256
257 fLength = len;
258 fSigned = signed;
259 fBase = base;
260
261 @SuppressWarnings("null")
262 @NonNull
263 ByteOrder actualByteOrder = (byteOrder == null ? ByteOrder.nativeOrder() : byteOrder);
264 fByteOrder = actualByteOrder;
265
266 fEncoding = encoding;
267 fClock = clock;
268 fAlignment = Math.max(alignment, 1);
269 }
270
271 private IntegerDeclaration(int len, boolean signed, @Nullable ByteOrder byteOrder) {
272 this(len, signed, 10, byteOrder, Encoding.NONE, "", 8); //$NON-NLS-1$
273 }
274
275 // ------------------------------------------------------------------------
276 // Getters/Setters/Predicates
277 // ------------------------------------------------------------------------
278
279 /**
280 * Is the integer signed?
281 *
282 * @return the is the integer signed
283 */
284 public boolean isSigned() {
285 return fSigned;
286 }
287
288 /**
289 * Get the integer base commonly decimal or hex
290 *
291 * @return the integer base
292 */
293 public int getBase() {
294 return fBase;
295 }
296
297 /**
298 * Get the byte order
299 *
300 * @return the byte order
301 */
302 public ByteOrder getByteOrder() {
303 return fByteOrder;
304 }
305
306 /**
307 * Get encoding, chars are 8 bit ints
308 *
309 * @return the encoding
310 */
311 public Encoding getEncoding() {
312 return fEncoding;
313 }
314
315 /**
316 * Is the integer a character (8 bits and encoded?)
317 *
318 * @return is the integer a char
319 */
320 public boolean isCharacter() {
321 return (fLength == 8) && (fEncoding != Encoding.NONE);
322 }
323
324 /**
325 * Is the integer an unsigned byte (8 bits and no sign)?
326 *
327 * @return is the integer an unsigned byte
328 * @since 3.1
329 */
330 public boolean isUnsignedByte() {
331 return (fLength == 8) && (!fSigned);
332 }
333
334 /**
335 * Get the length in bits for this integer
336 *
337 * @return the length of the integer
338 */
339 public int getLength() {
340 return fLength;
341 }
342
343 @Override
344 public long getAlignment() {
345 return fAlignment;
346 }
347
348 /**
349 * The integer's clock, since timestamps are stored in ints
350 *
351 * @return the integer's clock, can be null. (most often it is)
352 */
353 public String getClock() {
354 return fClock;
355 }
356
357 /**
358 * @since 3.0
359 */
360 @Override
361 public int getMaximumSize() {
362 return fLength;
363 }
364
365 // ------------------------------------------------------------------------
366 // Operations
367 // ------------------------------------------------------------------------
368
369 /**
370 * @since 3.0
371 */
372 @Override
373 public IntegerDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
374 String fieldName, BitBuffer input) throws CTFReaderException {
375 ByteOrder byteOrder = input.getByteOrder();
376 input.setByteOrder(fByteOrder);
377 long value = read(input);
378 input.setByteOrder(byteOrder);
379 return new IntegerDefinition(this, definitionScope, fieldName, value);
380 }
381
382 @Override
383 public String toString() {
384 /* Only used for debugging */
385 return "[declaration] integer[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
386 }
387
388 /**
389 * Get the maximum value for this integer declaration.
390 *
391 * @return The maximum value for this integer declaration
392 * @since 2.0
393 */
394 public BigInteger getMaxValue() {
395 /*
396 * Compute the number of bits able to represent an unsigned number,
397 * ignoring sign bit.
398 */
399 int significantBits = fLength - (fSigned ? 1 : 0);
400 /*
401 * For a given N significant bits, compute the maximal value which is (1
402 * << N) - 1.
403 */
404
405 @SuppressWarnings("null")
406 @NonNull
407 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).subtract(BigInteger.ONE);
408 return ret;
409 }
410
411 /**
412 * Get the minimum value for this integer declaration.
413 *
414 * @return The minimum value for this integer declaration
415 * @since 2.0
416 */
417 public BigInteger getMinValue() {
418 if (!fSigned) {
419 @SuppressWarnings("null")
420 @NonNull
421 BigInteger ret = BigInteger.ZERO;
422 return ret;
423 }
424
425 /*
426 * Compute the number of bits able to represent an unsigned number,
427 * without the sign bit.
428 */
429 int significantBits = fLength - 1;
430 /*
431 * For a given N significant bits, compute the minimal value which is -
432 * (1 << N).
433 */
434 @SuppressWarnings("null")
435 @NonNull
436 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).negate();
437 return ret;
438 }
439
440 private long read(BitBuffer input) throws CTFReaderException {
441 /* Offset the buffer position wrt the current alignment */
442 alignRead(input);
443
444 boolean signed = isSigned();
445 int length = getLength();
446 long bits = 0;
447
448 /*
449 * Is the endianness of this field the same as the endianness of the
450 * input buffer? If not, then temporarily set the buffer's endianness to
451 * this field's just to read the data
452 */
453 ByteOrder previousByteOrder = input.getByteOrder();
454 if ((getByteOrder() != input.getByteOrder())) {
455 input.setByteOrder(getByteOrder());
456 }
457
458 if (length > 64) {
459 throw new CTFReaderException("Cannot read an integer with over 64 bits. Length given: " + length); //$NON-NLS-1$
460 }
461
462 bits = input.get(length, signed);
463
464 /*
465 * Put the input buffer's endianness back to original if it was changed
466 */
467 if (previousByteOrder != input.getByteOrder()) {
468 input.setByteOrder(previousByteOrder);
469 }
470
471 return bits;
472 }
473
474 }
This page took 0.043562 seconds and 5 git commands to generate.