1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
10 * Matthew Khouzam - Initial API and implementation
11 * Simon Marchi - Initial API and implementation
12 * Marc-Andre Laperle - Add min/maximum for validation
13 *******************************************************************************/
15 package org
.eclipse
.linuxtools
.ctf
.core
.event
.types
;
17 import java
.math
.BigInteger
;
18 import java
.nio
.ByteOrder
;
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
;
28 * A CTF integer declaration.
30 * The declaration of a integer basic data type.
33 * @author Matthew Khouzam
34 * @author Simon Marchi
37 public class IntegerDeclaration
extends Declaration
implements ISimpleDatatypeDeclaration
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
44 * unsigned int 32 bits big endian
48 public static final IntegerDeclaration UINT_32B_DECL
= new IntegerDeclaration(32, false, ByteOrder
.BIG_ENDIAN
);
50 * unsigned int 32 bits little endian
54 public static final IntegerDeclaration UINT_32L_DECL
= new IntegerDeclaration(32, false, ByteOrder
.LITTLE_ENDIAN
);
56 * signed int 32 bits big endian
60 public static final IntegerDeclaration INT_32B_DECL
= new IntegerDeclaration(32, true, ByteOrder
.BIG_ENDIAN
);
62 * signed int 32 bits little endian
66 public static final IntegerDeclaration INT_32L_DECL
= new IntegerDeclaration(32, true, ByteOrder
.LITTLE_ENDIAN
);
68 * unsigned int 32 bits big endian
72 public static final IntegerDeclaration UINT_64B_DECL
= new IntegerDeclaration(64, false, ByteOrder
.BIG_ENDIAN
);
74 * unsigned int 64 bits little endian
78 public static final IntegerDeclaration UINT_64L_DECL
= new IntegerDeclaration(64, false, ByteOrder
.LITTLE_ENDIAN
);
80 * signed int 64 bits big endian
84 public static final IntegerDeclaration INT_64B_DECL
= new IntegerDeclaration(64, true, ByteOrder
.BIG_ENDIAN
);
86 * signed int 64 bits little endian
90 public static final IntegerDeclaration INT_64L_DECL
= new IntegerDeclaration(64, true, ByteOrder
.LITTLE_ENDIAN
);
92 * unsigned 8 bit int endianness doesn't matter since it's 8 bits (byte)
96 public static final IntegerDeclaration UINT_8_DECL
= new IntegerDeclaration(8, false, ByteOrder
.BIG_ENDIAN
);
98 * signed 8 bit int endianness doesn't matter since it's 8 bits (char)
102 public static final IntegerDeclaration INT_8_DECL
= new IntegerDeclaration(8, true, ByteOrder
.BIG_ENDIAN
);
104 * Unsigned 5 bit int, used for event headers
108 public static final IntegerDeclaration UINT_5B_DECL
= new IntegerDeclaration(5, false, ByteOrder
.BIG_ENDIAN
);
110 * Unsigned 5 bit int, used for event headers
114 public static final IntegerDeclaration UINT_5L_DECL
= new IntegerDeclaration(5, false, ByteOrder
.LITTLE_ENDIAN
);
116 * Unsigned 5 bit int, used for event headers
120 public static final IntegerDeclaration UINT_27B_DECL
= new IntegerDeclaration(27, false, ByteOrder
.BIG_ENDIAN
);
122 * Unsigned 5 bit int, used for event headers
126 public static final IntegerDeclaration UINT_27L_DECL
= new IntegerDeclaration(27, false, ByteOrder
.LITTLE_ENDIAN
);
128 * Unsigned 16 bit int, used for event headers
132 public static final IntegerDeclaration UINT_16B_DECL
= new IntegerDeclaration(16, false, ByteOrder
.BIG_ENDIAN
);
134 * Unsigned 16 bit int, used for event headers
138 public static final IntegerDeclaration UINT_16L_DECL
= new IntegerDeclaration(16, false, ByteOrder
.LITTLE_ENDIAN
);
139 // ------------------------------------------------------------------------
141 // ------------------------------------------------------------------------
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
;
151 // ------------------------------------------------------------------------
153 // ------------------------------------------------------------------------
156 * Factory, some common types cached
161 * Is the integer signed? false == unsigned
163 * The base (10-16 are most common)
165 * Big-endian little-endian or other
167 * ascii, utf8 or none.
169 * The clock path, can be null
171 * The minimum alignment. Should be >= 1
172 * @return the integer declaration
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$
181 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
188 return signed ? INT_8_DECL
: UINT_8_DECL
;
191 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
192 return UINT_16B_DECL
;
194 return UINT_16L_DECL
;
199 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
200 return UINT_27B_DECL
;
202 return UINT_27L_DECL
;
207 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
212 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
213 return UINT_32B_DECL
;
215 return UINT_32L_DECL
;
218 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
223 if (byteOrder
!= null && byteOrder
.equals(ByteOrder
.BIG_ENDIAN
)) {
224 return UINT_64B_DECL
;
226 return UINT_64L_DECL
;
230 return new IntegerDeclaration(len
, signed
, base
, byteOrder
, encoding
, clock
, alignment
);
239 * Is the integer signed? false == unsigned
241 * The base (10-16 are most common)
243 * Big-endian little-endian or other
245 * ascii, utf8 or none.
247 * The clock path, can be null
249 * The minimum alignment. Should be ≥ 1
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();
261 @SuppressWarnings("null")
263 ByteOrder actualByteOrder
= (byteOrder
== null ? ByteOrder
.nativeOrder() : byteOrder
);
264 fByteOrder
= actualByteOrder
;
266 fEncoding
= encoding
;
268 fAlignment
= Math
.max(alignment
, 1);
271 private IntegerDeclaration(int len
, boolean signed
, @Nullable ByteOrder byteOrder
) {
272 this(len
, signed
, 10, byteOrder
, Encoding
.NONE
, "", 8); //$NON-NLS-1$
275 // ------------------------------------------------------------------------
276 // Getters/Setters/Predicates
277 // ------------------------------------------------------------------------
280 * Is the integer signed?
282 * @return the is the integer signed
284 public boolean isSigned() {
289 * Get the integer base commonly decimal or hex
291 * @return the integer base
293 public int getBase() {
300 * @return the byte order
302 public ByteOrder
getByteOrder() {
307 * Get encoding, chars are 8 bit ints
309 * @return the encoding
311 public Encoding
getEncoding() {
316 * Is the integer a character (8 bits and encoded?)
318 * @return is the integer a char
320 public boolean isCharacter() {
321 return (fLength
== 8) && (fEncoding
!= Encoding
.NONE
);
325 * Is the integer an unsigned byte (8 bits and no sign)?
327 * @return is the integer an unsigned byte
330 public boolean isUnsignedByte() {
331 return (fLength
== 8) && (!fSigned
);
335 * Get the length in bits for this integer
337 * @return the length of the integer
339 public int getLength() {
344 public long getAlignment() {
349 * The integer's clock, since timestamps are stored in ints
351 * @return the integer's clock, can be null. (most often it is)
353 public String
getClock() {
361 public int getMaximumSize() {
365 // ------------------------------------------------------------------------
367 // ------------------------------------------------------------------------
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
);
383 public String
toString() {
384 /* Only used for debugging */
385 return "[declaration] integer[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
389 * Get the maximum value for this integer declaration.
391 * @return The maximum value for this integer declaration
394 public BigInteger
getMaxValue() {
396 * Compute the number of bits able to represent an unsigned number,
399 int significantBits
= fLength
- (fSigned ?
1 : 0);
401 * For a given N significant bits, compute the maximal value which is (1
405 @SuppressWarnings("null")
407 BigInteger ret
= BigInteger
.ONE
.shiftLeft(significantBits
).subtract(BigInteger
.ONE
);
412 * Get the minimum value for this integer declaration.
414 * @return The minimum value for this integer declaration
417 public BigInteger
getMinValue() {
419 @SuppressWarnings("null")
421 BigInteger ret
= BigInteger
.ZERO
;
426 * Compute the number of bits able to represent an unsigned number,
427 * without the sign bit.
429 int significantBits
= fLength
- 1;
431 * For a given N significant bits, compute the minimal value which is -
434 @SuppressWarnings("null")
436 BigInteger ret
= BigInteger
.ONE
.shiftLeft(significantBits
).negate();
440 private long read(BitBuffer input
) throws CTFReaderException
{
441 /* Offset the buffer position wrt the current alignment */
444 boolean signed
= isSigned();
445 int length
= getLength();
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
453 ByteOrder previousByteOrder
= input
.getByteOrder();
454 if ((getByteOrder() != input
.getByteOrder())) {
455 input
.setByteOrder(getByteOrder());
459 throw new CTFReaderException("Cannot read an integer with over 64 bits. Length given: " + length
); //$NON-NLS-1$
462 bits
= input
.get(length
, signed
);
465 * Put the input buffer's endianness back to original if it was changed
467 if (previousByteOrder
!= input
.getByteOrder()) {
468 input
.setByteOrder(previousByteOrder
);