front_processing/extern/TUIO_JAVA/src/com/illposed/osc/utility/OSCByteArrayToJavaConverter.java
changeset 0 6fefd4afe506
child 9 0f44b7360c8d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_processing/extern/TUIO_JAVA/src/com/illposed/osc/utility/OSCByteArrayToJavaConverter.java	Fri Mar 09 14:52:11 2012 +0100
@@ -0,0 +1,280 @@
+/* $Id: OSCByteArrayToJavaConverter.java,v 1.1.1.1 2006/11/13 14:47:22 modin Exp $
+ * Created on 28.10.2003
+ */
+package com.illposed.osc.utility;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import com.illposed.osc.*;
+
+/**
+ * @author cramakrishnan
+ *
+ * Copyright (C) 2003, C. Ramakrishnan / Auracle
+ * All rights reserved.
+ * 
+ * See license.txt (or license.rtf) for license information.
+ */
+public class OSCByteArrayToJavaConverter {
+
+	byte[] bytes;
+	int bytesLength;
+	int streamPosition;
+
+	private byte[] intBytes   = new byte[4];
+	private byte[] floatBytes = new byte[4];
+
+	private	byte[] secondBytes = new byte[8];
+	private	byte[] picosecBytes = new byte[8];
+
+	/**
+	 * Helper object for converting from a byte array to Java objects
+	 */
+	/*public OSCByteArrayToJavaConverter() {
+		super();
+	}*/
+
+	public OSCPacket convert(byte[] byteArray, int bytesLength) {
+		bytes = byteArray;
+		this.bytesLength = bytesLength;
+		streamPosition = 0;
+		if (isBundle())
+			return convertBundle();
+		else
+			return convertMessage();
+	}
+
+	private boolean isBundle() {
+		// only need the first 7 to check if it is a bundle
+		String bytesAsString = new String(bytes, 0, 7);
+		return bytesAsString.startsWith("#bundle");
+	}                               
+                               
+	private OSCBundle convertBundle() {
+		// skip the "#bundle " stuff
+		streamPosition = 8;
+		Date timestamp = readTimeTag();
+		OSCBundle bundle = new OSCBundle(timestamp);
+		OSCByteArrayToJavaConverter myConverter = new OSCByteArrayToJavaConverter();
+		while (streamPosition < bytesLength) {
+			// recursively read through the stream and convert packets you find
+			int packetLength = ((Integer) readInteger()).intValue();
+			byte[] packetBytes = new byte[packetLength];
+			//streamPosition++;
+			System.arraycopy(bytes,streamPosition,packetBytes,0,packetLength);
+			streamPosition+=packetLength;
+			//for (int i = 0; i < packetLength; i++)
+			//	packetBytes[i] = bytes[streamPosition++];
+			OSCPacket packet = myConverter.convert(packetBytes, packetLength);
+			bundle.addPacket(packet);
+		}
+		return bundle;
+	}
+
+	private OSCMessage convertMessage() {
+		OSCMessage message = new OSCMessage();
+		message.setAddress(readString());
+		char[] types = readTypes();
+		if (null == types) {
+			// we are done
+			return message;
+		}
+		moveToFourByteBoundry();
+		for (int i = 0; i < types.length; i++) {
+			if ('[' == types[i]) {
+				// we're looking at an array -- read it in
+				message.addArgument(readArray(types, i));
+				// then increment i to the end of the array
+				while (']' != types[i])
+					i++;
+			} else
+				message.addArgument(readArgument(types[i]));
+		}
+		return message;
+	}
+
+	private String readString() {
+		int strLen = lengthOfCurrentString();
+		char[] stringChars = new char[strLen];
+		//System.arraycopy(bytes,streamPosition,stringChars,0,strLen);
+		//streamPosition+=strLen;
+		for (int i = 0; i < strLen; i++)
+			stringChars[i] = (char) bytes[streamPosition++];
+		moveToFourByteBoundry();
+		return new String(stringChars);
+	}
+
+	/**
+	 * @return a char array with the types of the arguments
+	 */
+	private char[] readTypes() {
+		// the next byte should be a ","
+		if (bytes[streamPosition] != 0x2C)
+			return null;
+		streamPosition++;
+		// find out how long the list of types is
+		int typesLen = lengthOfCurrentString();
+		if (0 == typesLen) {
+			return null;
+		}
+		// read in the types
+		char[] typesChars = new char[typesLen];
+		for (int i = 0; i < typesLen; i++) {
+			typesChars[i] = (char) bytes[streamPosition++];
+		}
+		return typesChars;
+	}
+
+	/**
+	 * @param c type of argument
+	 * @return a Java representation of the argument
+	 */
+	private Object readArgument(char c) {
+		switch (c) {
+			case 'i' :
+				return readInteger();
+			case 'h' :
+				return readBigInteger();
+			case 'f' :
+				return readFloat();
+			case 'd' :
+				return readDouble();
+			case 's' :
+				return readString();
+			case 'c' :
+				return readChar();
+			case 'T' :
+				return Boolean.TRUE;
+			case 'F' :
+				return Boolean.FALSE;
+		}
+
+		return null;
+	}
+
+	/**
+	 * @return a Character
+	 */
+	private Object readChar() {
+		return new Character((char) bytes[streamPosition++]);
+	}
+
+	/**
+	 * @return a Double
+	 */
+	private Object readDouble() {
+		return readFloat();
+	}
+
+	/**
+	 * @return a Float
+	 */
+	private Object readFloat() {
+		//byte[] floatBytes = new byte[4];
+		floatBytes[0] = bytes[streamPosition++];
+		floatBytes[1] = bytes[streamPosition++];
+		floatBytes[2] = bytes[streamPosition++];
+		floatBytes[3] = bytes[streamPosition++];
+
+		int floatBits = 
+			((floatBytes[3] & 0xFF) ) +
+			((floatBytes[2] & 0xFF) << 8) +
+			((floatBytes[1] & 0xFF) << 16) +
+			((floatBytes[0] & 0xFF) << 24);
+		
+		return new Float(Float.intBitsToFloat(floatBits));
+	}
+
+	/**
+	 * @return a BigInteger
+	 */
+	private Object readBigInteger() {
+		//byte[] intBytes = new byte[4];
+		intBytes[0] = bytes[streamPosition++];
+		intBytes[1] = bytes[streamPosition++];
+		intBytes[2] = bytes[streamPosition++];
+		intBytes[3] = bytes[streamPosition++];
+
+		int intBits = 
+			((intBytes[3] & 0xFF) ) +
+			((intBytes[2] & 0xFF) << 8) +
+			((intBytes[1] & 0xFF) << 16) +
+			((intBytes[0] & 0xFF) << 24);
+		
+		return new Integer(intBits);
+	}
+
+	/**
+	 * @return an Integer
+	 */
+	private Object readInteger() {
+		//byte[] intBytes = new byte[4];
+		intBytes[0] = bytes[streamPosition++];
+		intBytes[1] = bytes[streamPosition++];
+		intBytes[2] = bytes[streamPosition++];
+		intBytes[3] = bytes[streamPosition++];
+
+		int intBits = 
+			((intBytes[3] & 0xFF) ) +
+			((intBytes[2] & 0xFF) << 8) +
+			((intBytes[1] & 0xFF) << 16) +
+			((intBytes[0] & 0xFF) << 24);
+		
+		return new Integer(intBits);
+	}
+	
+	/**
+	 * @return a Date
+	 */
+	private Date readTimeTag() {
+		//byte[] secondBytes = new byte[8];
+		//byte[] picosecBytes = new byte[8];
+		/*for (int i = 4; i < 8; i++)
+			secondBytes[i] = bytes[streamPosition++];
+		for (int i = 4; i < 8; i++)
+			picosecBytes[i] = bytes[streamPosition++];*/
+		System.arraycopy(bytes,streamPosition,secondBytes,4,4);
+		streamPosition+=4;
+		System.arraycopy(bytes,streamPosition,picosecBytes,4,4);
+		streamPosition+=4;
+		
+		BigInteger secsSince1900 = new BigInteger(secondBytes);
+		long secsSince1970 =  secsSince1900.longValue() - OSCBundle.SECONDS_FROM_1900_to_1970.longValue();
+		if (secsSince1970 < 0) secsSince1970 = 0; // no point maintaining times in the distant past
+		BigInteger picosecs = new BigInteger(picosecBytes);
+		long millisecs = (secsSince1970 * 1000) + (picosecs.longValue() / 1000);
+		return new Date(millisecs);
+	}
+
+	/**
+	 * @param types
+	 * @param i
+	 * @return an Array
+	 */
+	private Object[] readArray(char[] types, int i) {
+		int arrayLen = 0;
+		while (types[i + arrayLen] != ']')
+			arrayLen++;
+		Object[] array = new Object[arrayLen];
+		for (int j = 0; i < arrayLen; j++) {
+			array[j] = readArgument(types[i + j]);
+		}
+		return array;
+	}
+
+	private int lengthOfCurrentString() {
+		int i = 0;
+		while (bytes[streamPosition + i] != 0)
+			i++;
+		return i;
+	}
+
+	private void moveToFourByteBoundry() {
+		// If i'm already at a 4 byte boundry, I need to move to the next one
+		int mod = streamPosition % 4;
+		streamPosition += (4 - mod);
+	}
+
+}
+