tmf: Add a TmfTraceUtils class for advanced getter methods
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / IntegerDeclaration.java
CommitLineData
866e5b51 1/*******************************************************************************
0f231de2 2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
866e5b51
FC
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 *
4311ac8b
MAL
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
866e5b51
FC
13 *******************************************************************************/
14
f357bcd4 15package org.eclipse.tracecompass.ctf.core.event.types;
866e5b51 16
4311ac8b 17import java.math.BigInteger;
866e5b51
FC
18import java.nio.ByteOrder;
19
a4fa4e36
MK
20import org.eclipse.jdt.annotation.NonNull;
21import org.eclipse.jdt.annotation.NonNullByDefault;
22import org.eclipse.jdt.annotation.Nullable;
f357bcd4
AM
23import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
24import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
25import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
a4fa4e36 26
866e5b51 27/**
d37aaa7f 28 * A CTF integer declaration.
4311ac8b 29 *
d37aaa7f
FC
30 * The declaration of a integer basic data type.
31 *
32 * @version 1.0
33 * @author Matthew Khouzam
34 * @author Simon Marchi
866e5b51 35 */
a4fa4e36 36@NonNullByDefault
8fa270f6 37public class IntegerDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
a4fa4e36
MK
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);
6c7592e1
MK
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 */
0f231de2 114 public static final IntegerDeclaration UINT_5L_DECL = new IntegerDeclaration(5, false, ByteOrder.LITTLE_ENDIAN);
6c7592e1
MK
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 */
0f231de2 126 public static final IntegerDeclaration UINT_27L_DECL = new IntegerDeclaration(27, false, ByteOrder.LITTLE_ENDIAN);
6c7592e1
MK
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);
866e5b51
FC
139 // ------------------------------------------------------------------------
140 // Attributes
141 // ------------------------------------------------------------------------
142
a4fa4e36
MK
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;
866e5b51
FC
150
151 // ------------------------------------------------------------------------
152 // Constructors
153 // ------------------------------------------------------------------------
154
a4fa4e36
MK
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$
6c7592e1
MK
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:
a4fa4e36 188 return signed ? INT_8_DECL : UINT_8_DECL;
6c7592e1
MK
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:
a4fa4e36
MK
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;
6c7592e1 216 case 64:
a4fa4e36
MK
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;
6c7592e1 227 default:
a4fa4e36
MK
228 }
229 }
230 return new IntegerDeclaration(len, signed, base, byteOrder, encoding, clock, alignment);
231 }
232
9ac2eb62 233 /**
a511da0d 234 * Constructor
056ebaf1
AM
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
a511da0d 243 * Big-endian little-endian or other
056ebaf1
AM
244 * @param encoding
245 * ascii, utf8 or none.
246 * @param clock
247 * The clock path, can be null
248 * @param alignment
ab04fc6b 249 * The minimum alignment. Should be ≥ 1
9ac2eb62 250 */
a4fa4e36
MK
251 private IntegerDeclaration(int len, boolean signed, int base,
252 @Nullable ByteOrder byteOrder, Encoding encoding, String clock, long alignment) {
4311ac8b
MAL
253 if (len <= 0 || len == 1 && signed) {
254 throw new IllegalArgumentException();
255 }
a4fa4e36
MK
256
257 fLength = len;
258 fSigned = signed;
259 fBase = base;
260
261 @SuppressWarnings("null")
7b4f13e6
MK
262 @NonNull
263 ByteOrder actualByteOrder = (byteOrder == null ? ByteOrder.nativeOrder() : byteOrder);
a4fa4e36
MK
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$
866e5b51
FC
273 }
274
275 // ------------------------------------------------------------------------
a511da0d 276 // Getters/Setters/Predicates
866e5b51
FC
277 // ------------------------------------------------------------------------
278
9ac2eb62
MK
279 /**
280 * Is the integer signed?
bdc1590e 281 *
9ac2eb62
MK
282 * @return the is the integer signed
283 */
866e5b51 284 public boolean isSigned() {
a4fa4e36 285 return fSigned;
866e5b51
FC
286 }
287
9ac2eb62 288 /**
a511da0d 289 * Get the integer base commonly decimal or hex
bdc1590e 290 *
9ac2eb62
MK
291 * @return the integer base
292 */
866e5b51 293 public int getBase() {
a4fa4e36 294 return fBase;
866e5b51
FC
295 }
296
9ac2eb62 297 /**
bdc1590e
EB
298 * Get the byte order
299 *
9ac2eb62
MK
300 * @return the byte order
301 */
866e5b51 302 public ByteOrder getByteOrder() {
a4fa4e36 303 return fByteOrder;
866e5b51
FC
304 }
305
9ac2eb62 306 /**
a511da0d 307 * Get encoding, chars are 8 bit ints
bdc1590e 308 *
9ac2eb62
MK
309 * @return the encoding
310 */
866e5b51 311 public Encoding getEncoding() {
a4fa4e36 312 return fEncoding;
866e5b51
FC
313 }
314
9ac2eb62 315 /**
a511da0d 316 * Is the integer a character (8 bits and encoded?)
bdc1590e 317 *
9ac2eb62
MK
318 * @return is the integer a char
319 */
bdc1590e 320 public boolean isCharacter() {
a4fa4e36 321 return (fLength == 8) && (fEncoding != Encoding.NONE);
866e5b51
FC
322 }
323
7b4f13e6
MK
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
bdc1590e
EB
334 /**
335 * Get the length in bits for this integer
336 *
337 * @return the length of the integer
338 */
866e5b51 339 public int getLength() {
a4fa4e36 340 return fLength;
866e5b51
FC
341 }
342
07002e0a 343 @Override
6f04e06c 344 public long getAlignment() {
a4fa4e36 345 return fAlignment;
fd74e6c1
MK
346 }
347
9ac2eb62
MK
348 /**
349 * The integer's clock, since timestamps are stored in ints
bdc1590e 350 *
9ac2eb62
MK
351 * @return the integer's clock, can be null. (most often it is)
352 */
6f04e06c 353 public String getClock() {
a4fa4e36
MK
354 return fClock;
355 }
356
357 /**
358 * @since 3.0
359 */
360 @Override
361 public int getMaximumSize() {
362 return fLength;
fd74e6c1 363 }
bdc1590e 364
866e5b51
FC
365 // ------------------------------------------------------------------------
366 // Operations
367 // ------------------------------------------------------------------------
368
a4fa4e36
MK
369 /**
370 * @since 3.0
371 */
866e5b51 372 @Override
a4fa4e36
MK
373 public IntegerDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
374 String fieldName, BitBuffer input) throws CTFReaderException {
733c614c
MK
375 ByteOrder byteOrder = input.getByteOrder();
376 input.setByteOrder(fByteOrder);
a4fa4e36 377 long value = read(input);
733c614c 378 input.setByteOrder(byteOrder);
a4fa4e36 379 return new IntegerDefinition(this, definitionScope, fieldName, value);
866e5b51
FC
380 }
381
382 @Override
383 public String toString() {
66aa25f0 384 return "[declaration] integer[length:" + fLength + (fSigned?" ":" un")+"signed" + " base:" + fBase + " byteOrder:" + fByteOrder + " encoding:" + fEncoding + " alignment:" + fAlignment + " clock:" + fClock + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
866e5b51
FC
385 }
386
4311ac8b 387 /**
a4fa4e36 388 * Get the maximum value for this integer declaration.
4311ac8b
MAL
389 *
390 * @return The maximum value for this integer declaration
391 * @since 2.0
392 */
393 public BigInteger getMaxValue() {
bdc1590e
EB
394 /*
395 * Compute the number of bits able to represent an unsigned number,
396 * ignoring sign bit.
397 */
a4fa4e36 398 int significantBits = fLength - (fSigned ? 1 : 0);
bdc1590e 399 /*
a4fa4e36
MK
400 * For a given N significant bits, compute the maximal value which is (1
401 * << N) - 1.
bdc1590e 402 */
a4fa4e36
MK
403
404 @SuppressWarnings("null")
7b4f13e6
MK
405 @NonNull
406 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).subtract(BigInteger.ONE);
a4fa4e36 407 return ret;
4311ac8b
MAL
408 }
409
410 /**
a4fa4e36 411 * Get the minimum value for this integer declaration.
4311ac8b
MAL
412 *
413 * @return The minimum value for this integer declaration
414 * @since 2.0
415 */
416 public BigInteger getMinValue() {
a4fa4e36
MK
417 if (!fSigned) {
418 @SuppressWarnings("null")
7b4f13e6
MK
419 @NonNull
420 BigInteger ret = BigInteger.ZERO;
a4fa4e36 421 return ret;
4311ac8b
MAL
422 }
423
bdc1590e
EB
424 /*
425 * Compute the number of bits able to represent an unsigned number,
426 * without the sign bit.
427 */
a4fa4e36
MK
428 int significantBits = fLength - 1;
429 /*
430 * For a given N significant bits, compute the minimal value which is -
431 * (1 << N).
432 */
433 @SuppressWarnings("null")
7b4f13e6
MK
434 @NonNull
435 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).negate();
a4fa4e36
MK
436 return ret;
437 }
438
439 private long read(BitBuffer input) throws CTFReaderException {
440 /* Offset the buffer position wrt the current alignment */
441 alignRead(input);
442
443 boolean signed = isSigned();
444 int length = getLength();
445 long bits = 0;
446
447 /*
448 * Is the endianness of this field the same as the endianness of the
449 * input buffer? If not, then temporarily set the buffer's endianness to
450 * this field's just to read the data
451 */
452 ByteOrder previousByteOrder = input.getByteOrder();
453 if ((getByteOrder() != input.getByteOrder())) {
454 input.setByteOrder(getByteOrder());
455 }
456
457 if (length > 64) {
458 throw new CTFReaderException("Cannot read an integer with over 64 bits. Length given: " + length); //$NON-NLS-1$
459 }
460
461 bits = input.get(length, signed);
462
bdc1590e 463 /*
a4fa4e36 464 * Put the input buffer's endianness back to original if it was changed
bdc1590e 465 */
a4fa4e36
MK
466 if (previousByteOrder != input.getByteOrder()) {
467 input.setByteOrder(previousByteOrder);
468 }
469
470 return bits;
4311ac8b
MAL
471 }
472
e00e6663
MK
473 @Override
474 public int hashCode() {
475 final int prime = 31;
476 int result = 1;
477 result = prime * result + (int) (fAlignment ^ (fAlignment >>> 32));
478 result = prime * result + fBase;
479 result = prime * result + (fByteOrder.equals(ByteOrder.BIG_ENDIAN) ? 4321 : 1234);
480 result = prime * result + (fClock.hashCode());
481 switch (fEncoding) {
482 case ASCII:
483 result = prime * result + 1;
484 break;
485 case NONE:
486 result = prime * result + 2;
487 break;
488 case UTF8:
489 result = prime * result + 3;
490 break;
491 default:
492 result = prime * result + 4;
493 break;
494 }
495 result = prime * result + fLength;
496 result = prime * result + (fSigned ? 1231 : 1237);
497 return result;
498 }
499
500 @Override
501 public boolean equals(@Nullable Object obj) {
502 if (this == obj) {
503 return true;
504 }
505 if (obj == null) {
506 return false;
507 }
508 if (getClass() != obj.getClass()) {
509 return false;
510 }
511 IntegerDeclaration other = (IntegerDeclaration) obj;
512 if (fAlignment != other.fAlignment) {
513 return false;
514 }
515 if (fBase != other.fBase) {
516 return false;
517 }
518 if (!fByteOrder.equals(other.fByteOrder)) {
519 return false;
520 }
521 if (!fClock.equals(other.fClock)) {
522 return false;
523 }
524 if (fEncoding != other.fEncoding) {
525 return false;
526 }
527 if (fLength != other.fLength) {
528 return false;
529 }
530 if (fSigned != other.fSigned) {
531 return false;
532 }
533 return true;
534 }
535
66aa25f0
MK
536 @Override
537 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
538 if (this == obj) {
539 return true;
540 }
541 if (obj == null) {
542 return false;
543 }
544 if (getClass() != obj.getClass()) {
545 return false;
546 }
547 IntegerDeclaration other = (IntegerDeclaration) obj;
548 if (fAlignment != other.fAlignment) {
549 return false;
550 }
551 if (fLength != other.fLength) {
552 return false;
553 }
554 if (fSigned != other.fSigned) {
555 return false;
556 }
557 // no need for base
558 // no need for encoding
559 // no need for clock
560 // byte inversion is ok on byte order if the element is one byte long
561 if ((fLength != 8) && !fByteOrder.equals(other.fByteOrder)) {
562 return false;
563 }
564 return true;
565 }
566
866e5b51 567}
This page took 0.074722 seconds and 5 git commands to generate.