| /******************************************************************************* |
| * 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); |
| |
| } |
| |
| } |