Bug 453706 - Uncategorize RCP and Testing features
[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 */
2dd7bd51 108 public static final IntegerDeclaration UINT_5B_DECL = new IntegerDeclaration(5, false, 10, ByteOrder.BIG_ENDIAN, Encoding.NONE, "", 1); //$NON-NLS-1$
6c7592e1
MK
109 /**
110 * Unsigned 5 bit int, used for event headers
111 *
112 * @since 3.1
113 */
2dd7bd51 114 public static final IntegerDeclaration UINT_5L_DECL = new IntegerDeclaration(5, false, 10, ByteOrder.LITTLE_ENDIAN, Encoding.NONE, "", 1); //$NON-NLS-1$
6c7592e1
MK
115 /**
116 * Unsigned 5 bit int, used for event headers
117 *
118 * @since 3.1
119 */
2dd7bd51 120 public static final IntegerDeclaration UINT_27B_DECL = new IntegerDeclaration(27, false, 10, ByteOrder.BIG_ENDIAN, Encoding.NONE, "", 1); //$NON-NLS-1$
6c7592e1
MK
121 /**
122 * Unsigned 5 bit int, used for event headers
123 *
124 * @since 3.1
125 */
2dd7bd51 126 public static final IntegerDeclaration UINT_27L_DECL = new IntegerDeclaration(27, false, 10, ByteOrder.LITTLE_ENDIAN, Encoding.NONE, "", 1); //$NON-NLS-1$
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) {
2dd7bd51
MK
177 if (encoding.equals(Encoding.NONE) && (clock.equals("")) && base == 10) { //$NON-NLS-1$
178 if (alignment == 8) {
179 switch (len) {
180 case 8:
181 return signed ? INT_8_DECL : UINT_8_DECL;
182 case 16:
183 if (!signed) {
184 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
185 return UINT_16B_DECL;
186 }
187 return UINT_16L_DECL;
6c7592e1 188 }
2dd7bd51
MK
189 break;
190 case 32:
191 if (signed) {
192 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
193 return INT_32B_DECL;
194 }
195 return INT_32L_DECL;
6c7592e1 196 }
6c7592e1 197 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
2dd7bd51 198 return UINT_32B_DECL;
6c7592e1 199 }
2dd7bd51
MK
200 return UINT_32L_DECL;
201 case 64:
202 if (signed) {
203 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
204 return INT_64B_DECL;
205 }
206 return INT_64L_DECL;
a4fa4e36 207 }
a4fa4e36 208 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
2dd7bd51 209 return UINT_64B_DECL;
a4fa4e36 210 }
2dd7bd51
MK
211 return UINT_64L_DECL;
212 default:
a4fa4e36 213 }
2dd7bd51
MK
214 } else if (alignment == 1) {
215 switch (len) {
216 case 5:
217 if (!signed) {
218 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
219 return UINT_5B_DECL;
220 }
221 return UINT_5L_DECL;
222 }
223 break;
224 case 27:
225 if (!signed) {
226 if (byteOrder != null && byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
227 return UINT_27B_DECL;
228 }
229 return UINT_27L_DECL;
230 }
231 break;
232 default:
233 break;
a4fa4e36 234 }
a4fa4e36
MK
235 }
236 }
237 return new IntegerDeclaration(len, signed, base, byteOrder, encoding, clock, alignment);
238 }
239
9ac2eb62 240 /**
a511da0d 241 * Constructor
056ebaf1
AM
242 *
243 * @param len
244 * The length in bits
245 * @param signed
246 * Is the integer signed? false == unsigned
247 * @param base
248 * The base (10-16 are most common)
249 * @param byteOrder
a511da0d 250 * Big-endian little-endian or other
056ebaf1
AM
251 * @param encoding
252 * ascii, utf8 or none.
253 * @param clock
254 * The clock path, can be null
255 * @param alignment
ab04fc6b 256 * The minimum alignment. Should be ≥ 1
9ac2eb62 257 */
a4fa4e36
MK
258 private IntegerDeclaration(int len, boolean signed, int base,
259 @Nullable ByteOrder byteOrder, Encoding encoding, String clock, long alignment) {
4311ac8b
MAL
260 if (len <= 0 || len == 1 && signed) {
261 throw new IllegalArgumentException();
262 }
a4fa4e36
MK
263
264 fLength = len;
265 fSigned = signed;
266 fBase = base;
267
268 @SuppressWarnings("null")
7b4f13e6
MK
269 @NonNull
270 ByteOrder actualByteOrder = (byteOrder == null ? ByteOrder.nativeOrder() : byteOrder);
a4fa4e36
MK
271 fByteOrder = actualByteOrder;
272
273 fEncoding = encoding;
274 fClock = clock;
275 fAlignment = Math.max(alignment, 1);
276 }
277
278 private IntegerDeclaration(int len, boolean signed, @Nullable ByteOrder byteOrder) {
279 this(len, signed, 10, byteOrder, Encoding.NONE, "", 8); //$NON-NLS-1$
866e5b51
FC
280 }
281
282 // ------------------------------------------------------------------------
a511da0d 283 // Getters/Setters/Predicates
866e5b51
FC
284 // ------------------------------------------------------------------------
285
9ac2eb62
MK
286 /**
287 * Is the integer signed?
bdc1590e 288 *
9ac2eb62
MK
289 * @return the is the integer signed
290 */
866e5b51 291 public boolean isSigned() {
a4fa4e36 292 return fSigned;
866e5b51
FC
293 }
294
9ac2eb62 295 /**
a511da0d 296 * Get the integer base commonly decimal or hex
bdc1590e 297 *
9ac2eb62
MK
298 * @return the integer base
299 */
866e5b51 300 public int getBase() {
a4fa4e36 301 return fBase;
866e5b51
FC
302 }
303
9ac2eb62 304 /**
bdc1590e
EB
305 * Get the byte order
306 *
9ac2eb62
MK
307 * @return the byte order
308 */
866e5b51 309 public ByteOrder getByteOrder() {
a4fa4e36 310 return fByteOrder;
866e5b51
FC
311 }
312
9ac2eb62 313 /**
a511da0d 314 * Get encoding, chars are 8 bit ints
bdc1590e 315 *
9ac2eb62
MK
316 * @return the encoding
317 */
866e5b51 318 public Encoding getEncoding() {
a4fa4e36 319 return fEncoding;
866e5b51
FC
320 }
321
9ac2eb62 322 /**
a511da0d 323 * Is the integer a character (8 bits and encoded?)
bdc1590e 324 *
9ac2eb62
MK
325 * @return is the integer a char
326 */
bdc1590e 327 public boolean isCharacter() {
a4fa4e36 328 return (fLength == 8) && (fEncoding != Encoding.NONE);
866e5b51
FC
329 }
330
7b4f13e6
MK
331 /**
332 * Is the integer an unsigned byte (8 bits and no sign)?
333 *
334 * @return is the integer an unsigned byte
335 * @since 3.1
336 */
337 public boolean isUnsignedByte() {
338 return (fLength == 8) && (!fSigned);
339 }
340
bdc1590e
EB
341 /**
342 * Get the length in bits for this integer
343 *
344 * @return the length of the integer
345 */
866e5b51 346 public int getLength() {
a4fa4e36 347 return fLength;
866e5b51
FC
348 }
349
07002e0a 350 @Override
6f04e06c 351 public long getAlignment() {
a4fa4e36 352 return fAlignment;
fd74e6c1
MK
353 }
354
9ac2eb62
MK
355 /**
356 * The integer's clock, since timestamps are stored in ints
bdc1590e 357 *
9ac2eb62
MK
358 * @return the integer's clock, can be null. (most often it is)
359 */
6f04e06c 360 public String getClock() {
a4fa4e36
MK
361 return fClock;
362 }
363
364 /**
365 * @since 3.0
366 */
367 @Override
368 public int getMaximumSize() {
369 return fLength;
fd74e6c1 370 }
bdc1590e 371
866e5b51
FC
372 // ------------------------------------------------------------------------
373 // Operations
374 // ------------------------------------------------------------------------
375
a4fa4e36
MK
376 /**
377 * @since 3.0
378 */
866e5b51 379 @Override
a4fa4e36
MK
380 public IntegerDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
381 String fieldName, BitBuffer input) throws CTFReaderException {
733c614c
MK
382 ByteOrder byteOrder = input.getByteOrder();
383 input.setByteOrder(fByteOrder);
a4fa4e36 384 long value = read(input);
733c614c 385 input.setByteOrder(byteOrder);
a4fa4e36 386 return new IntegerDefinition(this, definitionScope, fieldName, value);
866e5b51
FC
387 }
388
389 @Override
390 public String toString() {
2dd7bd51 391 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
392 }
393
4311ac8b 394 /**
a4fa4e36 395 * Get the maximum value for this integer declaration.
4311ac8b
MAL
396 *
397 * @return The maximum value for this integer declaration
398 * @since 2.0
399 */
400 public BigInteger getMaxValue() {
bdc1590e
EB
401 /*
402 * Compute the number of bits able to represent an unsigned number,
403 * ignoring sign bit.
404 */
a4fa4e36 405 int significantBits = fLength - (fSigned ? 1 : 0);
bdc1590e 406 /*
a4fa4e36
MK
407 * For a given N significant bits, compute the maximal value which is (1
408 * << N) - 1.
bdc1590e 409 */
a4fa4e36
MK
410
411 @SuppressWarnings("null")
7b4f13e6
MK
412 @NonNull
413 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).subtract(BigInteger.ONE);
a4fa4e36 414 return ret;
4311ac8b
MAL
415 }
416
417 /**
a4fa4e36 418 * Get the minimum value for this integer declaration.
4311ac8b
MAL
419 *
420 * @return The minimum value for this integer declaration
421 * @since 2.0
422 */
423 public BigInteger getMinValue() {
a4fa4e36
MK
424 if (!fSigned) {
425 @SuppressWarnings("null")
7b4f13e6
MK
426 @NonNull
427 BigInteger ret = BigInteger.ZERO;
a4fa4e36 428 return ret;
4311ac8b
MAL
429 }
430
bdc1590e
EB
431 /*
432 * Compute the number of bits able to represent an unsigned number,
433 * without the sign bit.
434 */
a4fa4e36
MK
435 int significantBits = fLength - 1;
436 /*
437 * For a given N significant bits, compute the minimal value which is -
438 * (1 << N).
439 */
440 @SuppressWarnings("null")
7b4f13e6
MK
441 @NonNull
442 BigInteger ret = BigInteger.ONE.shiftLeft(significantBits).negate();
a4fa4e36
MK
443 return ret;
444 }
445
446 private long read(BitBuffer input) throws CTFReaderException {
447 /* Offset the buffer position wrt the current alignment */
448 alignRead(input);
449
450 boolean signed = isSigned();
451 int length = getLength();
452 long bits = 0;
453
454 /*
455 * Is the endianness of this field the same as the endianness of the
456 * input buffer? If not, then temporarily set the buffer's endianness to
457 * this field's just to read the data
458 */
459 ByteOrder previousByteOrder = input.getByteOrder();
460 if ((getByteOrder() != input.getByteOrder())) {
461 input.setByteOrder(getByteOrder());
462 }
463
464 if (length > 64) {
465 throw new CTFReaderException("Cannot read an integer with over 64 bits. Length given: " + length); //$NON-NLS-1$
466 }
467
468 bits = input.get(length, signed);
469
bdc1590e 470 /*
a4fa4e36 471 * Put the input buffer's endianness back to original if it was changed
bdc1590e 472 */
a4fa4e36
MK
473 if (previousByteOrder != input.getByteOrder()) {
474 input.setByteOrder(previousByteOrder);
475 }
476
477 return bits;
4311ac8b
MAL
478 }
479
e00e6663
MK
480 @Override
481 public int hashCode() {
482 final int prime = 31;
483 int result = 1;
484 result = prime * result + (int) (fAlignment ^ (fAlignment >>> 32));
485 result = prime * result + fBase;
486 result = prime * result + (fByteOrder.equals(ByteOrder.BIG_ENDIAN) ? 4321 : 1234);
487 result = prime * result + (fClock.hashCode());
488 switch (fEncoding) {
489 case ASCII:
490 result = prime * result + 1;
491 break;
492 case NONE:
493 result = prime * result + 2;
494 break;
495 case UTF8:
496 result = prime * result + 3;
497 break;
498 default:
499 result = prime * result + 4;
500 break;
501 }
502 result = prime * result + fLength;
503 result = prime * result + (fSigned ? 1231 : 1237);
504 return result;
505 }
506
507 @Override
508 public boolean equals(@Nullable Object obj) {
509 if (this == obj) {
510 return true;
511 }
512 if (obj == null) {
513 return false;
514 }
515 if (getClass() != obj.getClass()) {
516 return false;
517 }
518 IntegerDeclaration other = (IntegerDeclaration) obj;
519 if (fAlignment != other.fAlignment) {
520 return false;
521 }
522 if (fBase != other.fBase) {
523 return false;
524 }
525 if (!fByteOrder.equals(other.fByteOrder)) {
526 return false;
527 }
528 if (!fClock.equals(other.fClock)) {
529 return false;
530 }
531 if (fEncoding != other.fEncoding) {
532 return false;
533 }
534 if (fLength != other.fLength) {
535 return false;
536 }
537 if (fSigned != other.fSigned) {
538 return false;
539 }
540 return true;
541 }
542
66aa25f0
MK
543 @Override
544 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
545 if (this == obj) {
546 return true;
547 }
548 if (obj == null) {
549 return false;
550 }
551 if (getClass() != obj.getClass()) {
552 return false;
553 }
554 IntegerDeclaration other = (IntegerDeclaration) obj;
555 if (fAlignment != other.fAlignment) {
556 return false;
557 }
558 if (fLength != other.fLength) {
559 return false;
560 }
561 if (fSigned != other.fSigned) {
562 return false;
563 }
564 // no need for base
565 // no need for encoding
566 // no need for clock
567 // byte inversion is ok on byte order if the element is one byte long
568 if ((fLength != 8) && !fByteOrder.equals(other.fByteOrder)) {
569 return false;
570 }
571 return true;
572 }
573
866e5b51 574}
This page took 0.074437 seconds and 5 git commands to generate.