Commit | Line | Data |
---|---|---|
866e5b51 | 1 | /******************************************************************************* |
ed902a2b | 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 | * | |
9 | * Contributors: Matthew Khouzam - Initial API and implementation | |
10 | * Contributors: Simon Marchi - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
f357bcd4 | 13 | package org.eclipse.tracecompass.ctf.core.trace; |
866e5b51 FC |
14 | |
15 | import java.util.UUID; | |
16 | ||
680f9173 | 17 | import org.eclipse.tracecompass.ctf.core.CTFException; |
f357bcd4 AM |
18 | import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition; |
19 | import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration; | |
20 | import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration; | |
21 | import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration; | |
22 | import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition; | |
a4fa4e36 | 23 | |
866e5b51 | 24 | /** |
866e5b51 | 25 | * Various utilities. |
0594c61c | 26 | * |
d37aaa7f FC |
27 | * @version 1.0 |
28 | * @author Matthew Khouzam | |
29 | * @author Simon Marchi | |
866e5b51 | 30 | */ |
a4fa4e36 | 31 | public final class Utils { |
866e5b51 | 32 | |
a4fa4e36 MK |
33 | private Utils() { |
34 | } | |
0594c61c | 35 | |
866e5b51 FC |
36 | // ------------------------------------------------------------------------ |
37 | // Constants | |
38 | // ------------------------------------------------------------------------ | |
39 | ||
40 | /** | |
9ac2eb62 | 41 | * CTF magic number. (sort of looks like CTF CTF CT) |
866e5b51 | 42 | */ |
0594c61c | 43 | public static final int CTF_MAGIC = 0xC1FC1FC1; |
866e5b51 FC |
44 | |
45 | /** | |
9ac2eb62 | 46 | * TSDL magic number. (sort of looks like TSDL LSDT) |
866e5b51 | 47 | */ |
0594c61c | 48 | public static final int TSDL_MAGIC = 0x75D11D57; |
866e5b51 FC |
49 | |
50 | /** | |
51 | * TSDL magic number length in bytes. | |
52 | */ | |
0594c61c | 53 | public static final int TSDL_MAGIC_LEN = 4; |
866e5b51 FC |
54 | |
55 | /** | |
56 | * Directory separator on the current platform. | |
57 | */ | |
0594c61c | 58 | public static final String SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$ |
866e5b51 FC |
59 | |
60 | /** | |
61 | * Length in bytes of a UUID value. | |
62 | */ | |
0594c61c | 63 | public static final int UUID_LEN = 16; |
866e5b51 FC |
64 | |
65 | // ------------------------------------------------------------------------ | |
66 | // Operations | |
67 | // ------------------------------------------------------------------------ | |
68 | ||
69 | /** | |
1c8799d5 | 70 | * Performs an unsigned long comparison on two unsigned long numbers. |
866e5b51 | 71 | * |
7b4f13e6 MK |
72 | * <strong> As Java does not support unsigned types and arithmetic, |
73 | * parameters are received encoded as a signed long (two-complement) but the | |
74 | * operation is an unsigned comparator.</strong> | |
1c8799d5 EB |
75 | * |
76 | * @param left | |
77 | * Left operand of the comparator. | |
78 | * @param right | |
79 | * Right operand of the comparator. | |
ab04fc6b | 80 | * @return -1 if left < right, 1 if left > right, 0 if left == right. |
866e5b51 | 81 | */ |
1c8799d5 EB |
82 | public static int unsignedCompare(long left, long right) { |
83 | /* | |
a4fa4e36 MK |
84 | * This method assumes that the arithmetic overflow on signed integer |
85 | * wrap on a circular domain (modulo arithmetic in two-complement), | |
86 | * which is the defined behavior in Java. | |
1c8799d5 EB |
87 | * |
88 | * This idea is to rotate the domain by the length of the negative | |
89 | * space, and then use the signed operator. | |
90 | */ | |
f5166b60 AM |
91 | final long a = left + Long.MIN_VALUE; |
92 | final long b = right + Long.MIN_VALUE; | |
93 | if (a < b) { | |
94 | return -1; | |
95 | } else if (a > b) { | |
96 | return 1; | |
97 | } | |
98 | return 0; | |
866e5b51 FC |
99 | } |
100 | ||
a4fa4e36 MK |
101 | /** |
102 | * Gets a UUID from an array defintion | |
103 | * | |
104 | * @param uuidDef | |
105 | * the array defintions, must contain integer bytes | |
106 | * @return the UUID | |
680f9173 | 107 | * @throws CTFException |
a4fa4e36 | 108 | * if the definition contains less than 16 elements |
a4fa4e36 | 109 | */ |
680f9173 | 110 | public static UUID getUUIDfromDefinition(AbstractArrayDefinition uuidDef) throws CTFException { |
f068c622 | 111 | byte[] uuidArray = new byte[UUID_LEN]; |
7b4f13e6 MK |
112 | IDeclaration declaration = uuidDef.getDeclaration(); |
113 | if (!(declaration instanceof CompoundDeclaration)) { | |
680f9173 | 114 | throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
7b4f13e6 MK |
115 | } |
116 | CompoundDeclaration uuidDec = (CompoundDeclaration) declaration; | |
117 | ||
118 | IDeclaration uuidElem = uuidDec.getElementType(); | |
119 | if (!(uuidElem instanceof IntegerDeclaration)) { | |
680f9173 | 120 | throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
7b4f13e6 MK |
121 | } |
122 | IntegerDeclaration intUuidElem = (IntegerDeclaration) uuidElem; | |
123 | if (!intUuidElem.isUnsignedByte()) { | |
680f9173 | 124 | throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
7b4f13e6 | 125 | } |
363edfc2 MK |
126 | return getUUID(uuidDef, uuidArray); |
127 | } | |
128 | ||
680f9173 | 129 | private static UUID getUUID(AbstractArrayDefinition uuidDef, byte[] uuidArray) throws CTFException { |
7b4f13e6 MK |
130 | for (int i = 0; i < uuidArray.length; i++) { |
131 | IntegerDefinition uuidByteDef = (IntegerDefinition) uuidDef.getDefinitions().get(i); | |
132 | if (uuidByteDef == null) { | |
680f9173 | 133 | throw new CTFException("UUID incomplete, only " + i + " bytes available"); //$NON-NLS-1$ //$NON-NLS-2$ |
7b4f13e6 MK |
134 | } |
135 | uuidArray[i] = (byte) uuidByteDef.getValue(); | |
136 | } | |
137 | ||
138 | UUID uuid = Utils.makeUUID(uuidArray); | |
139 | return uuid; | |
140 | } | |
141 | ||
866e5b51 FC |
142 | /** |
143 | * Creates a UUID object from an array of 16 bytes. | |
144 | * | |
145 | * @param bytes | |
146 | * Array of 16 bytes. | |
147 | * @return A UUID object. | |
148 | */ | |
149 | public static UUID makeUUID(byte bytes[]) { | |
150 | long high = 0; | |
151 | long low = 0; | |
152 | ||
153 | assert (bytes.length == Utils.UUID_LEN); | |
154 | ||
f068c622 MK |
155 | final int bitsPerByte = Byte.SIZE; |
156 | int bitMask = (1 << bitsPerByte) - 1; | |
157 | for (int i = 0; i < bitsPerByte; i++) { | |
158 | low = (low << bitsPerByte) | (bytes[i + bitsPerByte] & bitMask); | |
159 | high = (high << bitsPerByte) | (bytes[i] & bitMask); | |
866e5b51 FC |
160 | } |
161 | ||
162 | UUID uuid = new UUID(high, low); | |
163 | ||
164 | return uuid; | |
165 | } | |
166 | ||
167 | } |