package de.uni.trier.infsec.utils;


public class MessageTools {
	
	public static byte[] copyOf(byte[] message) {
		if (message==null) return null;
		byte[] copy = new byte[message.length];
		for (int i = 0; i < message.length; i++) {
			copy[i] = message[i];
		}
		return copy;
	}

    public static boolean equal(byte[] a, byte[] b) {
        if( a.length != b.length ) return false;
        for( int i=0; i<a.length; ++i)
            if( a[i] != b[i] ) return false;
        return true;
    }			

	public static byte[] getZeroMessage(int messageSize) {
		byte[] zeroVector = new byte[messageSize];
		for (int i = 0; i < zeroVector.length; i++) {
			zeroVector[i] = 0x00;
		}
		return zeroVector;
	}	
	
	public static byte[] concatenate(byte[] m1, byte[] m2) {
		// Concatenated Message --> byte[0-3] = Integer, Length of Message 1
		byte[] out = new byte[m1.length + m2.length + 4];

		// 4 bytes for length
		byte[] len = intToByteArray(m1.length);

		// copy all bytes to output array
		int j = 0;
		for( int i=0; i<len.length; ++i ) out[j++] = len[i];
		for( int i=0; i<m1.length;  ++i ) out[j++] = m1[i];
		for( int i=0; i<m2.length;  ++i ) out[j++] = m2[i];

		return out;
	}

	/**
	 * Projection of the message to its two parts (part 1 = position 0, part 2 = position 1) Structure of the expected data: 1 Byte Identifier [0x01], 4 Byte
	 * length of m1, m1, m2
	 */
	private static byte[] project(byte[] message, int position) {
		try {
			int len = byteArrayToInt(message);
			if (len > (message.length - 4)) return new byte[]{}; // Something is wrong with the message!
			if (position == 0) {
				byte[] m1 = new byte[len];
				for (int i = 0; i < len; i ++) m1[i] = message[i + 4];
				return m1;
			} else if (position == 1) {
				byte[] m2 = new byte[message.length - len - 4];
				for (int i = 0; i < message.length - len - 4; i ++) m2[i] = message[i + 4 + len];
				return m2;
			} else return new byte[]{};
		} catch (Exception e) {
			return new byte[]{};
		}
	}

	public static byte[] first(byte[] in) {
		return project(in, 0);
	}

	public static byte[] second(byte[] in) {
		return project(in, 1);
	}

	public static final int byteArrayToInt(byte [] b) {
        return (b[0] << 24)
                + ((b[1] & 0xFF) << 16)
                + ((b[2] & 0xFF) << 8)
                + (b[3] & 0xFF);
	}
	

	public static final byte[] intToByteArray(int value) {
	        return new byte[] {
	                (byte)(value >>> 24),
	                (byte)(value >>> 16),
	                (byte)(value >>> 8),
	                (byte)value};
	}
}

@@ -699,16 +699,234 @@
 ;%0A%09%7D%09%0A%09%0A
+%09/**%0A%09 * Concatenates messages in a way that makes it possible to unambiguously%0A%09 * split the message into the original messages (it adds length of the%0A%09 * first message at the beginning of the returned message).%0A%09 */%0A
 %09public 
@@ -1397,16 +1397,373 @@
 ut;%0A%09%7D%0A%0A
+%09/**%0A%09 * Simply concatenates the messages (without adding any information for%0A%09 * de-concatenation).%0A%09 */%0A%09public static byte%5B%5D raw_concatenate(byte%5B%5D a, byte%5B%5D b) %7B%0A%09%09byte%5B%5D result = new byte%5Ba.length + b.length%5D;%0A%09%09int j = 0;%0A%09%09for( int i=0; i%3Ca.length; ++i ) result%5Bj++%5D = a%5Bi%5D;%0A%09%09for( int i=0; i%3Cb.length; ++i ) result%5Bj++%5D = b%5Bi%5D;%0A%09%09return result;%0A%09%7D%0A%0A
 %09/**%0A%09 *

add raw concatenation to MessageTools