com.illposed.osc.utility.OSCJavaToByteArrayConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ProcessingTUIO Show documentation
Show all versions of ProcessingTUIO Show documentation
Tuio Processing, PapARt version.
The newest version!
/**
* @author cramakrishnan
*
* Copyright (C) 2003, C. Ramakrishnan / Illposed Software
* All rights reserved.
*
* See license.txt (or license.rtf) for license information.
*
*
* OSCJavaToByteArrayConverter is a helper class that translates
* from Java types to the format the OSC spec specifies for those
* types.
*
* This implementation is based on Markus Gaelli and
* Iannis Zannos' OSC implementation in Squeak:
* http://www.emergent.de/Goodies/
*/
package com.illposed.osc.utility;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.Enumeration;
import java.util.Vector;
public class OSCJavaToByteArrayConverter {
protected ByteArrayOutputStream stream = new ByteArrayOutputStream();
private byte[] intBytes = new byte[4];
/*public OSCJavaToByteArrayConverter() {
super();
}*/
/**
* Creation date: (2/23/2001 2:43:25 AM)
* @param anArray java.lang.Object[]
*
*/
public void appendNullCharToAlignStream() {
int mod = stream.size() % 4;
int pad = 4 - mod;
for (int i = 0; i < pad; i++)
stream.write(0);
}
/**
* Creation date: (2/23/2001 2:21:53 AM)
* @return byte[]
*/
public byte[] toByteArray() {
return stream.toByteArray();
}
/**
* Creation date: (2/23/2001 2:14:23 AM)
* @param bytes byte[]
*/
public void write(byte[] bytes) {
writeBigEndToFourByteBoundry(bytes);
}
/**
* Creation date: (2/23/2001 2:21:04 AM)
* @param i int
*/
public void write(int i) {
writeIntegerToByteArray(i);
}
/**
* Creation date: (2/23/2001 2:03:57 AM)
* @param f java.lang.Float
*/
public void write(Float f) {
writeIntegerToByteArray(Float.floatToIntBits(f.floatValue()));
}
/**
* Creation date: (2/23/2001 2:08:36 AM)
* @param i java.lang.Integer
*/
public void write(Integer i) {
writeIntegerToByteArray(i.intValue());
}
/**
* Creation date: (2/23/2001 1:57:35 AM)
* @param str java.lang.String
*/
public void write(String str) {
writeLittleEndToFourByteBoundry(str.getBytes());
}
/**
* Creation date: (2/23/2001 2:08:36 AM)
* @param c char
*/
public void write(char c) {
stream.write(c);
}
/**
* Creation date: (2/23/2001 2:02:54 AM)
* @param anObject java.lang.Object
*/
public void write(Object anObject) {
// Can't do switch on class
if (null == anObject)
return;
if (anObject instanceof Float) {
write((Float) anObject);
return;
}
if (anObject instanceof String) {
write((String) anObject);
return;
}
if (anObject instanceof Integer) {
write((Integer) anObject);
return;
}
}
/**
* Creation date: (2/23/2001 2:43:25 AM)
* @param aClass Class
*/
public void writeType(Class c) {
// A big ol' case statement -- what's polymorphism mean, again?
// I really wish I could extend the base classes!
// use the appropriate flags to tell SuperCollider what kind of
// thing it is looking at
if (Integer.class.equals(c)) {
stream.write('i');
return;
}
if (java.math.BigInteger.class.equals(c)) {
stream.write('h');
return;
}
if (Float.class.equals(c)) {
stream.write('f');
return;
}
if (Double.class.equals(c)) {
stream.write('d');
return;
}
if (String.class.equals(c)) {
stream.write('s');
return;
}
if (Character.class.equals(c)) {
stream.write('c');
return;
}
}
/**
* Creation date: (2/23/2001 2:43:25 AM)
* @param anArray java.lang.Object[]
*/
public void writeTypesArray(Object[] array) {
// A big ol' case statement in a for loop -- what's polymorphism mean, again?
// I really wish I could extend the base classes!
for (int i = 0; i < array.length; i++) {
if (null == array[i])
continue;
// if the array at i is a type of array write a [
// This is used for nested arguments
if (array[i].getClass().isArray()) {
stream.write('[');
// fill the [] with the SuperCollider types corresponding to the object
// (i.e. Object of type String needs -s).
writeTypesArray((Object[]) array[i]);
// close the array
stream.write(']');
continue;
}
// Create a way to deal with Boolean type objects
if (Boolean.TRUE.equals(array[i])) {
stream.write('T');
continue;
}
if (Boolean.FALSE.equals(array[i])) {
stream.write('F');
continue;
}
// go through the array and write the superCollider types as shown in the
// above method. the Classes derived here are used as the arg to the above method
writeType(array[i].getClass());
}
// align the stream with padded bytes
appendNullCharToAlignStream();
}
/**
* Same as writeSuperColliderTypes(Object[]), just that it takes a vector (for jdk1.1
* compatibility), rather than an array.
* @param vector the collection I am to write out types for
*/
public void writeTypes(Vector vector) {
// A big ol' case statement in a for loop -- what's polymorphism mean, again?
// I really wish I could extend the base classes!
Enumeration enm = vector.elements();
Object nextObject;
while (enm.hasMoreElements()) {
nextObject = enm.nextElement();
if (null == nextObject)
continue;
// if the array at i is a type of array write a [
// This is used for nested arguments
if (nextObject.getClass().isArray()) {
stream.write('[');
// fill the [] with the SuperCollider types corresponding to the object
// (e.g., Object of type String needs -s).
writeTypesArray((Object[]) nextObject);
// close the array
stream.write(']');
continue;
}
// Create a way to deal with Boolean type objects
if (Boolean.TRUE.equals(nextObject)) {
stream.write('T');
continue;
}
if (Boolean.FALSE.equals(nextObject)) {
stream.write('F');
continue;
}
// go through the array and write the superCollider types as shown in the
// above method. the Classes derived here are used as the arg to the above method
writeType(nextObject.getClass());
}
// align the stream with padded bytes
appendNullCharToAlignStream();
}
/**
* convert an integer to byte array
*
* @param value int
*/
private void writeIntegerToByteArray(int value) {
byte[] intBytes = new byte[4];
intBytes[3] = (byte)value; value>>>=8;
intBytes[2] = (byte)value; value>>>=8;
intBytes[1] = (byte)value; value>>>=8;
intBytes[0] = (byte)value;
try {
stream.write(intBytes);
} catch (IOException e) {
throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream");
}
}
/**
* Line up the BigEnd of the bytes to a 4 byte boundry
*
* @param bytes byte[]
*/
private void writeBigEndToFourByteBoundry(byte[] bytes) {
int mod = bytes.length % 4;
// if the remainder == 0 write the bytes
if (mod == 0) {
try { stream.write(bytes); } catch (IOException e)
{ throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); }
return;
}
// pad the bytes to lineup correctly
int pad = 4 - mod;
byte[] newBytes = new byte[pad + bytes.length];
System.arraycopy(bytes,0,newBytes,pad,bytes.length);
try { stream.write(newBytes); } catch (IOException e)
{ throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); }
}
/**
* Line up the LittleEnd of the bytes to a 4 byte boundry
*
* @param bytes byte[]
*/
private void writeLittleEndToFourByteBoundry(byte[] bytes) {
int mod = bytes.length % 4;
// if the remainder == 0 write the bytes
if (mod == 4) {
try { stream.write(bytes); } catch (IOException e)
{ throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); }
return;
}
// pad the bytes to lineup correctly
int pad = 4 - mod;
byte[] newBytes = new byte[pad + bytes.length];
System.arraycopy(bytes,0,newBytes,0,bytes.length);
try { stream.write(newBytes); } catch (IOException e)
{ throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); }
}
}