| /******************************************************************************* |
| * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others |
| * |
| * All rights reserved. This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: Matthew Khouzam - Initial API and implementation |
| * Contributors: Simon Marchi - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.internal.ctf.core.utils; |
| |
| import java.util.UUID; |
| |
| import org.eclipse.tracecompass.ctf.core.CTFException; |
| import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition; |
| import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration; |
| import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration; |
| import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration; |
| import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition; |
| |
| /** |
| * Various utilities. |
| * |
| * @version 1.0 |
| * @author Matthew Khouzam |
| * @author Simon Marchi |
| */ |
| public final class Utils { |
| |
| private Utils() { |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Constants |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * CTF magic number. (sort of looks like CTF CTF CT) |
| */ |
| public static final int CTF_MAGIC = 0xC1FC1FC1; |
| |
| /** |
| * TSDL magic number. (sort of looks like TSDL LSDT) |
| */ |
| public static final int TSDL_MAGIC = 0x75D11D57; |
| |
| /** |
| * TSDL magic number length in bytes. |
| */ |
| public static final int TSDL_MAGIC_LEN = 4; |
| |
| /** |
| * Directory separator on the current platform. |
| */ |
| public static final String SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$ |
| |
| /** |
| * Length in bytes of a UUID value. |
| */ |
| public static final int UUID_LEN = 16; |
| |
| // ------------------------------------------------------------------------ |
| // Operations |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Performs an unsigned long comparison on two unsigned long numbers. |
| * |
| * <strong> As Java does not support unsigned types and arithmetic, |
| * parameters are received encoded as a signed long (two-complement) but the |
| * operation is an unsigned comparator.</strong> |
| * |
| * @param left |
| * Left operand of the comparator. |
| * @param right |
| * Right operand of the comparator. |
| * @return -1 if left < right, 1 if left > right, 0 if left == right. |
| */ |
| public static int unsignedCompare(long left, long right) { |
| /* |
| * This method assumes that the arithmetic overflow on signed integer |
| * wrap on a circular domain (modulo arithmetic in two-complement), |
| * which is the defined behavior in Java. |
| * |
| * This idea is to rotate the domain by the length of the negative |
| * space, and then use the signed operator. |
| */ |
| final long a = left + Long.MIN_VALUE; |
| final long b = right + Long.MIN_VALUE; |
| if (a < b) { |
| return -1; |
| } else if (a > b) { |
| return 1; |
| } |
| return 0; |
| } |
| |
| /** |
| * Gets a UUID from an array defintion |
| * |
| * @param uuidDef |
| * the array defintions, must contain integer bytes |
| * @return the UUID |
| * @throws CTFException |
| * if the definition contains less than 16 elements |
| */ |
| public static UUID getUUIDfromDefinition(AbstractArrayDefinition uuidDef) throws CTFException { |
| byte[] uuidArray = new byte[UUID_LEN]; |
| IDeclaration declaration = uuidDef.getDeclaration(); |
| if (!(declaration instanceof CompoundDeclaration)) { |
| throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
| } |
| CompoundDeclaration uuidDec = (CompoundDeclaration) declaration; |
| |
| IDeclaration uuidElem = uuidDec.getElementType(); |
| if (!(uuidElem instanceof IntegerDeclaration)) { |
| throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
| } |
| IntegerDeclaration intUuidElem = (IntegerDeclaration) uuidElem; |
| if (!intUuidElem.isUnsignedByte()) { |
| throw new CTFException("UUID must be a sequence of unsigned bytes"); //$NON-NLS-1$ |
| } |
| return getUUID(uuidDef, uuidArray); |
| } |
| |
| private static UUID getUUID(AbstractArrayDefinition uuidDef, byte[] uuidArray) throws CTFException { |
| for (int i = 0; i < uuidArray.length; i++) { |
| IntegerDefinition uuidByteDef = (IntegerDefinition) uuidDef.getDefinitions().get(i); |
| if (uuidByteDef == null) { |
| throw new CTFException("UUID incomplete, only " + i + " bytes available"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| uuidArray[i] = (byte) uuidByteDef.getValue(); |
| } |
| |
| UUID uuid = Utils.makeUUID(uuidArray); |
| return uuid; |
| } |
| |
| /** |
| * Creates a UUID object from an array of 16 bytes. |
| * |
| * @param bytes |
| * Array of 16 bytes. |
| * @return A UUID object. |
| * @throws CTFException |
| * the byte buffer was the wrong size |
| */ |
| public static UUID makeUUID(byte bytes[]) throws CTFException { |
| long high = 0; |
| long low = 0; |
| |
| if (bytes.length < Utils.UUID_LEN) { |
| throw new CTFException("UUID byte field must be 16 bytes long"); //$NON-NLS-1$ |
| } |
| final int bitsPerByte = Byte.SIZE; |
| int bitMask = (1 << bitsPerByte) - 1; |
| for (int i = 0; i < bitsPerByte; i++) { |
| low = (low << bitsPerByte) | (bytes[i + bitsPerByte] & bitMask); |
| high = (high << bitsPerByte) | (bytes[i] & bitMask); |
| } |
| |
| return new UUID(high, low); |
| } |
| |
| } |