org.energy_home.jemma.javagal.layers.data.implementations.Utils.DataManipulation.java Source code

Java tutorial

Introduction

Here is the source code for org.energy_home.jemma.javagal.layers.data.implementations.Utils.DataManipulation.java

Source

/**
 * This file is part of JEMMA - http://jemma.energy-home.org
 * (C) Copyright 2013 Telecom Italia (http://www.telecomitalia.it)
 *
 * JEMMA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (LGPL) version 3
 * or later as published by the Free Software Foundation, which accompanies
 * this distribution and is available at http://www.gnu.org/licenses/lgpl.html
 *
 * JEMMA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License (LGPL) for more details.
 *
 */
package org.energy_home.jemma.javagal.layers.data.implementations.Utils;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Utility class with a number of data's manipulation methods. 
 * 
 * @author "Ing. Marco Nieddu <marco.nieddu@consoft.it> or <marco.niedducv@gmail.com> from Consoft Sistemi S.P.A.<http://www.consoft.it>, financed by EIT ICT Labs activity SecSES - Secure Energy Systems (activity id 13030)"
 *
 */
public class DataManipulation {

    /**
     * Start sequence in received frames.
     */
    public final static int SEQUENCE_START = 0x02;
    /**
     * Index of the first payload's byte in frames.
     */
    public final static int START_PAYLOAD_INDEX = 4;

    // Defining array of bytes to pass later to the key

    private static Log logger = LogFactory.getLog(DataManipulation.class);

    /**
     * Converts a string to an array of bytes.
     * 
     * @param s
     *            the string to convert.
     * @return the converted array of bytes.
     */
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * Converts a string to an array of shorts.
     * 
     * @param _list
     *            the short list to convert.
     * @return the converted array of shorts.
     */
    public static short[] toVectFromList(List<Short> _list) {
        short[] _vect = new short[_list.size()];
        int i = 0;
        for (short s : _list)
            _vect[i++] = s;
        return _vect;

    }

    /**
     * Creates an int starting from two given shorts. An int is composed of four
     * bytes. Numbering the four bytes from 1 (the most important) to 4 (the
     * least important), the converted int will be formed placing the two given
     * bytes in the two less important places of the created int.
     * <p>
     * More formally the low byte will be placed in position 4, the high byte
     * will be placed in position 3, while positions 1 and 2 will be set at
     * zero.
     * 
     * @param hb
     *            the high byte.
     * @param lb
     *            the low byte.
     * @return the result int.
     */
    public static int toIntFromShort(byte hb, byte lb) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0x00, 0x00, hb, lb });
        return bb.getInt();
    }

    /**
     * Creates a long starting from eight given bytes. A long is composed of
     * eight bytes. Numbering them from 1 (the most important) to 8 (the least
     * important), the given bytes will be placed in the place indicated by
     * their respective names.
     * 
     * @param _1
     *            byte placed in position 1
     * @param _2
     *            byte placed in position 2
     * @param _3
     *            byte placed in position 3
     * @param _4
     *            byte placed in position 4
     * @param _5
     *            byte placed in position 5
     * @param _6
     *            byte placed in position 6
     * @param _7
     *            byte placed in position 7
     * @param _8
     *            byte placed in position 8
     * @return the resulting long
     */
    public static long toLong(byte _1, byte _2, byte _3, byte _4, byte _5, byte _6, byte _7, byte _8) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[] { _1, _2, _3, _4, _5, _6, _7, _8 });
        return bb.getLong();
    }

    /**
     * Starts from a {@code short[]} and returns a sub array, converted as
     * {@code byte[]}.
     * 
     * @param array
     *            the original array
     * @param start
     *            the start index, included
     * @param stop
     *            the stop index, included
     * @return the converted sub array
     */
    public static byte[] subByteArray(short[] array, int start, int stop) {
        byte[] toReturn = new byte[stop - start + 1];
        for (int i = start; i <= stop; i++) {
            toReturn[i - start] = (byte) array[i];
        }
        return toReturn;
    }

    /**
     * Converts a {@code long} to a {@code List<Byte>}. A long is composed of
     * eight bytes. Numbering them from 1 (the most important) to 8 (the least
     * important), the resulting list will have all them placed in the same
     * order. The pad parameter indicate the minimum size of the resulting list.
     * In case its size is less then the one indicated in the pad parameter, a
     * number of leading zeros will be inserted.
     * 
     * @param toConvert
     *            the long to convert.
     * @param pad
     *            the minimum size of the returned {@code Byte}'s list.
     * @return the converted list.
     */
    public static List<Byte> toByteList(Long toConvert, int pad) {
        List<Byte> toReturn = new ArrayList<Byte>();

        String inString = Long.toHexString(toConvert);

        int length = inString.length();

        // Characters must be even in number
        if (length % 2 != 0) {
            // System.out
            // .print("Odd number of chars in conversion from Long to byte[] ");
            inString = "0" + inString;
            length = inString.length();
        }

        for (int start = 0; start < length; start += 2) {
            toReturn.add((byte) Short.parseShort(inString.substring(start, Math.min(length, start + 2)), 16));
        }

        if (toReturn.size() < pad) {
            int diff = pad - toReturn.size();
            for (int i = 0; i < diff; i++) {
                toReturn.add(0, (byte) 0);
            }
        }

        return toReturn;
    }

    /**
     * Converts a {@code Short} to a {@code List<Byte>}. A short is composed of
     * two bytes. Numbering them from 1 (the most important) to 2 (the least
     * important), the resulting list will have all them placed in the same
     * order. The pad parameter indicate the minimum size of the resulting list.
     * In case its size is less then the one indicated in the pad parameter, a
     * number of leading zeros will be inserted.
     * 
     * @param toConvert
     *            the short to convert.
     * @param pad
     *            the minimum size of the returned {@code Byte}'s list.
     * @return the converted list.
     */
    public static List<Byte> toByteList(Short toConvert, int pad) {
        List<Byte> toReturn = new ArrayList<Byte>();

        String inString = Integer.toHexString(toConvert);

        int length = inString.length();

        // Characters must be even in number
        if (length % 2 != 0) {
            // System.out
            // .print("Odd number of chars in conversion from Long to byte[] ");
            inString = "0" + inString;
            length = inString.length();
        }

        for (int start = 0; start < length; start += 2) {
            toReturn.add((byte) Short.parseShort(inString.substring(start, Math.min(length, start + 2)), 16));
        }

        if (toReturn.size() < pad) {
            int diff = pad - toReturn.size();
            for (int i = 0; i < diff; i++) {
                toReturn.add(0, (byte) 0);
            }
        }

        return toReturn;
    }

    /**
     * Converts a {@code long} to a {@code byte[]}. A long is composed of eight
     * bytes. Writes eight bytes containing the given long value, in the current
     * byte order. Numbering them from 0 (the most important) to 7 (the least
     * important), the resulting array will have all them placed in the same
     * position.
     * 
     * @return the converted list.
     * @param x
     *            the long to convert
     * @return the resulting array.
     */
    public static byte[] longToBytes(long x) {
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.putLong(x);
        return buffer.array();
    }

    /**
     * Converts an {@code int} to a {@code byte[]}. An int is composed of four
     * bytes. Writes four bytes containing the given int value, in the current
     * byte order. Numbering them from 0 (the most important) to 5 (the least
     * important), the resulting array will have all them placed in the same
     * position.
     * 
     * @param x
     *            the int to convert.
     * @return the resulting array.
     */
    public static byte[] intToBytes(int x) {
        ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.putInt(x);
        return buffer.array();
    }

    /**
     * Converts a {@code BigInteger} to a {@code byte[]}. The resulting array
     * will have all bytes contained in the BigInteger placed in the same
     * position (from byte 0 to byte n). The pad parameter indicate the minimum
     * size of the resulting array. In case its size would be less then the one
     * indicated in the pad parameter, a number of leading zeros will be
     * inserted.
     * 
     * @param toConvert
     *            the BigInteger to convert.
     * @param pad
     *            the minimum size of the returned array.
     * @return the resulting array.
     */
    public static byte[] toByteVect(BigInteger toConvert, int pad) {
        byte[] toReturn = new byte[pad];
        byte[] byteArray = toConvert.toByteArray();
        int i;
        for (i = 0; i <= (pad - byteArray.length - 1); i++)
            toReturn[i] = 0;
        int x = 0;
        for (; i <= (toReturn.length - 1); i++)
            toReturn[i] = byteArray[x++];
        return toReturn;
    }

    /**
     * Converts a {@code Long} to a {@code byte[]}. A Long is composed of eight
     * bytes. In case pad is set to 8, writes eight bytes containing the given
     * Long value, in the current byte order. The pad parameter indicate the
     * minimum size of the resulting array. In case its size would be less then
     * the one indicated in the pad parameter, a number of leading zeros will be
     * inserted.
     * 
     * @param toConvert
     *            the Long to convert.
     * @param pad
     *            the minimum size of the returned array.
     * @return the resulting array.
     */
    public static byte[] toByteVect(Long toConvert, int pad) {
        byte[] toReturn = new byte[pad];
        byte[] byteArray = longToBytes(toConvert);
        int i;
        for (i = 0; i <= (pad - byteArray.length - 1); i++)
            toReturn[i] = 0;
        int x = 0;
        for (; i <= (toReturn.length - 1); i++)
            toReturn[i] = byteArray[x++];
        return toReturn;

    }

    /**
     * Converts an {@code int} to a {@code byte[]}. An int is composed of four
     * bytes. In case pad is set to 4, writes eight bytes containing the given
     * int value, in the current byte order. The pad parameter indicate the
     * minimum size of the resulting array. In case its size would be less then
     * the one indicated in the pad parameter, a number of leading zeros will be
     * inserted.
     * 
     * @param toConvert
     *            the int to convert.
     * @param pad
     *            the minimum size of the returned array.
     * @return the resulting array.
     */
    public static byte[] toByteVect(int toConvert, int pad) {
        byte[] toReturn = new byte[pad];
        byte[] byteArray = intToBytes(toConvert);
        int i;
        for (i = 0; i <= (pad - byteArray.length - 1); i++)
            toReturn[i] = 0;
        int x = 0;
        for (; i <= (toReturn.length - 1); i++)
            toReturn[i] = byteArray[x++];
        return toReturn;
    }

    /**
     * Logs an hexadecimal representation of a given {@code short[]}, preceded
     * by a leading caption.
     * 
     * @param caption
     *            the leading caption.
     * @param arr
     *            the array to log.
     */
    public static void logArrayHexRadix(String caption, short[] arr) {
        StringBuilder sb = new StringBuilder();
        for (short s : arr) {
            sb.append(String.format("%02X", s));
        }
        logger.info(caption + ":" + sb.toString());
    }

    /**
     * Logs an hexadecimal representation of a given {@code short[]}, preceded
     * by a leading caption.
     * 
     * @param caption
     *            the leading caption.
     * @param arr
     *            the array to log.
     */
    public static void logArrayHexRadixDataReceived(String caption, short[] arr) {
        StringBuilder sb = new StringBuilder();
        for (short s : arr) {
            sb.append(String.format("%02X", s));
        }
        logger.info(caption + sb.toString());
    }

    /**
     * Logs an hexadecimal representation of a given {@code byte[]}, preceded by
     * a leading caption.
     * 
     * @param caption
     *            the leading caption.
     * @param arr
     *            the array to log.
     */
    public static void logArrayHexRadix(String caption, byte[] arr) {
        StringBuilder sb = new StringBuilder();
        for (byte s : arr) {
            sb.append(String.format("%02X", s));
        }
        logger.info(caption + ":" + sb.toString());
    }

    /**
     * Produces an hexadecimal string representation of a given {@code byte[]}.
     * 
     * @param arr
     *            the array to convert.
     * @return the produced hexadecimal string representation.
     */
    public static String convertBytesToString(byte[] arr) {
        String sb = new String();
        for (byte s : arr) {
            sb += String.format("%02X", s);
        }
        return sb;
    }

    /**
     * Reverses the order of elements in a given {@code byte[]}.
     * 
     * @param _vect
     *            the array to reverse.
     * @return the reversed array.
     */
    public static byte[] reverseBytes(byte[] _vect) {
        if (_vect == null) {
            return null;
        }
        byte[] _toReverse = new byte[_vect.length];
        for (int i = 0; i < _vect.length; i++)
            _toReverse[i] = _vect[i];

        int i = 0;
        int j = _toReverse.length - 1;
        byte tmp;
        while (j > i) {
            tmp = _toReverse[j];
            _toReverse[j] = _toReverse[i];
            _toReverse[i] = tmp;
            j--;
            i++;
        }
        return _toReverse;

    }

}