blob: d8828349337c2191d2b309aed3964b5c0d742499 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Ericsson
*
* 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:
* Vincent Perot - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.internal.pcap.core.util;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.pcap.core.protocol.ethernet2.EthernetIIValues;
/**
* Class for helping with the conversion of data.
*
* @author Vincent Perot
*/
public final class ConversionHelper {
private static final char[] HEX_ARRAY = checkNotNull("0123456789abcdef".toCharArray()); //$NON-NLS-1$
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final String DEFAULT_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$
private static final DateFormat DATE_FORMATTER = new SimpleDateFormat(DEFAULT_TIME_PATTERN);
private ConversionHelper() {
}
/**
* Generate an integer from an unsigned byte.
*
* @param n
* the unsigned byte.
* @return the integer representing the unsigned value.
*/
public static int unsignedByteToInt(byte n) {
return n & 0x000000FF;
}
/**
* Generate an integer from an unsigned short.
*
* @param n
* the unsigned short.
* @return the integer representing the unsigned value.
*/
public static int unsignedShortToInt(short n) {
return n & 0x0000FFFF;
}
/**
* Generate a long from an unsigned integer.
*
* @param n
* the unsigned integer.
* @return the long representing the unsigned value.
*/
public static long unsignedIntToLong(int n) {
return n & 0x00000000FFFFFFFFL;
}
/**
* Generate an hex number from a byte array.
*
* @param bytes
* The array of bytes.
* @param spaced
* Whether there must be a space between each byte or not.
* @return the hex as a string.
*/
public static String bytesToHex(byte[] bytes, boolean spaced) {
// No need to check for character encoding since bytes represents a
// number.
if (bytes.length == 0) {
return EMPTY_STRING;
}
char[] hexChars = spaced ? new char[bytes.length * 3 - 1] : new char[bytes.length * 2];
int delta = spaced ? 3 : 2;
char separator = ' ';
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * delta] = HEX_ARRAY[v >>> 4];
hexChars[j * delta + 1] = HEX_ARRAY[v & 0x0F];
if (spaced && (j != bytes.length - 1)) {
hexChars[j * delta + 2] = separator;
}
}
return new String(hexChars);
}
// TODO Add little endian support
/**
* Generate a string representing the MAC address.
*
* @param mac
* The MAC address as a byte array.
* @return The string representing the MAC address.
*/
public static String toMacAddress(byte[] mac) {
if (mac.length != EthernetIIValues.MAC_ADDRESS_SIZE) {
throw new IllegalArgumentException();
}
char separator = ':';
return String.format("%02x", mac[0]) + separator + //$NON-NLS-1$
String.format("%02x", mac[1]) + separator + //$NON-NLS-1$
String.format("%02x", mac[2]) + separator + //$NON-NLS-1$
String.format("%02x", mac[3]) + separator + //$NON-NLS-1$
String.format("%02x", mac[4]) + separator + //$NON-NLS-1$
String.format("%02x", mac[5]); //$NON-NLS-1$
}
// TODO support non GMT time.
/**
* Convert a timestamp into a date.
*
* @param ts
* The timestamp. It represents the time since Epoch in
* microseconds.
* @param scale
* The scale of the timestamp.
* @return The date as a string.
*/
public static String toGMTTime(long ts, PcapTimestampScale scale) {
long timestamp;
switch (scale) {
case MICROSECOND:
timestamp = ts * 1000;
break;
case NANOSECOND:
timestamp = ts;
break;
default:
throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$
}
return format(timestamp);
}
/**
* Format the timestamp to a string.
*
* @param value
* the timestamp value to format (in ns)
* @return the formatted timestamp
*/
private static String format(long value) {
// Split the timestamp value into its sub-components
long date = value / 1000000; // milliseconds since epoch
long cs = Math.abs((value % 1000000) / 1000); // microseconds
long ns = Math.abs(value % 1000); // nanoseconds
Date dateObject = new Date(date);
StringBuilder sb = new StringBuilder(DATE_FORMATTER.format(dateObject));
sb.append('.')
.append(String.format("%03d", cs)) //$NON-NLS-1$
.append('.')
.append(String.format("%03d", ns)); //$NON-NLS-1$
return NonNullUtils.nullToEmptyString(sb);
}
}