diff options
Diffstat (limited to 'libraries/oscP5/src')
36 files changed, 8485 insertions, 0 deletions
diff --git a/libraries/oscP5/src/netP5/AbstractMulticast.java b/libraries/oscP5/src/netP5/AbstractMulticast.java new file mode 100644 index 0000000..6a85451 --- /dev/null +++ b/libraries/oscP5/src/netP5/AbstractMulticast.java @@ -0,0 +1,337 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.io.IOException; + +import java.net.MulticastSocket; +import java.net.SocketException; +import java.net.DatagramPacket; +import java.util.Vector; + +/** + * @invisible + */ +public abstract class AbstractMulticast implements Runnable { + + protected NetAddress _myNetAddress; + + protected boolean isRunning; + + protected boolean isSocket; + + protected MulticastSocket _myMulticastSocket; + + protected UdpPacketListener _myListener; + + protected int _myDatagramSize = 1536; + + private Thread _myThread; + + + /** + * @invisible + * @param theDatagramListener UdpPacketListener + * @param theMulticastAddress String + * @param thePort int + * @param theBufferSize int + */ + public AbstractMulticast( + final UdpPacketListener theDatagramListener, + final String theMulticastAddress, + final int thePort, + final int theBufferSize) { + _myDatagramSize = theBufferSize; + _myListener = theDatagramListener; + if (_myListener != null) { + init(theMulticastAddress, thePort); + } + } + + /** + * @invisible + * @param theDatagramListener UdpPacketListener + * @param theMulticastAddress String + * @param thePort int + */ + public AbstractMulticast( + final UdpPacketListener theDatagramListener, + final String theMulticastAddress, + final int thePort) { + _myListener = theDatagramListener; + if (_myListener != null) { + init(theMulticastAddress, thePort); + } + } + + protected void init(final String theMulticastAddress, final int thePort) { + _myNetAddress = new NetAddress(theMulticastAddress, thePort); + if (!_myNetAddress.isvalid()) { + Logger.printError("UdpClient", "unknown host " + + theMulticastAddress); + } + isRunning = openSocket(); + start(); + } + + + /** + * get the running multicast socket. + * @return MulticastSocket + */ + public MulticastSocket socket() { + return _myMulticastSocket; + } + + /** + * set the buffer size of the datagrams received by the multicast socket. + * @param theDatagramSize int + */ + public void setDatagramSize(int theDatagramSize) { + _myDatagramSize = theDatagramSize; + } + + /** + * @invisible + */ + public void start() { + _myThread = null; + _myMulticastSocket = null; + _myThread = new Thread(this); + try { + Thread.sleep(1000); + } catch (InterruptedException iex) { + Logger.printError("Multicast.start()", + "Multicast sleep interuption " + iex); + } + try { + _myMulticastSocket = new MulticastSocket(_myNetAddress.port()); + _myMulticastSocket.joinGroup(_myNetAddress.inetaddress()); + Logger.printProcess("Multicast.start()", + "new Multicast DatagramSocket created @ port " + + _myNetAddress.port()); + } catch (IOException ioex) { + Logger.printError("Multicast.start()", + " IOException, couldnt create new DatagramSocket @ port " + + _myNetAddress.port() + " " + ioex); + } + if (_myMulticastSocket != null) { + _myThread.start(); + isRunning = _myThread.isAlive(); + isSocket = true; + } else { + isRunning = false; + } + } + + /** + * @invisible + */ + public void run() { + if (_myMulticastSocket != null) { + if (isRunning) { + Logger.printProcess("Multicast.run()", + "Multicast is running @ " + + _myNetAddress.inetaddress().getHostAddress() + + ":" + _myNetAddress.port()); + } + } else { + Logger.printError("UdpServer.run()", + "Socket is null. closing UdpServer."); + return; + } + + while (isRunning) { + try { + byte[] myBuffer = new byte[_myDatagramSize]; + DatagramPacket myPacket = new DatagramPacket(myBuffer, + _myDatagramSize); + _myMulticastSocket.receive(myPacket); + Logger.printDebug("Multicast.run()","got it."); + _myListener.process(myPacket, _myNetAddress.port()); + } catch (IOException ioex) { + Logger.printError("UdpServer.run()", "IOException: " + ioex); + break; + } catch (ArrayIndexOutOfBoundsException ex) { + Logger.printError("UdpServer.run()", + "ArrayIndexOutOfBoundsException: " + ex); + } + } + dispose(); + } + + /** + * dispose the multicastSocket. + */ + public void dispose() { + close(); + } + + /** + * @invisible + */ + public void close() { + isRunning = false; + if (_myMulticastSocket != null) { + try { + _myMulticastSocket.leaveGroup(_myNetAddress.inetaddress()); + _myMulticastSocket.disconnect(); + _myMulticastSocket.close(); + _myMulticastSocket = null; + Logger.printProcess("Multicast.close", + "Closing multicast datagram socket."); + } catch (IOException e) { + + } + } + } + + private boolean openSocket() { + try { + _myMulticastSocket = new MulticastSocket(); + } catch (SocketException e) { + Logger.printError("Multicast.openSocket", "cant create socket " + + e.getMessage()); + return false; + } catch (IOException e) { + Logger.printError("Multicast.openSocket", + "cant create multicastSocket " + e.getMessage()); + return false; + } + Logger.printProcess("Multicast.openSocket", + "multicast socket initialized."); + return true; + } + + /** + * Set the default time-to-live for multicast packets + * sent out on this MulticastSocket in order to control the scope + * of the multicasts. theTTL must be in the range 0 <= ttl <= 255 + * @param theTTL int + * @return boolean + * @shortdesc Set the default time-to-live for multicast packets. + */ + public boolean setTimeToLive(int theTTL) { + try { + _myMulticastSocket.setTimeToLive(theTTL); + return true; + } catch (IOException ioe) { + Logger.printError("UdpServer.setTimeToLive()", "" + ioe); + } catch (IllegalArgumentException iae) { + Logger.printError("UdpServer.setTimeToLive()", "" + iae); + } + return false; + } + + /** + * get the current time to live value. + * + * @return int + */ + public int timeToLive() { + try { + return _myMulticastSocket.getTimeToLive(); + } catch (IOException ioe) { + Logger.printError("Multicast.getTimeToLive()", "" + ioe); + } + return -1; + } + + /** + * Disable/Enable local loopback of multicast datagrams. + * The option is used by the platform's networking code as a + * hint for setting whether multicast data will be + * looped back to the local socket. + * @shortdesc Disable/Enable local loopback of multicast datagrams. + * @param theFlag boolean + */ + public void setLoopback(boolean theFlag) { + try { + _myMulticastSocket.setLoopbackMode(theFlag); + } catch (SocketException se) { + Logger.printError("Multicast.setLoopback()", "" + se); + } + } + + /** + * get the current loopback mode. messages loop back to the local address + * if the loopback is set to false. set loopback to false to prevent messages + * to loop back to your local address. + * + * @return boolean + * @shortdesc get the current loopback mode. + */ + public boolean loopback() { + try { + return _myMulticastSocket.getLoopbackMode(); + } catch (SocketException se) { + Logger.printError("Multicast.loopback()", "" + se); + } + return false; + } + + protected void send(DatagramPacket thePacket) { + if (isRunning) { + try { + _myMulticastSocket.send(thePacket); + + } catch (IOException e) { + Logger.printError("Multicast.send", + "ioexception while sending packet."); + } + } + } + + /** + * send a string to the multicast address. + * @param theString String + */ + public void send(String theString) { + send(theString.getBytes()); + } + + /** + * send a byte array to the mulitcast address. + * @param theBytes byte[] + */ + public void send(byte[] theBytes) { + if (isRunning) { + try { + DatagramPacket myPacket = new DatagramPacket(theBytes, + theBytes.length, _myNetAddress.inetaddress(), + _myNetAddress.port()); + send(myPacket); + } catch (NullPointerException npe) { + Logger.printError("Multicast.send", + "a nullpointer exception occured." + npe); + } + } else { + Logger.printWarning("Multicast.send", + "DatagramSocket is not running. Packet has not been sent."); + } + } + +} diff --git a/libraries/oscP5/src/netP5/AbstractTcpClient.java b/libraries/oscP5/src/netP5/AbstractTcpClient.java new file mode 100644 index 0000000..7f6cac4 --- /dev/null +++ b/libraries/oscP5/src/netP5/AbstractTcpClient.java @@ -0,0 +1,491 @@ +/**
+ * A network library for processing which supports UDP, TCP and Multicast.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package netP5;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+/**
+ * @invisible
+ */
+public abstract class AbstractTcpClient implements Runnable {
+
+ private Socket _mySocket;
+
+ protected TcpPacketListener _myTcpPacketListener;
+
+ private PrintWriter _myOutput = null;
+
+ private BufferedReader _myInput = null;
+
+ private OutputStream _myOutputStream = null;
+
+ protected byte[] _myBytes = new byte[0];
+
+ protected StringBuffer _myStringBuffer = new StringBuffer(0);
+
+ protected AbstractTcpServer _myTcpServer;
+
+ protected NetAddress _myNetAddress;
+
+ protected int _myServerPort;
+
+ private Thread _myThread;
+
+ private char TERMINATOR = '\0';
+
+ /**
+ * terminator is readline.
+ */
+ public static final int MODE_READLINE = 0;
+
+ /**
+ * terminator is terminated, by default this is character '\0'
+ * and can be set with setTerminator
+ */
+ public static final int MODE_TERMINATED = 1;
+
+ /**
+ * terminator is newline.
+ */
+ public static final int MODE_NEWLINE = 2;
+
+ /**
+ * no terminator required, packets are sent via
+ * a tcp stream.
+ */
+ public static final int MODE_STREAM = 3;
+
+ private final int _myMode;
+
+ /**
+ * @invisible
+ * @param theTcpPacketListener TcpPacketListener
+ * @param theHost String
+ * @param thePort int
+ */
+ public AbstractTcpClient(final TcpPacketListener theTcpPacketListener,
+ final String theHost,
+ final int thePort) {
+ this(theTcpPacketListener, theHost, thePort, MODE_READLINE);
+ }
+
+ /**
+ * @invisible
+ * @param theHost String
+ * @param thePort int
+ */
+ public AbstractTcpClient(final String theHost,
+ final int thePort) {
+ this(null, theHost, thePort, MODE_READLINE);
+ }
+
+ /**
+ * @invisible
+ * @param theTcpPacketListener TcpPacketListener
+ * @param theHost String
+ * @param thePort int
+ * @param theMode int
+ */
+ public AbstractTcpClient(final TcpPacketListener theTcpPacketListener,
+ final String theHost,
+ final int thePort,
+ final int theMode) {
+ _myTcpPacketListener = theTcpPacketListener;
+ _myNetAddress = new NetAddress(theHost, thePort);
+ _myMode = theMode;
+ startSocket();
+ }
+
+ /**
+ * @invisible
+ * @param theHost String
+ * @param thePort int
+ * @param theMode int
+ */
+ public AbstractTcpClient(final String theHost,
+ final int thePort,
+ final int theMode) {
+ this(null, theHost, thePort, theMode);
+ }
+
+
+ /**
+ * @invisible
+ * @param theTcpServer AbstractTcpServer
+ * @param theSocket Socket
+ * @param theTcpPacketListener TcpPacketListener
+ * @param theServerPort int
+ * @param theMode int
+ */
+ public AbstractTcpClient(final AbstractTcpServer theTcpServer,
+ final Socket theSocket,
+ final TcpPacketListener theTcpPacketListener,
+ final int theServerPort,
+ final int theMode) {
+ _myTcpServer = theTcpServer;
+ _mySocket = theSocket;
+ _myTcpPacketListener = theTcpPacketListener;
+ _myServerPort = theServerPort;
+ _myMode = theMode;
+ startSocket();
+ }
+
+
+ private void startSocket() {
+ try {
+ if (_mySocket == null) {
+ _mySocket = new Socket(_myNetAddress.address(), _myNetAddress.port());
+ } else {
+ _myNetAddress = new NetAddress(_mySocket.getInetAddress().getHostAddress(),
+ _mySocket.getPort());
+ }
+ Logger.printProcess("TcpClient", "### starting new TcpClient " + _myNetAddress);
+ if (_myMode == MODE_STREAM) {
+ _myOutputStream = _mySocket.getOutputStream();
+ }
+ init();
+ } catch (final IOException e) {
+ Logger.printError("TcpClient",
+ "IOException while trying to create a new socket.");
+// handleStatus(NetStatus.CONNECTION_FAILED); // FIX! NetPlug is still null at this point. NetPlug has to exist first.
+ }
+ }
+
+
+ /**
+ * when a TCP connection is lost, reconnect to the server with reconnect().
+ */
+ public void reconnect() {
+ try {
+ Thread.sleep(1000);
+ } catch(final Exception e) { }
+ startSocket();
+ }
+
+
+ private void init() {
+ _myThread = new Thread(this);
+ _myThread.start();
+ }
+
+ /**
+ * to parse an incomming tcp message, a terminator character is required to
+ * determine the end of the message so that it can be parsed and forwarded.
+ *
+ * @param theTerminator
+ */
+ public void setTerminator(final char theTerminator) {
+ TERMINATOR = theTerminator;
+ }
+
+ /**
+ * stop and dispose a tcp client.
+ */
+ public void dispose() {
+ try {
+ // do io streams need to be closed first?
+ if (_myInput != null) {
+ _myInput.close();
+ }
+ if (_myOutput != null) {
+ _myOutput.close();
+ }
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ _myInput = null;
+ _myOutput = null;
+
+ try {
+ if (_mySocket != null) {
+ _mySocket.close();
+ }
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ if(_myThread==null) {
+ return;
+ }
+ _mySocket = null;
+ _myThread = null;
+ handleStatus(NetStatus.CONNECTION_CLOSED);
+ Logger.printProcess("TcpClient.dispose", "TcpClient closed.");
+ }
+
+ /**
+ * @invisible
+ */
+ public void run() {
+ if (_myMode == MODE_STREAM) {
+ try {
+ try {
+ // sleep a little bit to avoid threading and nullpointer
+ // issues when reconnecting.
+ _myThread.sleep(500);
+ } catch (final Exception e) {
+
+ }
+
+ final InputStream in = _mySocket.getInputStream();
+ while (!_mySocket.isClosed() && _mySocket != null) {
+ final int myLen = Bytes.toIntBigEndian(in);
+ if (myLen < 0) {
+ break;
+ }
+ _myBytes = Bytes.toByteArray(in, myLen);
+ handleInput();
+ }
+ } catch (final java.net.SocketException se) {
+ System.out.println("Connection reset.");
+ } catch (final Exception e) {
+ System.out.println("### EXCEPTION " + e);
+ }
+ try {
+ handleStatus(NetStatus.SERVER_CLOSED);
+ handleStatus(NetStatus.CONNECTION_TERMINATED);
+ dispose();
+ } catch (final NullPointerException e) {
+ System.out.println("### nullpointer while calling handleStatus.");
+ }
+ } else {
+ while (Thread.currentThread() == _myThread) {
+ switch (_myMode) {
+ case (MODE_TERMINATED):
+ read();
+ break;
+ case (MODE_READLINE):
+ default:
+ readline();
+ break;
+ }
+ break;
+ }
+ }
+ if (_myTcpServer != null) {
+ _mySocket = null;
+ _myTcpServer.remove(this);
+ }
+ }
+
+
+ private void read() {
+ try {
+ _myInput = new BufferedReader(new InputStreamReader(_mySocket.getInputStream()));
+
+ final char[] charBuffer = new char[1];
+ while (_myInput.read(charBuffer, 0, 1) != -1) {
+
+ /**@todo
+ * StringBuffer size is limited yet.
+ * increase the buffer size dynamically.
+ */
+ _myStringBuffer = new StringBuffer(4096);
+ while (charBuffer[0] != TERMINATOR && charBuffer[0] != 3) {
+ _myStringBuffer.append(charBuffer[0]);
+ _myInput.read(charBuffer, 0, 1);
+ }
+ _myBytes = _myStringBuffer.toString().getBytes();
+ handleInput();
+ }
+ } catch (final IOException e) {
+ Logger.printProcess("TcpClient.read()", "connection has been terminated.");
+ if (_myTcpServer == null) {
+ handleStatus(NetStatus.SERVER_CLOSED);
+ }
+ handleStatus(NetStatus.CONNECTION_TERMINATED);
+ }
+ }
+
+
+ private void readline() {
+ try {
+ _myOutput = new PrintWriter(_mySocket.getOutputStream(), true);
+ _myInput = new BufferedReader(new InputStreamReader(_mySocket.getInputStream()));
+ String inputLine;
+
+ while ((inputLine = _myInput.readLine()) != null) {
+ _myStringBuffer = new StringBuffer(inputLine);
+ _myBytes = _myStringBuffer.toString().getBytes();
+ handleInput();
+ }
+ } catch (final IOException e) {
+ Logger.printProcess("TcpClient.readline()", "connection has been terminated.");
+ handleStatus(NetStatus.CONNECTION_TERMINATED);
+ if (_myTcpServer == null) {
+ handleStatus(NetStatus.SERVER_CLOSED);
+ }
+ }
+ }
+
+ /**
+ * @invisible
+ */
+ public abstract void handleInput();
+
+ /**
+ * @invisible
+ * @param theIndex
+ */
+ public abstract void handleStatus(int theIndex);
+
+ /**
+ * @invisible
+ * @return
+ */
+ public TcpPacketListener listener() {
+ return _myTcpPacketListener;
+ }
+
+ /**
+ * get the server port.
+ * @return
+ */
+ public int serverport() {
+ return _myServerPort;
+ }
+
+ /**
+ * get the instance of the socket. more info at java.net.Socket
+ * @return
+ */
+ public Socket socket() {
+ return _mySocket;
+ }
+
+
+ /**
+ * get the mode of the terminator.
+ * @return
+ */
+ public int mode() {
+ return _myMode;
+ }
+
+
+ public String getString() {
+ return _myStringBuffer.toString();
+ }
+
+
+ public StringBuffer getStringBuffer() {
+ return _myStringBuffer;
+ }
+
+
+ public void send(final byte[] theBytes) {
+ if (_myMode == MODE_STREAM) {
+ try {
+ Bytes.toStream(_myOutputStream, theBytes);
+ } catch (final Exception ex) {
+ handleStatus(NetStatus.SEND_FAILED);
+ }
+ } else {
+ System.out.println("### sending bytes is only supported for STREAMs");
+ }
+ }
+
+
+ public void send(final byte[][] theBytes) {
+ if (_myMode == MODE_STREAM) {
+ try {
+ for (int i = 0; i < theBytes.length; i++) {
+ Bytes.toStream(_myOutputStream, theBytes[i]);
+ }
+ } catch (final Exception ex) {
+ handleStatus(NetStatus.SEND_FAILED);
+ }
+ } else {
+ System.out.println("### sending bytes is only supported for STREAMs");
+ }
+
+ }
+
+
+ public void send(final String theString) {
+ if (_myMode == MODE_STREAM) {
+ send(theString.getBytes());
+ } else {
+ switch (_myMode) {
+ case (MODE_TERMINATED):
+ _myOutput.write(theString + TERMINATOR);
+ break;
+ case (MODE_NEWLINE):
+ _myOutput.write(theString + "\n");
+ break;
+ case (MODE_READLINE):
+ default:
+ _myOutput.println(theString);
+ break;
+ }
+ _myOutput.flush();
+ }
+ }
+
+
+ public NetAddress netAddress() {
+ return _myNetAddress;
+ }
+
+
+ /**
+ * @deprecated
+ * @invisible
+ * @return NetAddress
+ */
+
+ public NetAddress netaddress() {
+ return _myNetAddress;
+ }
+
+
+ /**
+ * @param theNetAddress NetAddress
+ * @return boolean
+ */
+ public boolean equals(final NetAddress theNetAddress) {
+ if (theNetAddress.address().equals(_myNetAddress.address()) &&
+ theNetAddress.port() == _myNetAddress.port()) {
+ return true;
+ }
+ return false;
+ }
+
+
+ public boolean equals(final TcpClient theClient) {
+ return equals(theClient.netAddress());
+ }
+
+}
diff --git a/libraries/oscP5/src/netP5/AbstractTcpServer.java b/libraries/oscP5/src/netP5/AbstractTcpServer.java new file mode 100644 index 0000000..824efbb --- /dev/null +++ b/libraries/oscP5/src/netP5/AbstractTcpServer.java @@ -0,0 +1,317 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Enumeration; +import java.util.Vector; + +/** + * @invisible + */ + +public abstract class AbstractTcpServer implements Runnable, TcpPacketListener { + + protected ServerSocket _myServerSocket; + + protected static int _myPort; + + protected TcpPacketListener _myTcpPacketListener = null; + + protected Vector _myTcpClients; + + protected Thread _myThread; + + public final static int MODE_READLINE = TcpClient.MODE_READLINE; + + public final static int MODE_TERMINATED = TcpClient.MODE_TERMINATED; + + public final static int MODE_NEWLINE = TcpClient.MODE_NEWLINE; + + public final static int MODE_STREAM = TcpClient.MODE_STREAM; + + protected final int _myMode; + + protected Vector _myBanList; + + /** + * @invisible + * @param thePort + * int + * @param theMode + * int + */ + public AbstractTcpServer( + final int thePort, + final int theMode) { + _myPort = thePort; + _myMode = theMode; + _myTcpPacketListener = this; + init(); + } + + /** + * @invisible + * @param theTcpPacketListener + * TcpPacketListener + * @param thePort + * int + * @param theMode + * int + */ + public AbstractTcpServer( + final TcpPacketListener theTcpPacketListener, + final int thePort, + final int theMode) { + _myPort = thePort; + _myMode = theMode; + _myTcpPacketListener = theTcpPacketListener; + init(); + } + + protected void init() { + _myBanList = new Vector(); + _myServerSocket = null; + _myTcpClients = new Vector(); + try { + Thread.sleep(1000); + } catch (InterruptedException iex) { + Logger.printError("TcpServer.start()", + "TcpServer sleep interuption " + iex); + return; + } + try { + _myServerSocket = new ServerSocket(_myPort); + } catch (IOException e) { + Logger.printError("TcpServer.start()", "TcpServer io Exception " + + e); + return; + } + + _myThread = new Thread(this); + _myThread.start(); + Logger.printProcess("TcpServer", "ServerSocket started @ " + _myPort); + } + + /** + * ban an IP address from the server. + * @param theIP + */ + public void ban(String theIP) { + _myBanList.add(theIP); + for (int i = _myTcpClients.size() - 1; i >= 0; i--) { + if (((TcpClient) _myTcpClients.get(i)).netAddress().address() + .equals(theIP)) { + ((TcpClient) _myTcpClients.get(i)).dispose(); + } + } + } + + /** + * remove the ban for an IP address. + * @param theIP + */ + public void unBan(String theIP) { + _myBanList.remove(theIP); + } + + + private boolean checkBanList(ServerSocket theSocket) { + try { + String mySocketAddress = theSocket.getInetAddress() + .getHostAddress(); + String mySocketName = theSocket.getInetAddress().getHostName(); + for (int i = _myBanList.size() - 1; i >= 0; i--) { + if (mySocketAddress.equals(_myBanList.get(i)) + || mySocketName.equals(_myBanList.get(i))) { + return false; + } + } + return true; + } catch (Exception e) { + } + return false; + } + + /** + * get the server socket object. more at java.net.ServerSocket + * @return + */ + public ServerSocket socket() { + return _myServerSocket; + } + + /** + * @invisible + */ + public void run() { + threadLoop: while (Thread.currentThread() == _myThread) { + try { + /** + * @author when synchronized, disconnected clients are only + * removed from _myTcpClients when there is a new + * connection. + */ + // synchronized(_myTcpClients) { + if (checkBanList(_myServerSocket)) { + TcpClient t = new TcpClient(this, _myServerSocket.accept(), + _myTcpPacketListener, _myPort, _myMode); + if (NetP5.DEBUG) { + System.out.println("### new Client @ " + t); + } + _myTcpClients.addElement(t); + Logger.printProcess("TcpServer.run", _myTcpClients.size() + + " currently running."); + } + } + // } + catch (IOException e) { + Logger.printError("TcpServer", "IOException. Stopping server."); + break threadLoop; + } + } + dispose(); + } + + /** + * send a string to the connected client(s). + * @param theString + */ + public synchronized void send(final String theString) { + try { + Enumeration en = _myTcpClients.elements(); + while (en.hasMoreElements()) { + ((TcpClient) en.nextElement()).send(theString); + } + } catch (NullPointerException e) { + + } + } + + /** + * send a byte array to the connected client(s). + * @param theBytes + */ + public synchronized void send(final byte[] theBytes) { + try { + Enumeration en = _myTcpClients.elements(); + while (en.hasMoreElements()) { + ((TcpClient) en.nextElement()).send(theBytes); + } + } catch (NullPointerException e) { + + } + } + + /** + * kill the server. + */ + public void dispose() { + try { + _myThread = null; + + if (_myTcpClients != null) { + Enumeration en = _myTcpClients.elements(); + while (en.hasMoreElements()) { + remove((TcpClient) en.nextElement()); + } + _myTcpClients = null; + } + + if (_myServerSocket != null) { + _myServerSocket.close(); + _myServerSocket = null; + } + } catch (IOException e) { + Logger.printError("TcpServer.dispose", "IOException " + e); + } + } + + /** + * get the number of connected clients. + * @return + */ + public int size() { + return _myTcpClients.size(); + } + + /** + * get a list of all connected clients. an array of type TcpClient[] + * will be returned. + * @return + */ + public TcpClient[] getClients() { + TcpClient[] s = new TcpClient[_myTcpClients.size()]; + _myTcpClients.toArray(s); + return s; + } + + /** + * get a client at a specific position the client list. + * @param theIndex + * @return + */ + public TcpClient getClient(final int theIndex) { + return (TcpClient) _myTcpClients.elementAt(theIndex); + } + + /** + * @invisible + * @param thePacket + * TcpPacket + * @param thePort + * int + */ + public void process(final TcpPacket thePacket, final int thePort) { + handleInput(thePacket, thePort); + } + + /** + * @invisible + * @param thePacket + * TcpPacket + * @param thePort + * int + */ + public abstract void handleInput(final TcpPacket thePacket, + final int thePort); + + /** + * remove a TcpClient from the server's client list. + * @param theTcpClient + * TCPClientAbstract + */ + public void remove(AbstractTcpClient theTcpClient) { + if (_myTcpPacketListener != null && !_myTcpPacketListener.equals(this)) { + _myTcpPacketListener.remove(theTcpClient); + } + theTcpClient.dispose(); + _myTcpClients.removeElement(theTcpClient); + Logger.printProcess("TcpServer", "removing TcpClient."); + } + +} diff --git a/libraries/oscP5/src/netP5/AbstractUdpClient.java b/libraries/oscP5/src/netP5/AbstractUdpClient.java new file mode 100644 index 0000000..45ebd8d --- /dev/null +++ b/libraries/oscP5/src/netP5/AbstractUdpClient.java @@ -0,0 +1,199 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + + + + +/** + * @invisible + */ +public abstract class AbstractUdpClient { + + protected NetAddress _myNetAddress; + + protected DatagramSocket _mySocket; + + protected boolean isRunning = false; + + + /** + * @invisible + */ + public AbstractUdpClient() { + isRunning = openSocket(); + } + + + /** + * @invisible + * @param theAddr String + * @param thePort int + */ + public AbstractUdpClient(String theAddr, int thePort) { + + _myNetAddress = new NetAddress(theAddr, thePort); + + if(!_myNetAddress.isvalid()) { + Logger.printError("UdpClient", "unknown host " + theAddr); + } + isRunning = openSocket(); + } + + /** + * get the datagram socket of the UDP client. more info at java.net.DatagramSocket + * @return DatagramSocket + */ + public DatagramSocket socket() { + return _mySocket; + } + + + + private boolean openSocket() { + try { + _mySocket = new DatagramSocket(); + } + catch (SocketException e) { + Logger.printError("UdpClient.openSocket", "cant create socket " + + e.getMessage()); + return false; + } + + Logger.printProcess("UdpClient.openSocket", "udp socket initialized."); + return true; + } + + /** + * send a string using UDP to an already specified RemoteAddress. + * @param theString + */ + public void send(String theString) { + send(theString.getBytes()); + } + + + /** + * send a byte array using UDP to an already specified RemoteAddress. + * @param theBytes byte[] + */ + public void send(byte[] theBytes) { + if (_myNetAddress.isvalid()) { + send(theBytes, _myNetAddress); + } + else { + Logger.printWarning("UdpClient.send", + "no InetAddress and port has been set. Packet has not been sent."); + } + } + + /** + * send a byte array to the dedicated remoteAddress. + * @param theBytes + * @param theNetAddress + */ + public void send(final byte[] theBytes, + final NetAddress theNetAddress + ) { + if (_myNetAddress.isvalid()) { + send(theBytes, theNetAddress.inetaddress(),theNetAddress.port()); + } + } + + /** + * send a byte array to the dedicated remoteAddress. + * @param thePacket OscPacket + * @param theAddress String + * @param thePort int + */ + public void send(final byte[] theBytes, + final String theAddress, + final int thePort) { + try { + InetAddress myInetAddress = InetAddress.getByName(theAddress); + send(theBytes, myInetAddress, thePort); + } + catch (UnknownHostException e) { + Logger.printError("UdpClient.send", "while sending to " + + theAddress + " " + e); + } + } + + + + /** + * @invisible + * @param thePacket DatagramPacket + */ + public void send(DatagramPacket thePacket) { + if (isRunning) { + try { + _mySocket.send(thePacket); + + } + catch (IOException e) { + Logger.printError("UdpClient.send", + "ioexception while sending packet. "+e); + } + } + } + + + + /** + * send a byte array to the dedicated remoteAddress. + * @param theBytes byte[] + * @param theAddress InetAddress + * @param thePort int + */ + public void send(final byte[] theBytes, + final InetAddress theAddress, + final int thePort) { + if (isRunning) { + try { + DatagramPacket myPacket = new DatagramPacket(theBytes,theBytes.length, theAddress, thePort); + send(myPacket); + } + catch (NullPointerException npe) { + Logger.printError("UdpClient.send", + "a nullpointer exception occured." + npe); + } + } + else { + Logger.printWarning("UdpClient.send", + "DatagramSocket is not running. Packet has not been sent."); + } + } + +} diff --git a/libraries/oscP5/src/netP5/AbstractUdpServer.java b/libraries/oscP5/src/netP5/AbstractUdpServer.java new file mode 100644 index 0000000..9a35d63 --- /dev/null +++ b/libraries/oscP5/src/netP5/AbstractUdpServer.java @@ -0,0 +1,271 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.UnknownHostException; + + +public abstract class AbstractUdpServer implements Runnable { + + private DatagramSocket _myDatagramSocket = null; + + protected UdpPacketListener _myListener; + + private Thread _myThread = null; + + private int _myPort; + + private String _myAddress; + + private InetAddress _myInetAddress; + + protected int _myDatagramSize = 1536; // common MTU + + private boolean isRunning = true; + + private boolean isSocket = false; + + /** + * create a new UdpServer + * + * @invisible + * @param theListener + * UdpPacketListener + * @param thePort + * int + * @param theBufferSize + * int + */ + public AbstractUdpServer(UdpPacketListener theListener, int thePort, + int theBufferSize) { + _myDatagramSize = theBufferSize; + _myPort = thePort; + _myListener = theListener; + if (_myListener != null) { + start(); + } + } + + /** + * @invisible + * @param theListener + * UdpPacketListener + * @param theAddress + * String + * @param thePort + * int + * @param theBufferSize + * int + */ + protected AbstractUdpServer(UdpPacketListener theListener, + String theAddress, int thePort, int theBufferSize) { + _myDatagramSize = theBufferSize; + _myAddress = theAddress; + _myPort = thePort; + _myListener = theListener; + if (_myListener != null) { + start(); + } + } + + /** + * get the datagram socket of the UDP server. + * + * @return DatagramSocket + */ + public DatagramSocket socket() { + return _myDatagramSocket; + } + + /** + * @invisible + * + */ + public void start() { + _myThread = null; + _myDatagramSocket = null; + _myThread = new Thread(this); + try { + Thread.sleep(1000); + } catch (InterruptedException iex) { + Logger.printError("UdpServer.start()", + "oscServer sleep interruption " + iex); + } + try { + _myDatagramSocket = new DatagramSocket(_myPort); + _myInetAddress = InetAddress.getByName(_myAddress); + Logger.printProcess("UdpServer.start()", + "new Unicast DatagramSocket created @ port " + _myPort); + } catch (IOException ioex) { + Logger.printError("UdpServer.start()", + " IOException, couldnt create new DatagramSocket @ port " + + _myPort + " " + ioex); + } + + if (_myDatagramSocket != null) { + _myThread.start(); + isRunning = _myThread.isAlive(); + isSocket = true; + } else { + isRunning = false; + } + } + + /** + * @invisible + */ + public void run() { + if (_myDatagramSocket != null) { + if (isRunning) { + Logger.printProcess("UdpServer.run()", + "UdpServer is running @ " + _myPort); + } + } else { + Logger.printError("UdpServer.run()", + "Socket is null. closing UdpServer."); + return; + } + + while (isRunning) { + try { + byte[] myBuffer = new byte[_myDatagramSize]; + DatagramPacket myPacket = new DatagramPacket(myBuffer, + _myDatagramSize); + _myDatagramSocket.receive(myPacket); + _myListener.process(myPacket, _myPort); + } catch (IOException ioex) { + Logger.printProcess("UdpServer.run()", " socket closed."); + break; + } catch (ArrayIndexOutOfBoundsException ex) { + Logger.printError("UdpServer.run()", + "ArrayIndexOutOfBoundsException: " + ex); + } + } + dispose(); + } + + /** + * stop the UDP server, clean up and delete its reference. + */ + public void dispose() { + isRunning = false; + _myThread = null; + if (_myDatagramSocket != null) { + if (_myDatagramSocket.isConnected()) { + Logger.printDebug("UdpServer.dispose()", "disconnect()"); + _myDatagramSocket.disconnect(); + } + Logger.printDebug("UdpServer.dispose()", "close()"); + _myDatagramSocket.close(); + _myDatagramSocket = null; + Logger.printDebug("UdpServer.dispose()", + "Closing unicast datagram socket."); + } + } + + /** + * send a byte array to a previously defined remoteAddress. + * + * @param theBytes + * byte[] + */ + public void send(byte[] theBytes) { + if (isSocket) { + send(theBytes, _myInetAddress, _myPort); + } else { + Logger + .printWarning("UdpClient.send", + "no InetAddress and port has been set. Packet has not been sent."); + } + } + + /** + * send a byte array to a dedicated remoteAddress. + * + * @param thePacket + * OscPacket + * @param theAddress + * String + * @param thePort + * int + */ + public void send(byte[] theBytes, String theAddress, int thePort) { + try { + InetAddress myInetAddress = InetAddress.getByName(theAddress); + send(theBytes, myInetAddress, thePort); + } catch (UnknownHostException e) { + Logger.printError("UdpClient.send", "while sending to " + + theAddress + " " + e); + } + } + + /** + * @invisible + * @param thePacket + * DatagramPacket + */ + public void send(DatagramPacket thePacket) { + if (isSocket) { + try { + _myDatagramSocket.send(thePacket); + } catch (IOException e) { + Logger.printError("UdpClient.send", + "ioexception while sending packet."); + } + } + } + + /** + * send a byte array to a dedicated remoteAddress. + * + * @param theBytes + * byte[] + * @param theAddress + * InetAddress + * @param thePort + * int + */ + public void send(byte[] theBytes, InetAddress theAddress, int thePort) { + if (isSocket) { + try { + DatagramPacket myPacket = new DatagramPacket(theBytes, + theBytes.length, theAddress, thePort); + send(myPacket); + } catch (NullPointerException npe) { + Logger.printError("UdpServer.send", + "a nullpointer exception occured." + npe); + } + } else { + Logger.printWarning("UdpServer.send", + "DatagramSocket is not running. Packet has not been sent."); + } + } + +} diff --git a/libraries/oscP5/src/netP5/Bytes.java b/libraries/oscP5/src/netP5/Bytes.java new file mode 100644 index 0000000..7284b3b --- /dev/null +++ b/libraries/oscP5/src/netP5/Bytes.java @@ -0,0 +1,470 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + + +/** + * @invisible + */ +public class Bytes { + + public Bytes() { + } + + + + /** + * converts an object array into a String that is formated like a list + * + * @param theObject + * Object[] + * @return String + */ + public static String getAsString(Object[] theObject) { + StringBuffer s = new StringBuffer(); + for (int i = 0; i < theObject.length; i++) { + s.append("[" + i + "]" + " " + theObject[i] + "\n"); + } + return s.toString(); + } + + + + public static String getAsString(byte[] theBytes) { + StringBuffer s = new StringBuffer(); + for (int i = 0; i < theBytes.length; i++) { + s.append( (char) theBytes[i]); + } + return s.toString(); + } + + + + public static int toInt(byte abyte0[]) { + return (abyte0[3] & 0xff) + ( (abyte0[2] & 0xff) << 8) + + ( (abyte0[1] & 0xff) << 16) + ( (abyte0[0] & 0xff) << 24); + } + + + + public static long toLong(byte abyte0[]) { + return ( (long) abyte0[7] & 255L) + ( ( (long) abyte0[6] & 255L) << 8) + + ( ( (long) abyte0[5] & 255L) << 16) + + ( ( (long) abyte0[4] & 255L) << 24) + + ( ( (long) abyte0[3] & 255L) << 32) + + ( ( (long) abyte0[2] & 255L) << 40) + + ( ( (long) abyte0[1] & 255L) << 48) + + ( ( (long) abyte0[0] & 255L) << 56); + } + + + + public static float toFloat(byte abyte0[]) { + int i = toInt(abyte0); + return Float.intBitsToFloat(i); + } + + + + public static double toDouble(byte abyte0[]) { + long l = toLong(abyte0); + return Double.longBitsToDouble(l); + } + + + + public static byte[] toBytes(int i) { + return toBytes(i, new byte[4]); + } + + + + public static byte[] toBytes(int i, byte abyte0[]) { + abyte0[3] = (byte) i; + i >>>= 8; + abyte0[2] = (byte) i; + i >>>= 8; + abyte0[1] = (byte) i; + i >>>= 8; + abyte0[0] = (byte) i; + return abyte0; + } + + + + public static byte[] toBytes(long l) { + return toBytes(l, new byte[8]); + } + + + + public static byte[] toBytes(long l, byte abyte0[]) { + abyte0[7] = (byte) (int) l; + l >>>= 8; + abyte0[6] = (byte) (int) l; + l >>>= 8; + abyte0[5] = (byte) (int) l; + l >>>= 8; + abyte0[4] = (byte) (int) l; + l >>>= 8; + abyte0[3] = (byte) (int) l; + l >>>= 8; + abyte0[2] = (byte) (int) l; + l >>>= 8; + abyte0[1] = (byte) (int) l; + l >>>= 8; + abyte0[0] = (byte) (int) l; + return abyte0; + } + + + + public static boolean areEqual(byte abyte0[], byte abyte1[]) { + int i = abyte0.length; + if (i != abyte1.length) { + return false; + } + for (int j = 0; j < i; j++) { + if (abyte0[j] != abyte1[j]) { + return false; + } + } + + return true; + } + + + + public static byte[] append(byte abyte0[], byte abyte1[]) { + byte abyte2[] = new byte[abyte0.length + abyte1.length]; + System.arraycopy(abyte0, 0, abyte2, 0, abyte0.length); + System.arraycopy(abyte1, 0, abyte2, abyte0.length, abyte1.length); + return abyte2; + } + + + + public static byte[] append(byte abyte0[], byte abyte1[], byte abyte2[]) { + byte abyte3[] = new byte[abyte0.length + abyte1.length + abyte2.length]; + System.arraycopy(abyte0, 0, abyte3, 0, abyte0.length); + System.arraycopy(abyte1, 0, abyte3, abyte0.length, abyte1.length); + System.arraycopy(abyte2, 0, abyte3, abyte0.length + abyte1.length, + abyte2.length); + return abyte3; + } + + + + public static byte[] copy(byte abyte0[], int i) { + return copy(abyte0, i, abyte0.length - i); + } + + + + public static byte[] copy(byte abyte0[], int i, int j) { + byte abyte1[] = new byte[j]; + System.arraycopy(abyte0, i, abyte1, 0, j); + return abyte1; + } + + + + public static void merge(byte abyte0[], byte abyte1[], int i, int j, int k) { + System.arraycopy(abyte0, i, abyte1, j, k); + } + + + + public static void merge(byte abyte0[], byte abyte1[], int i) { + System.arraycopy(abyte0, 0, abyte1, i, abyte0.length); + } + + + + public static void merge(byte abyte0[], byte abyte1[]) { + System.arraycopy(abyte0, 0, abyte1, 0, abyte0.length); + } + + + + public static void merge(byte abyte0[], byte abyte1[], int i, int j) { + System.arraycopy(abyte0, 0, abyte1, i, j); + } + + + + public static String toString(byte abyte0[], int i, int j) { + char ac[] = new char[j * 2]; + int k = i; + int l = 0; + for (; k < i + j; k++) { + byte byte0 = abyte0[k]; + ac[l++] = hexDigits[byte0 >>> 4 & 0xf]; + ac[l++] = hexDigits[byte0 & 0xf]; + } + + return new String(ac); + } + + + + public static String toString(byte abyte0[]) { + return toString(abyte0, 0, abyte0.length); + } + + + + public static void printBytes(byte[] byteArray) { + for (int i = 0; i < byteArray.length; i++) { + System.out.print( (char) byteArray[i] + " (" + + hexDigits[byteArray[i] >>> 4 & 0xf] + "" + + hexDigits[byteArray[i] & 0xf] + ") "); + if ( (i + 1) % 4 == 0) { + System.out.print("\n"); + } + } + } + + + + private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + + /** + * ByteStream + */ + + private static byte[] toByteArray(int in_int) { + byte a[] = new byte[4]; + for (int i = 0; i < 4; i++) { + + int b_int = (in_int >> (i * 8)) & 255; + byte b = (byte) (b_int); + + a[i] = b; + } + return a; + } + + private static byte[] toByteArrayBigEndian(int theInt) { + byte a[] = new byte[4]; + for (int i = 0; i < 4; i++) { + int b_int = (theInt >> (i * 8)) & 255; + byte b = (byte) (b_int); + a[3-i] = b; + } + return a; + } + + + + + private static int asInt(byte[] byte_array_4) { + int ret = 0; + for (int i = 0; i < 4; i++) { + int b = (int) byte_array_4[i]; + if (i < 3 && b < 0) { + b = 256 + b; + } + ret += b << (i * 8); + } + return ret; + } + + + + public static int toIntLittleEndian(InputStream theInputStream) throws java.io.IOException { + byte[] byte_array_4 = new byte[4]; + + byte_array_4[0] = (byte) theInputStream.read(); + byte_array_4[1] = (byte) theInputStream.read(); + byte_array_4[2] = (byte) theInputStream.read(); + byte_array_4[3] = (byte) theInputStream.read(); + + return asInt(byte_array_4); + } + + + public static int toIntBigEndian(InputStream theInputStream) throws java.io.IOException { + byte[] byte_array_4 = new byte[4]; + /* used to reverse the int32 Big Endian of the tcp header to convert it to an int */ + byte_array_4[3] = (byte) theInputStream.read(); + byte_array_4[2] = (byte) theInputStream.read(); + byte_array_4[1] = (byte) theInputStream.read(); + byte_array_4[0] = (byte) theInputStream.read(); + return asInt(byte_array_4); + } + + + public static String toString(InputStream ins) throws java.io.IOException { + int len = toIntLittleEndian(ins); + return toString(ins, len); + } + + + + private static String toString(InputStream ins, int len) throws java.io.IOException { + String ret = new String(); + for (int i = 0; i < len; i++) { + ret += (char) ins.read(); + } + return ret; + } + + + + public static void toStream(OutputStream os, int i) throws Exception { + byte[] byte_array_4 = toByteArrayBigEndian(i); + os.write(byte_array_4); + } + + + + public static void toStream(OutputStream os, String s) throws Exception { + int len_s = s.length(); + toStream(os, len_s); + for (int i = 0; i < len_s; i++) { + os.write( (byte) s.charAt(i)); + } + os.flush(); + } + + + + public static void toStream(OutputStream os, byte[] theBytes) throws Exception { + int myLength = theBytes.length; + toStream(os, myLength); + os.write(theBytes); + os.flush(); + } + + + + public static byte[] toByteArray(InputStream ins) throws java.io.IOException { + int len = toIntLittleEndian(ins); + try { + return toByteArray(ins, len); + } + catch (Exception e) { + return new byte[0]; + } + } + + + + protected static byte[] toByteArray(InputStream ins, int an_int) throws + java.io.IOException, + Exception { + + byte[] ret = new byte[an_int]; + + int offset = 0; + int numRead = 0; + int outstanding = an_int; + + while ( + (offset < an_int) + && + ( (numRead = ins.read(ret, offset, outstanding)) > 0) + ) { + offset += numRead; + outstanding = an_int - offset; + } + if (offset < ret.length) { + throw new Exception("Could not completely read from stream, numRead=" + numRead + ", ret.length=" + ret.length); // ??? + } + return ret; + } + + + + private static void toFile(InputStream ins, FileOutputStream fos, int len, int buf_size) throws + java.io.FileNotFoundException, + java.io.IOException { + + byte[] buffer = new byte[buf_size]; + + int len_read = 0; + int total_len_read = 0; + + while (total_len_read + buf_size <= len) { + len_read = ins.read(buffer); + total_len_read += len_read; + fos.write(buffer, 0, len_read); + } + + if (total_len_read < len) { + toFile(ins, fos, len - total_len_read, buf_size / 2); + } + } + + + + private static void toFile(InputStream ins, File file, int len) throws + java.io.FileNotFoundException, + java.io.IOException { + + FileOutputStream fos = new FileOutputStream(file); + + toFile(ins, fos, len, 1024); + } + + + + public static void toFile(InputStream ins, File file) throws + java.io.FileNotFoundException, + java.io.IOException { + + int len = toIntLittleEndian(ins); + toFile(ins, file, len); + } + + + + public static void toStream(OutputStream os, File file) throws java.io.FileNotFoundException, + Exception { + + toStream(os, (int) file.length()); + + byte b[] = new byte[1024]; + InputStream is = new FileInputStream(file); + int numRead = 0; + + while ( (numRead = is.read(b)) > 0) { + os.write(b, 0, numRead); + } + os.flush(); + } + +} diff --git a/libraries/oscP5/src/netP5/Logger.java b/libraries/oscP5/src/netP5/Logger.java new file mode 100644 index 0000000..63f4f0e --- /dev/null +++ b/libraries/oscP5/src/netP5/Logger.java @@ -0,0 +1,153 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.util.Calendar; + +public class Logger { + + /** + * + */ + public static final int ON = 0; + + /** + * + */ + public static final int OFF = 1; + + /** + * + */ + public static final int ERROR = 0; + + /** + * + */ + public static final int WARNING = 1; + + /** + * + */ + public static final int PROCESS = 2; + + /** + * + */ + public static final int INFO = 3; + + /** + * + */ + public static final int DEBUG = 4; + + /** + * + */ + public static final int ALL = 5; + + + + public static int[] flags = new int[] { ON, ON, ON, ON, OFF }; + + public static void set(int theIndex, int theValue) { + if (theValue > -1 && theValue < 2) { + if (theIndex > -1 && theIndex < flags.length) { + flags[theIndex] = theValue; + return; + } else if (theIndex == ALL) { + for (int i = 0; i < flags.length; i++) { + flags[i] = theValue; + } + return; + } + } + } + + public static void printError(String theLocation, String theMsg) { + if (flags[ERROR] == ON) { + println("### " + getTime() + " ERROR @ " + theLocation + " " + + theMsg); + } + } + + public static void printProcess(String theLocation, String theMsg) { + if (flags[PROCESS] == ON) { + println("### " + getTime() + " PROCESS @ " + theLocation + " " + + theMsg); + } + } + + public static void printWarning(String theLocation, String theMsg) { + if (flags[WARNING] == ON) { + println("### " + getTime() + " WARNING @ " + theLocation + " " + + theMsg); + } + } + + public static void printInfo(String theLocation, String theMsg) { + if (flags[INFO] == ON) { + println("### " + getTime() + " INFO @ " + theLocation + " " + + theMsg); + } + } + + public static void printDebug(String theLocation, String theMsg) { + if (flags[DEBUG] == ON) { + println("### " + getTime() + " DEBUG @ " + theLocation + " " + + theMsg); + } + } + + public static void print(String theMsg) { + System.out.print(theMsg); + } + + public static void println(String theMsg) { + System.out.println(theMsg); + } + + public static void printBytes(byte[] byteArray) { + for (int i = 0; i < byteArray.length; i++) { + print(byteArray[i] + " (" + (char) byteArray[i] + ") "); + if ((i + 1) % 4 == 0) { + print("\n"); + } + } + print("\n"); + } + + public static String getTime() { + Calendar cal = Calendar.getInstance(); + return "[" + (cal.get(Calendar.YEAR)) + "/" + + (cal.get(Calendar.MONTH) + 1) + "/" + + cal.get(Calendar.DAY_OF_MONTH) + " " + + cal.get(Calendar.HOUR_OF_DAY) + ":" + + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND) + + "]"; + } + +} diff --git a/libraries/oscP5/src/netP5/Multicast.java b/libraries/oscP5/src/netP5/Multicast.java new file mode 100644 index 0000000..bc50d2d --- /dev/null +++ b/libraries/oscP5/src/netP5/Multicast.java @@ -0,0 +1,116 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.net.DatagramPacket; +import java.util.Vector; + + +/** + * Multicast is a method of forwarding IP datagrams to a group of interested receivers. + * UDP is used as the transport portocol. + */ +public class Multicast extends AbstractMulticast implements UdpPacketListener { + + + protected Object _myParent; + + protected NetPlug _myNetPlug; + + /** + * create a new instance of Multicast. the buffersize of the datagrams + * is set to 1536 by default. + * + * @param theObject Object + * @param theMulticastAddress String + * @param thePort int + * @param theBufferSize int + */ + public Multicast(final Object theObject, + final String theMulticastAddress, + final int thePort, + final int theBufferSize) { + super(null, theMulticastAddress, thePort, theBufferSize); + _myParent = theObject; + _myListener = this; + _myNetPlug = new NetPlug(_myParent); + init(theMulticastAddress,thePort); + } + + + public Multicast(final Object theObject, + final String theMulticastAddress, + final int thePort) { + super(null, theMulticastAddress, thePort, 1536); + _myParent = theObject; + _myListener = this; + _myNetPlug = new NetPlug(_myParent); + init(theMulticastAddress,thePort); + } + + + public Multicast(final UdpPacketListener theDatagramListener, + final String theMulticastAddress, + final int thePort, + final int theBufferSize) { + super(theDatagramListener, theMulticastAddress, thePort, theBufferSize); + } + + + public Multicast(final UdpPacketListener theDatagramListener, + final String theMulticastAddress, + final int thePort) { + super(theDatagramListener, theMulticastAddress, thePort); + } + + /** + * @invisible + * @param thePacket DatagramPacket + * @param thePort int + */ + public void process(DatagramPacket thePacket, int thePort) { + _myNetPlug.process(thePacket,thePort); + } + + + public void addListener(NetListener theListener) { + _myNetPlug.addListener(theListener); + } + + + public void removeListener(NetListener theListener) { + _myNetPlug.removeListener(theListener); + } + + public NetListener getListener(int theIndex) { + return _myNetPlug.getListener(theIndex); + } + + public Vector getListeners() { + return _myNetPlug.getListeners(); + } + +} diff --git a/libraries/oscP5/src/netP5/NetAddress.java b/libraries/oscP5/src/netP5/NetAddress.java new file mode 100644 index 0000000..09baa6c --- /dev/null +++ b/libraries/oscP5/src/netP5/NetAddress.java @@ -0,0 +1,130 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * NetAddress is an Object that contains an inetaddress + * of an remote internet address, consisting of an + * ip address and a port number. + * @author andreas schlegel + * + */ +public class NetAddress { + protected InetAddress inetaddress = null; + + protected String hostAddress; + + public String name = ""; + + protected int port = 0; + + protected boolean isValid = false; + + /** + * + * @param theAddress String + * @param thePort int + */ + public NetAddress(final String theAddress, + final int thePort) { + hostAddress = theAddress; + port = thePort; + if (thePort > 0) { + try { + inetaddress = InetAddress.getByName(theAddress); + isValid = true; + } + catch (UnknownHostException e) { + System.out.println("no such host " + inetaddress); + } + } + } + + public NetAddress(NetAddress theNetAddress) { + this(theNetAddress.address(),theNetAddress.port()); + } + + + /** + * + * @param theInetAddress InetAddress + * @param thePort int + */ + public NetAddress(InetAddress theInetAddress, int thePort) { + inetaddress = theInetAddress; + hostAddress = inetaddress.getHostAddress(); + port = thePort; + } + + + + /** + * + * @return InetAddress + */ + public InetAddress inetaddress() { + return inetaddress; + } + + + + /** + *returns the remote ip address as string + * @return String + */ + public String address() { + return hostAddress; + } + + + + /** + *returns the remote port number + * @return int + */ + public int port() { + return port; + } + + + + /** + *check if the netAddress is valid. this is true if + * the remote ip address was found. + * @return boolean + */ + public boolean isvalid() { + return isValid; + } + + public String toString() { + return hostAddress+":"+port; + } +} diff --git a/libraries/oscP5/src/netP5/NetAddressList.java b/libraries/oscP5/src/netP5/NetAddressList.java new file mode 100644 index 0000000..44ae782 --- /dev/null +++ b/libraries/oscP5/src/netP5/NetAddressList.java @@ -0,0 +1,169 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.util.ArrayList; + +/** + * NetAddressList is an arraylist of netaddresses. + * @author andreas schlegel + */ +public class NetAddressList { + protected ArrayList _myList = new ArrayList(); + + /** + * + * @param theNetAddress NetAddress + */ + public void add(NetAddress theNetAddress) { + if (theNetAddress.isValid == true) { + _myList.add(theNetAddress); + } + } + + + + /** + * + * @param theAddress String + * @param thePort int + */ + public void add(String theAddress, int thePort) { + NetAddress myOscHost = new NetAddress(theAddress, thePort); + if (myOscHost.isValid == true) { + _myList.add(myOscHost); + } + } + + + + /** + * + * @param theAddress String + * @param thePort int + */ + public void remove(String theAddress, int thePort) { + for (int i = 0; i < _myList.size(); i++) { + NetAddress myHost = ( (NetAddress) _myList.get(i)); + if (myHost.hostAddress.equals(theAddress) && myHost.port == thePort) { + _myList.remove(myHost); + } + } + } + + + + /** + * + * @param theNetAddress NetAddress + */ + public void remove(NetAddress theNetAddress) { + _myList.remove(theNetAddress); + } + + + public NetAddress get(String theIPaddress, int thePort) { + for (int i = 0; i < _myList.size(); i++) { + NetAddress myHost = ( (NetAddress) _myList.get(i)); + if (myHost.hostAddress.equals(theIPaddress) && myHost.port == thePort) { + return myHost; + } + } + return null; + + } + + + /** + * + * @param theNetAddress NetAddress + * @return boolean + */ + public boolean contains(NetAddress theNetAddress) { + if (_myList.contains(theNetAddress)) { + return true; + } + return false; + } + + /** + * + * @param theIPaddress String + * @param thePort int + * @return boolean + */ + public boolean contains(String theIPaddress, int thePort) { + for (int i = 0; i < _myList.size(); i++) { + NetAddress myHost = ( (NetAddress) _myList.get(i)); + if (myHost.hostAddress.equals(theIPaddress) && myHost.port == thePort) { + return true; + } + } + return false; + } + + + public int size() { + return _myList.size(); + } + + + + + /** + * + * @param theList NetAddress[] + */ + public void set(NetAddress[] theList) { + _myList = new ArrayList(); + for (int i = 0; i < theList.length; i++) { + _myList.add(theList[i]); + } + } + + + + /** + * + * @return ArrayList + */ + public ArrayList list() { + return _myList; + } + + + + /** + * + * @param theIndex int + * @return NetAddress + */ + public NetAddress get(int theIndex) { + return (NetAddress) _myList.get(theIndex); + } + +} diff --git a/libraries/oscP5/src/netP5/NetInfo.java b/libraries/oscP5/src/netP5/NetInfo.java new file mode 100644 index 0000000..069c2d9 --- /dev/null +++ b/libraries/oscP5/src/netP5/NetInfo.java @@ -0,0 +1,154 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.StringTokenizer; + + +/** + * some description + * @author andreas schlegel + */ +public class NetInfo { + + public NetInfo() { + } + + + + public static void print() { + try { + java.net.InetAddress i = java.net.InetAddress.getLocalHost(); + System.out.println("### hostname/ip " + i); // name and IP address + System.out.println("### hostname " + i.getHostName()); // name + System.out.println("### ip " + i.getHostAddress()); // IP address + // only + } + catch (Exception e) { + e.printStackTrace(); + } + } + + + + public static String getHostAddress() { + try { + java.net.InetAddress i = java.net.InetAddress.getLocalHost(); + return i.getHostAddress(); + } + catch (Exception e) { + } + return "ERROR"; + } + + + + public static String lan() { + Logger.printProcess("NetInfo.checkNetworkStatus : ", getHostAddress()); + return getHostAddress(); + } + + + + public static String wan() { + // create URL object. + String myIp = null; + URL u = null; + String URLstring = "http://checkip.dyndns.org"; + boolean isConnectedToInternet = false; + Logger.printProcess("NetInfo.checkNetworkStatus", + "Checking internet connection ..."); + try { + u = new URL(URLstring); + } + catch (MalformedURLException e) { + Logger.printError("NetInfo.checkNetworkStatus", "Bad URL " + + URLstring + " " + e); + } + + InputStream in = null; + try { + in = u.openStream(); + isConnectedToInternet = true; + } + catch (IOException e) { + Logger.printError("NetInfo.checkNetworkStatus", + "! Unable to open " + URLstring + "\n" + "Either the " + + URLstring + + " is unavailable or this machine is not" + + "connected to the internet !"); + } + + if (isConnectedToInternet) { + try { + BufferedReader br = new BufferedReader( + new InputStreamReader(in)); + String line; + String theToken = ""; + while ( (line = br.readLine()) != null) { + theToken += line; + } + br.close(); + + StringTokenizer st = new StringTokenizer(theToken, " <>", false); + + while (st.hasMoreTokens()) { + String myToken = st.nextToken(); + if (myToken.compareTo("Address:") == 0) { + myToken = st.nextToken(); + myIp = myToken; + Logger.printProcess("NetInfo.checkNetworkStatus", + "WAN address : " + myIp); + } + } + } + catch (IOException e) { + Logger.printError("NetInfo.checkNetworkStatus", + "I/O error reading " + URLstring + + " Exception = " + e); + } + } + return myIp; + } + + + + /** + * + * @param args String[] + * @invisible + */ + public static void main(String[] args) { + NetInfo.wan(); + } +} diff --git a/libraries/oscP5/src/netP5/NetListener.java b/libraries/oscP5/src/netP5/NetListener.java new file mode 100644 index 0000000..2f2fd2a --- /dev/null +++ b/libraries/oscP5/src/netP5/NetListener.java @@ -0,0 +1,34 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +public interface NetListener { + + public void netEvent(NetMessage theNetMessage); + + public void netStatus(NetStatus theStatus); + +} diff --git a/libraries/oscP5/src/netP5/NetMessage.java b/libraries/oscP5/src/netP5/NetMessage.java new file mode 100644 index 0000000..71e2822 --- /dev/null +++ b/libraries/oscP5/src/netP5/NetMessage.java @@ -0,0 +1,148 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.net.DatagramPacket; + +import java.net.InetAddress; + + +/** + * @author andreas schlegel + */ +public class NetMessage { + + private InetAddress _myInetAddress; + + private int _myPort; + + private String _myString = ""; + + private byte[] _myData = new byte[0]; + + private TcpClient _myTcpClient; + + private boolean isDatagramPacket = false; + + private int _myProtocol; + + private DatagramPacket _myDatagramPacket; + + private TcpPacket _myTcpPacket; + + protected NetMessage(DatagramPacket theDatagramPacket) { + _myDatagramPacket = theDatagramPacket; + _myInetAddress = theDatagramPacket.getAddress(); + _myPort = theDatagramPacket.getPort(); + _myData = theDatagramPacket.getData(); + _myProtocol = NetP5.UDP; + isDatagramPacket = true; + } + + + protected NetMessage(TcpPacket theTcpPacket) { + _myTcpPacket = theTcpPacket; + _myInetAddress = theTcpPacket.getTcpConnection().socket().getInetAddress(); + _myPort = theTcpPacket.getTcpConnection().socket().getPort(); + _myString = theTcpPacket.getTcpConnection().getString(); + _myData = theTcpPacket.getData(); + _myProtocol = NetP5.TCP; + _myTcpClient = theTcpPacket.getTcpConnection(); + } + + + public TcpPacket getTcpPacket() { + return _myTcpPacket; + } + + public DatagramPacket getDatagramPacket() { + return _myDatagramPacket; + } + + protected void setProtocol(int theType) { + _myProtocol = theType; + } + + + /** + * get the data of the message as bytes. + * @return + */ + public byte[] getData() { + return _myData; + } + + + /** + * get the data the message as string. + * @return + */ + public String getString() { + if(isDatagramPacket) { + return new String(_myData); + } else { + return _myString; + } + } + + /** + * get the protocol type the message was sent over. + * NetP5.TCP or NetP5.UDP are possible. + * @return + */ + public int protocol() { + return _myProtocol; + } + + + /** + * get the port the net message was received at. + * @return + */ + public int port() { + return _myPort; + } + + + + public TcpClient tcpConnection() { + return _myTcpClient; + } + + + + public String address() { + return _myInetAddress.getHostAddress(); + } + + + + public InetAddress inetAddress() { + return _myInetAddress; + } + +} diff --git a/libraries/oscP5/src/netP5/NetP5.java b/libraries/oscP5/src/netP5/NetP5.java new file mode 100644 index 0000000..7a5d69c --- /dev/null +++ b/libraries/oscP5/src/netP5/NetP5.java @@ -0,0 +1,55 @@ +/**
+ * A network library for processing which supports UDP, TCP and Multicast.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package netP5;
+
+public interface NetP5 {
+
+ String VERSION = "0.9.9";
+
+ boolean DEBUG = true;
+
+ /**
+ * @related setNetworkProtocol ( )
+ */
+ public final static int UDP = 0;
+
+ /**
+ * @related setNetworkProtocol ( )
+ */
+ public final static int MULTICAST = 1;
+
+
+ /**
+ * @related setNetworkProtocol ( )
+ */
+ public final static int TCP = 2;
+ /**
+ * TODO
+ * authentification in AbstractTcpServer and AbstractUdpServer.
+ * TcpServer.authentificationRequired(true/false);
+ * UdpServer.authentificationRequired(true/false);
+ */
+}
diff --git a/libraries/oscP5/src/netP5/NetPlug.java b/libraries/oscP5/src/netP5/NetPlug.java new file mode 100644 index 0000000..f651fc2 --- /dev/null +++ b/libraries/oscP5/src/netP5/NetPlug.java @@ -0,0 +1,222 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.net.DatagramPacket; +import java.util.Vector; + + + +class NetPlug { + + protected boolean isEventMethod = false; + + protected Method _myEventMethod; + + protected String _myEventMethodName = "netEvent"; + + protected boolean isStatusMethod = false; + + protected Method _myStatusMethod; + + protected String _myStatusMethodName = "netStatus"; + + protected Class _myParentClass; + + protected Object _myParent; + + protected Vector _myNetListeners; + + protected boolean isNetListener; + + protected NetPlug(Object theObject) { + _myParent = theObject; + _myNetListeners = new Vector(); + checkMethod(); + } + + protected void invoke(final Object theObject, final Method theMethod, + final Object[] theArgs) { + try { + theMethod.invoke(theObject, theArgs); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + System.out + .println("NetP5 ClassCastException. parsing failed for NetMessage " + + e); + } + } + + protected void checkMethod() { + try { + checkEventMethod(); + checkStatusMethod(); + } catch (Exception e) { + } + } + + private boolean checkEventMethod() { + _myParentClass = _myParent.getClass(); + if (_myEventMethodName != null) { + try { + _myEventMethod = _myParentClass.getDeclaredMethod( + _myEventMethodName, new Class[] { NetMessage.class }); + isEventMethod = true; + _myEventMethod.setAccessible(true); + return true; + } catch (SecurityException e1) { + e1.printStackTrace(); + } catch (NoSuchMethodException e1) { + System.out + .println("### NOTE. no netEvent(NetMessage theMessage) method available."); + } + } + if (_myEventMethod != null) { + return true; + } + return false; + } + + private boolean checkStatusMethod() { + _myParentClass = _myParent.getClass(); + if (_myStatusMethodName != null) { + try { + _myStatusMethod = _myParentClass.getDeclaredMethod( + _myStatusMethodName, new Class[] { NetStatus.class }); + isStatusMethod = true; + _myStatusMethod.setAccessible(true); + return true; + } catch (SecurityException e1) { + e1.printStackTrace(); + } catch (NoSuchMethodException e1) { + // System.out.println("### NOTE. no netStatus(NetStatus + // theMessage) method available."); + } + } + if (_myStatusMethod != null) { + return true; + } + return false; + } + + /** + * + * @param theDatagramPacket + * DatagramPacket + * @param thePort + * int + * @invisible + */ + public void process(final DatagramPacket theDatagramPacket, + final int thePort) { + if (isNetListener || isEventMethod) { + NetMessage n = new NetMessage(theDatagramPacket); + for (int i = 0; i < _myNetListeners.size(); i++) { + getListener(i).netEvent(n); + } + if (isEventMethod) { + try { + invoke(_myParent, _myEventMethod, new Object[] { n }); + } catch (ClassCastException e) { + System.out + .println("ChatP5.callMessage ClassCastException. failed to forward ChatMessage."); + } + } + } + } + + /** + * @invisible + * @param theIndex + */ + public void status(int theIndex) { + if (isNetListener || isEventMethod) { + NetStatus n = new NetStatus(theIndex); + for (int i = 0; i < _myNetListeners.size(); i++) { + getListener(i).netStatus(n); + } + if (isStatusMethod) { + try { + invoke(_myParent, _myStatusMethod, new Object[] { n }); + } catch (ClassCastException e) { + System.out + .println("ChatP5.callMessage ClassCastException. failed to forward ChatMessage."); + } + } + } + } + + /** + * + * @param theTcpPacket + * TcpPacket + * @param thePort + * int + * @invisible + */ + public void process(final TcpPacket theTcpPacket, final int thePort) { + + if (isNetListener || isEventMethod) { + NetMessage n = new NetMessage(theTcpPacket); + for (int i = 0; i < _myNetListeners.size(); i++) { + getListener(i).netEvent(n); + } + + if (isEventMethod) { + try { + invoke(_myParent, _myEventMethod, new Object[] { n }); + } catch (ClassCastException e) { + System.out + .println("NetP5.callMessage ClassCastException. failed to forward ChatMessage."); + } + } + } + } + + protected void addListener(NetListener theListener) { + _myNetListeners.add(theListener); + isNetListener = true; + } + + protected void removeListener(NetListener theListener) { + _myNetListeners.remove(theListener); + isNetListener = (_myNetListeners.size() > 0) ? true : false; + } + + protected NetListener getListener(int theIndex) { + return ((NetListener) _myNetListeners.get(theIndex)); + } + + protected Vector getListeners() { + return _myNetListeners; + } + +} diff --git a/libraries/oscP5/src/netP5/NetStatus.java b/libraries/oscP5/src/netP5/NetStatus.java new file mode 100644 index 0000000..a16e57d --- /dev/null +++ b/libraries/oscP5/src/netP5/NetStatus.java @@ -0,0 +1,65 @@ +/**
+ * A network library for processing which supports UDP, TCP and Multicast.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package netP5;
+
+/**
+ * @author andreas schlegel
+ */
+public class NetStatus {
+
+
+ public static int ERROR = -1;
+
+ public static int DEFAULT = 0;
+
+ public static int CONNECTION_CLOSED = 1;
+
+ public static int CONNECTION_REFUSED = 2;
+
+ public static int CONNECTION_TERMINATED = 4;
+
+ public static int CONNECTION_FAILED = 8;
+
+ public static int SERVER_CLOSED = 16;
+
+ public static int CLIENT_CLOSED = 32;
+
+ public static int SEND_FAILED = 64;
+
+ private int _myIndex = DEFAULT;
+
+
+ public NetStatus(int theIndex) {
+ _myIndex = theIndex;
+ }
+
+
+
+ public int id() {
+ return _myIndex;
+ }
+
+}
diff --git a/libraries/oscP5/src/netP5/StringUtils.java b/libraries/oscP5/src/netP5/StringUtils.java new file mode 100644 index 0000000..393bc90 --- /dev/null +++ b/libraries/oscP5/src/netP5/StringUtils.java @@ -0,0 +1,705 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +/** + * StringUtils Contains some basic utility methods for handling Strings. + * + * Copyright (C) 2003 Johan Känngård + * Contains code Copyright (C) 2001,2002 Stephen Ostermiller + * http://ostermiller.org/utils/StringHelper.java.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * The GPL is located at: http://www.gnu.org/licenses/gpl.txt + * + * @author Johan Känngård, http://dev.kanngard.net/ + * @version 0.4 + */ + +package netP5; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; + +/** + * @invisible + */ +public class StringUtils extends Object { + + /** + * Protected because this class does only contain static methods. + */ + protected StringUtils() { + } + + /** + * Returns the substring to the right of the specified substring in the + * specified String, starting from the left. + * + * @param source + * the source String to search. + * @param searchFor + * the substring to search for in source. + * @return the substring that is to the right of searchFor in source. + */ + public static String right(String source, String searchFor) { + int index = source.indexOf(searchFor) + searchFor.length(); + + if (index < 0) { + return ""; + } + return source.substring(index); + } + + /** + * Returns the substring to the right of the specified substring in the + * specified String, starting from the right. + * + * @param source + * the source String to search. + * @param searchFor + * the substring to search for in source. + * @return the substring that is to the right of searchFor in source, + * starting from the right. + */ + public static String rightBack(String source, String searchFor) { + int index = source.lastIndexOf(searchFor) + searchFor.length(); + + if (index < 0) { + return ""; + } + return source.substring(index); + } + + /** + * Returns the substring to the left of the specified substring in the + * specified String, starting from the left. + * + * @param source + * the source String to search. + * @param searchFor + * the substring to search for in source. + * @return the substring that is to the left of searchFor in source. + */ + public static String left(String source, String searchFor) { + int index = source.indexOf(searchFor); + + if (index <= 0) { + return ""; + } + return source.substring(0, index); + } + + /** + * Returns the substring to the left of the specified substring in the + * specified String, starting from the right. + * + * @param source + * the source String to search. + * @param searchFor + * the substring to search for in source. + * @return the substring that is to the left of searchFor in source, + * starting from the right. + */ + public static String leftBack(String source, String searchFor) { + int index = source.lastIndexOf(searchFor); + + if (index <= 0) { + return ""; + } + return source.substring(0, index); + } + + /** + * Returns the substring between two substrings. I.e. + * StringUtils.middle("This i a big challenge", "a", "challenge") returns " + * big ". + * + * @param source + * the String to search. + * @param start + * the String to the left to search for, from the left. + * @param end + * the String to the right to search for, from the right. + */ + public static String middle(String source, String start, String end) { + String one = StringUtils.right(source, start); + return StringUtils.leftBack(one, end); + } + + /** + * Returns a substring of a String, starting from specified index and with + * specified length. I. e. StringUtils.middle("This is a big challenge", 5, + * 6) returns " is a " + * + * @param source + * the String to get a substring from. + * @param startIndex + * the index in the source String to get the substring from. + * @param length + * the length of the substring to return. + */ + public static String middle(String source, int startIndex, int length) { + return source.substring(startIndex, source.length() - length); + } + + /** + * Replaces substrings in a string. + * + * @param source + * the source String to replace substrings in. + * @param searchFor + * the string to search for. + * @param replaceWith + * the string to replace all found searchFor-substrings with. + */ + public static String replace(String source, String searchFor, + String replaceWith) { + if (source.length() < 1) { + return ""; + } + int p = 0; + + while (p < source.length() && (p = source.indexOf(searchFor, p)) >= 0) { + source = source.substring(0, p) + replaceWith + + source.substring(p + searchFor.length(), source.length()); + p += replaceWith.length(); + } + return source; + } + + /** + * Replaces several substrings in a string. + * + * @param source + * the source String to replace substrings in. + * @param searchFor + * the substrings to search for. + * @param replaceWith + * what to replace every searchFor with, + */ + public static String replace(String source, String[] searchFor, + String replaceWith) { + for (int i = 0; i < searchFor.length; i++) { + StringUtils.replace(source, searchFor[i], replaceWith); + } + return source; + } + + /** + * Splits every String in an array at the specified lengths. + * + * Example: <code><pre> + * String source[] = { "123a123b123c123d", "Bla1bla2bla3bla4bla5bla6bla7" }; + * int[] lengths = { 3, 1, 3, 1 }; + * Vector result = StringUtils.explode(source, lengths); + * Object element = null; + * String[] rowElements = null; + * Enumeration enum = result.elements(); + * while (enum.hasMoreElements()) { + * element = enum.nextElement(); + * if (element instanceof String[]) { + * rowElements = (String[]) element; + * for (int i = 0; i < rowElements.length; i++) { + * System.out.println(rowElements[i]); + * } + * } + * } + * </pre></code> The result that will be output: 123 a 123 b + * + * Bla 1 bla 2 + * + * @return a Vector containing String arrays (the rows). + */ + public static Vector explode(String[] source, int[] lengths) { + Vector v = new Vector(); + for (int i = 0; i < source.length; i++) { + v.addElement(StringUtils.explode(source[i], lengths)); + } + return v; + } + + /** + * Splits a string at the specified lengths and returns an array of Strings. + * + * @param source + * the String to split. + * @lengths an array of lengths where to split the String. + * @return an array of Strings with the same number of elements as the + * number of elements in the lengths argument. The length of each + * String element is specified by the correspondent lengths array + * element. + * @throws IndexOutOfBoundsException + * if any of the length´s are invalid. + */ + public static String[] explode(String source, int[] lengths) { + String[] result = new String[lengths.length]; + int position = 0; + for (int i = 0; i < lengths.length; i++) { + if (lengths[i] + position > source.length()) { + throw new IndexOutOfBoundsException(); + } + result[i] = source.substring(position, position + lengths[i]); + position += lengths[i]; + } + return result; + } + + /** + * Splits a string into an array with a space as delimiter. + * + * @param source + * the source String to explode. + * @return an array of strings that are made out of splitting the string at + * the spaces. + */ + public static String[] explode(String source) { + return StringUtils.explode(source, " "); + } + + /** + * Splits a string into an array with the specified delimiter. Original code + * Copyright (C) 2001,2002 Stephen Ostermiller + * http://ostermiller.org/utils/StringHelper.java.html + * + * <p> + * This method is meant to be similar to the split function in other + * programming languages but it does not use regular expressions. Rather the + * String is split on a single String literal. It is equivalent to the + * + * @Explode function in Lotus Notes / Domino. + * </p> + * <p> + * Unlike java.util.StringTokenizer which accepts multiple + * character tokens as delimiters, the delimiter here is a single + * String literal. + * </p> + * <p> + * Each null token is returned as an empty String. Delimiters are + * never returned as tokens. + * </p> + * <p> + * If there is no delimiter because it is either empty or null, the + * only element in the result is the original String. + * </p> + * <p> + * StringHelper.explode("1-2-3", "-");<br> + * result: {"1", "2", "3"}<br> + * StringHelper.explode("-1--2-", "-");<br> + * result: {"", "1", ,"", "2", ""}<br> + * StringHelper.explode("123", "");<br> + * result: {"123"}<br> + * StringHelper.explode("1-2---3----4", "--");<br> + * result: {"1-2", "-3", "", "4"}<br> + * </p> + * @param s + * the String to explode. + * @param delimiter + * the delimiter where to split the string. + * @return an array of strings that are made out of splitting the string at + * the specified delimiter. + * @throws NullPointerException + * if s is null. + */ + public static String[] explode(String s, String delimiter) { + int delimiterLength; + int stringLength = s.length(); + + if (delimiter == null || (delimiterLength = delimiter.length()) == 0) { + return new String[] { s }; + } + // a two pass solution is used because a one pass solution would + // require the possible resizing and copying of memory structures + // In the worst case it would have to be resized n times with each + // resize having a O(n) copy leading to an O(n^2) algorithm. + int count = 0; + int start = 0; + int end; + + while ((end = s.indexOf(delimiter, start)) != -1) { + count++; + start = end + delimiterLength; + } + count++; + + String[] result = new String[count]; + // Scan s again, but this time pick out the tokens + count = 0; + start = 0; + while ((end = s.indexOf(delimiter, start)) != -1) { + result[count] = s.substring(start, end); + count++; + start = end + delimiterLength; + } + end = stringLength; + result[count] = s.substring(start, end); + return result; + } + + public static String[] slice(int theNum, String[] theStringArray) { + if (theNum < theStringArray.length) { + String[] t = new String[theStringArray.length - theNum]; + for (int i = theNum; i < theStringArray.length; i++) { + t[i - theNum] = theStringArray[i]; + } + return t; + } + return theStringArray; + } + + /** + * Combines an array to a string, using the specified delimiter. + * + * @param elements + * the array to combine to a single string. + * @param delimiter + * the delimiter to put between the combined elements. + * @return the array combined to a string. + */ + public static String implode(Object[] elements, String delimiter) { + StringBuffer buffer = new StringBuffer(""); + for (int i = 0; i < elements.length - 1; i++) { + buffer.append((String) elements[i] + delimiter); + } + buffer.append((String) elements[elements.length - 1]); + return buffer.toString(); + } + + /** + * Combines an array to a string, using a comma and a space as delimiter. + * + * @param elements + * the array to combine to a single string. + * @return the array combined to a string. + */ + public static String implode(Object[] elements) { + return implode(elements, ", "); + } + + /** + * Used by randomString(int) for valid characters. + */ + protected static String VALID_RANDOM_CHARACTERS = "abcdefghijkmnopqrstuvwxyz" + + "ABCDEFGHJKLMNPQRSTUVWXYZ-_.,;:<>()1234567890%&/=?+"; + + /** + * Removes all instances of a character in a String. + * + * @param source + * the String to remove substring in. + * @param searchFor + * the character to remove. + * @return the replaced String. + */ + public static String remove(String source, char searchFor) { + String s = String.valueOf(searchFor); + return StringUtils.remove(source, s); + } + + /** + * Removes all instances of a substring in a String. + * + * @param source + * the String to remove substring in. + * @param searchFor + * the substring to remove. + * @return the replaced String. + */ + public static String remove(String source, String searchFor) { + + return StringUtils.replace(source, searchFor, ""); + } + + /** + * Removes all instances of substrings in a String. + * + * @param source + * the String to remove substrings in. + * @param searchFor + * an array of substrings to remove from the source String. + * @return the replaced String. + */ + public static String remove(String source, String searchFor[]) { + return StringUtils.replace(source, searchFor, ""); + } + + /** + * Removes duplicates of a substring in a String. Case sensitive. + * + * @param source + * the String to remove duplicates in. + * @param searchFor + * the substring that can only occur one at a time, several can + * exist in the source though. + */ + public static String removeDuplicates(String source, String searchFor) { + StringBuffer result = new StringBuffer(""); + Enumeration myEnum = new StringTokenizer(source, searchFor, true); + String current = ""; + String previous = ""; + + while (myEnum.hasMoreElements()) { + current = (String) myEnum.nextElement(); + if (!current.equals(previous)) { + result.append(current); + } + previous = current; + } + return result.toString(); + } + + /** + * A utility method to remove duplicate characters from a string. For + * example, it would convert "hello" to "helo", and "abcd123abcaaa" to + * "abcd123". + * + * @param source + * the String to remove all duplicate characters in. + * @return a String with no duplicate characters. + */ + protected String unique(String source) { + String result = ""; + + for (int k = 0; k < source.length(); k++) { + if (result.indexOf(source.charAt(k)) == -1) { + result += source.charAt(k); + } + } + return result; + } + + /** + * Prints the stacktrace to a buffer and returns the buffer as a String. + * + * @param t + * the Throwable you wnat to generate a stacktrace for. + * @return the stacktrace of the supplied Throwable. + */ + public static String getStackTrace(Throwable t) throws IOException { + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + sw.close(); + return sw.toString(); + } + + /** + * Checks if a String is empty or null. + * + * @param s + * the String to test if it is empty or null. + * @return true if the String is null or empty (""). + */ + public static boolean isEmpty(String s) { + if (s == null) { + return true; + } + return s.equals(""); + } + + /** + * Creates a string of the given width with the given string left justified + * (followed by an appropriate number of spaces). + * + * @param source + * the String to justify + * @param length + * the length of the resulting String + * @return the source String padded with spaces to fill up the length. If + * the source string is longer than the length argument, the source + * String is returned. + */ + public static String leftJustify(String source, int length) { + if (source.length() >= length) { + return source; + } + return StringUtils.spaces(length - source.length()) + source; + } + + /** + * Creates a string of the given width with the given string right justified + * (with an appropriate number of spaces before it). + * + * @param source + * the String to justify + * @param length + * the length of the resulting String + * @return the source String padded with spaces to fill up the length. If + * the source string is longer than the length argument, the source + * String is returned. + */ + public static String rightJustify(String source, int length) { + if (source.length() >= length) { + return source; + } + + return source + StringUtils.spaces(length - source.length()); + } + + /** + * Creates a string of the given width with the given string left justified + * (padded by an appropriate number of spaces in front and after it). + * + * @param source + * the String to justify + * @param length + * the length of the resulting String + * @return the source String padded with spaces to fill up the length. If + * the source string is longer than the length argument, the source + * String is returned. + */ + public static String centerJustify(String source, int length) { + if (source.length() >= length) { + return source; + } + int leftLength = (length - source.length()) / 2; + int rightLength = length - (leftLength + source.length()); + return StringUtils.spaces(leftLength) + source + + StringUtils.spaces(rightLength); + } + + /** + * Returns a String with the specified number of spaces. + * + * @param length + * the number of spaces to return. + * @return a String consisting of the specified number of spaces. + */ + public static String spaces(int length) { + return duplicate(" ", length); + } + + /** + * Returns a String with the source String copied the specified number of + * times. + * + * @param source + * the source String to copy. + * @param length + * the number of copies of source to return. + * @return a String consisting of the specified source String copied the + * specified number of times. + */ + public static String duplicate(String source, int copies) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < copies; i++) { + buf.append(source); + } + return buf.toString(); + } + + /** + * Switches the case of the supplied String. Any lower case characters will + * be uppercase and vice versa. + * + * @param source + * the String to switch case of. + * @return the supplied String with switched case. + */ + public static String switchCase(String source) { + char[] sourceArray = source.toCharArray(); + StringBuffer result = new StringBuffer(); + + for (int i = 0; i < sourceArray.length; i++) { + result.append(StringUtils.switchCase(sourceArray[i])); + } + return result.toString(); + } + + /** + * Switches the case of the supplied character. A lower case character will + * be uppercase and vice versa. + * + * @param source + * the character to switch case of. + * @return the supplied character with switched case. + */ + public static char switchCase(char source) { + if (Character.isUpperCase(source)) { + return Character.toLowerCase(source); + } + if (Character.isLowerCase(source)) { + return Character.toUpperCase(source); + } + return source; + } + + public static int getInt(String theString) { + int i = 0; + try { + i = Integer.valueOf(theString).intValue(); + } catch (Exception iex) { + } + return i; + } + + public static float getFloat(String theString) { + float i = 0; + try { + i = Float.valueOf(theString).floatValue(); + } catch (Exception iex) { + } + return i; + } + + public static String arrayToString(String[] theArray) { + String myString = ""; + for (int i = 0; i < theArray.length; i++) { + myString += theArray[i] + ","; + } + myString = myString.substring(0, myString.length() - 1); + return myString; + } + + + + public static String arrayToString(String[] theArray, int theStart, int theEnd) { + String myString = ""; + if (theArray.length > theStart) { + for (int i = theStart; i < theEnd; i++) { + myString += theArray[i]+" "; + } + myString = myString.substring(0,myString.length()-1); + } + return myString; + } + + +} diff --git a/libraries/oscP5/src/netP5/TcpClient.java b/libraries/oscP5/src/netP5/TcpClient.java new file mode 100644 index 0000000..05515ad --- /dev/null +++ b/libraries/oscP5/src/netP5/TcpClient.java @@ -0,0 +1,214 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +import java.net.Socket; + + +/** + * @author andreas schlegel + */ +public class TcpClient + extends AbstractTcpClient { + + protected final static int NULL = -1; + + protected final static int LISTENER = 0; + + protected final static int EVENT = 1; + + private int _myMode = NULL; + + private Object _myParent; + + private NetPlug _myNetPlug; + + private String _myName = ""; + + /** + * + * @param theAddress String + * @param thePort int + */ + + public TcpClient(final Object theObject, + final String theAddress, + final int thePort) { + super(theAddress, thePort); + _myParent = theObject; + initEvent(); + } + + + /** + * + * @param theObject Object + * @param theAddress String + * @param thePort int + * @param theMode int + */ + public TcpClient(final Object theObject, + final String theAddress, + final int thePort, + final int theMode + ) { + super(theAddress, thePort, theMode); + _myParent = theObject; + initEvent(); + } + + + /** + * + * @param theListener TcpPacketListener + * @param theServerAddress String + * @param theServerPort int + * @param theMode int + */ + public TcpClient(TcpPacketListener theListener, + String theServerAddress, + int theServerPort, + int theMode) { + super(theListener, theServerAddress, theServerPort, theMode); + _myMode = LISTENER; + } + + + + /** + * + * @param theNetAddress NetAddress + */ + public TcpClient(final Object theObject, + final NetAddress theNetAddress) { + super(theNetAddress.address(), theNetAddress.port()); + _myParent = theObject; + initEvent(); + } + + + /** + * + * @param theNetAddress NetAddress + */ + public TcpClient(final NetAddress theNetAddress) { + super(theNetAddress.address(), theNetAddress.port()); + } + + + + /** + * + * @param theAddress String + * @param thePort int + */ + public TcpClient(final String theAddress, + final int thePort) { + super(theAddress, thePort); + } + + + + /** + * @invisible + */ + public TcpClient(AbstractTcpServer theTcpServer, + Socket theSocket, + TcpPacketListener theTcpPacketListener, + int theServerPort, + int theMode) { + super(theTcpServer, + theSocket, + theTcpPacketListener, + theServerPort, + theMode); + _myMode = LISTENER; + } + + + + private void initEvent() { + _myMode = EVENT; + _myNetPlug = new NetPlug(_myParent); + } + + + /** + * @invisible + * @param theIndex int + */ + public void handleStatus(int theIndex) { + switch (_myMode) { + case (EVENT): + _myNetPlug.status(theIndex); + break; + case (LISTENER): + _myTcpPacketListener.status(theIndex); + break; + case (NULL): + Logger.printDebug("TcpClient.handleStatus()","net status id " + theIndex); + break; + } + } + + + /** + * @invisible + */ + public void handleInput() { + switch (_myMode) { + case (EVENT): + _myNetPlug.process(new TcpPacket(this, _myStringBuffer, _myBytes),_myServerPort); + break; + case (LISTENER): + _myTcpPacketListener.process(new TcpPacket(this, _myStringBuffer, _myBytes),_myServerPort); + break; + case (NULL): + Logger.printDebug("TcpClient.handleInput()","received a message : " + _myStringBuffer.toString()); + break; + } + } + + + /** + * + * @return String + */ + public String name() { + return _myName; + } + + + /** + * + * @param theName String + */ + public void setName(String theName) { + _myName = theName; + } + +} diff --git a/libraries/oscP5/src/netP5/TcpPacket.java b/libraries/oscP5/src/netP5/TcpPacket.java new file mode 100644 index 0000000..c3aacb5 --- /dev/null +++ b/libraries/oscP5/src/netP5/TcpPacket.java @@ -0,0 +1,67 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +/** + * @invisible + */ +public class TcpPacket { + + private final TcpClient _myTcpClient; + + private final StringBuffer _myStringBuffer; + + private final byte[] _myData; + + public TcpPacket(final TcpClient theTcpClient, + final StringBuffer theBuffer, + final byte[] theBytes) { + _myStringBuffer = theBuffer; + _myTcpClient = theTcpClient; + _myData = theBytes; + } + + + public TcpClient getTcpConnection() { + return _myTcpClient; + } + + + public String getString() { + return _myStringBuffer.toString(); + } + + + public StringBuffer getStringBuffer() { + return _myStringBuffer; + } + + + public byte[] getData() { + return _myData; + } + +} diff --git a/libraries/oscP5/src/netP5/TcpPacketListener.java b/libraries/oscP5/src/netP5/TcpPacketListener.java new file mode 100644 index 0000000..5587b19 --- /dev/null +++ b/libraries/oscP5/src/netP5/TcpPacketListener.java @@ -0,0 +1,38 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +/** + * @invisible + */ +public interface TcpPacketListener { + + public void process(TcpPacket theTcpPacket, int thePort); + + public void status(int theStatus); + + public void remove(AbstractTcpClient theClient); +} diff --git a/libraries/oscP5/src/netP5/TcpServer.java b/libraries/oscP5/src/netP5/TcpServer.java new file mode 100644 index 0000000..af832a3 --- /dev/null +++ b/libraries/oscP5/src/netP5/TcpServer.java @@ -0,0 +1,177 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.util.Vector; + + + +/** + * @author andreas schlegel + */ +public class TcpServer + extends AbstractTcpServer { + + protected NetPlug _myNetPlug; + + protected Object _myParent; + + protected final static int NULL = -1; + + protected final static int LISTENER = 0; + + protected final static int EVENT = 1; + + protected int _myMode = NULL; + + /** + * @invisible + * @param thePort int + */ + public TcpServer(final int thePort) { + super(thePort, AbstractTcpServer.MODE_READLINE); + } + + + /** + * + * @param theObject Object + * @param thePort int + */ + public TcpServer(final Object theObject, + final int thePort) { + super(thePort, AbstractTcpServer.MODE_READLINE); + _myParent = theObject; + initEvent(); + } + + + /** + * + * @param theObject Object + * @param thePort int + * @param theMode int + */ + public TcpServer(final Object theObject, + final int thePort, + final int theMode) { + super(thePort, theMode); + _myParent = theObject; + initEvent(); + } + + + /** + * + * @param thePort int + * @param theMode int + */ + public TcpServer(final int thePort, + final int theMode) { + super(thePort, theMode); + } + + + /** + * @invisible + * @param theTcpPacketListener TcpPacketListener + * @param thePort int + * @param theMode int + */ + public TcpServer(final TcpPacketListener theTcpPacketListener, + final int thePort, + final int theMode) { + super(theTcpPacketListener, thePort, theMode); + _myMode = LISTENER; + } + + + + private void initEvent() { + _myMode = EVENT; + _myNetPlug = new NetPlug(_myParent); +// _myEventListener.checkMethod(); + + } + + + /** + * @invisible + * @param thePacket TcpPacket + * @param thePort int + */ + public void handleInput(final TcpPacket thePacket, + final int thePort) { + switch (_myMode) { + case (EVENT): + _myNetPlug.process(thePacket, thePort); + break; + case (LISTENER): + break; + case (NULL): + System.out.println("received a message : " + thePacket.getString()); + break; + } + } + + + /** + * @invisible + * @param theIndex int + */ + public void status(final int theIndex) { + switch (_myMode) { + case (EVENT): + _myNetPlug.status(theIndex); + break; + case (LISTENER): + case (NULL): + System.out.println("### status id : " + theIndex); + break; + } + } + + + + public void addListener(NetListener theListener) { + _myNetPlug.addListener(theListener); + } + + + public void removeListener(NetListener theListener) { + _myNetPlug.removeListener(theListener); + } + + public NetListener getListener(int theIndex) { + return _myNetPlug.getListener(theIndex); + } + + public Vector getListeners() { + return _myNetPlug.getListeners(); + } + + +} diff --git a/libraries/oscP5/src/netP5/UdpClient.java b/libraries/oscP5/src/netP5/UdpClient.java new file mode 100644 index 0000000..cb748ef --- /dev/null +++ b/libraries/oscP5/src/netP5/UdpClient.java @@ -0,0 +1,49 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + + +/** + * @author andreas schlegel + */ +public class UdpClient extends AbstractUdpClient { + + public UdpClient() { + super(); + } + + + public UdpClient(String theAddr, int thePort) { + super(theAddr, thePort); + } + + + public UdpClient(NetAddress theNetAddress) { + super(theNetAddress.address(), theNetAddress.port); + } + + +} diff --git a/libraries/oscP5/src/netP5/UdpPacketListener.java b/libraries/oscP5/src/netP5/UdpPacketListener.java new file mode 100644 index 0000000..9283f23 --- /dev/null +++ b/libraries/oscP5/src/netP5/UdpPacketListener.java @@ -0,0 +1,41 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.net.DatagramPacket; + +/** + * @invisible + * @author andreas schlegel + */ +public interface UdpPacketListener { + /** + * + * @param theDatagramPacket + * DatagramPacket + */ + public void process(DatagramPacket theDatagramPacket, int thePort); +} diff --git a/libraries/oscP5/src/netP5/UdpServer.java b/libraries/oscP5/src/netP5/UdpServer.java new file mode 100644 index 0000000..ce4fb0d --- /dev/null +++ b/libraries/oscP5/src/netP5/UdpServer.java @@ -0,0 +1,151 @@ +/** + * A network library for processing which supports UDP, TCP and Multicast. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package netP5; + +import java.net.DatagramPacket; +import java.util.Vector; + + +/** + * + * @author andreas schlegel + * + */ +public class UdpServer extends AbstractUdpServer implements UdpPacketListener { + + protected Object _myParent; + + protected NetPlug _myNetPlug; + + /** + * new UDP server. + * by default the buffersize of a udp packet is 1536 bytes. you can set + * your own individual buffersize with the third parameter int in the constructor. + * @param theObject Object + * @param thePort int + * @param theBufferSize int + */ + public UdpServer( + final Object theObject, + final int thePort, + final int theBufferSize) { + super(null, thePort, theBufferSize); + _myParent = theObject; + _myListener = this; + _myNetPlug = new NetPlug(_myParent); + start(); + } + + + + public UdpServer( + final Object theObject, + final int thePort) { + super(null, thePort, 1536); + _myParent = theObject; + _myListener = this; + _myNetPlug = new NetPlug(_myParent); + start(); + } + + + /** + * @invisible + * @param theListener + * @param thePort + * @param theBufferSize + */ + public UdpServer( + final UdpPacketListener theListener, + final int thePort, + final int theBufferSize) { + super(theListener, thePort, theBufferSize); + } + + + /** + * @invisible + * @param theListener + * @param theAddress + * @param thePort + * @param theBufferSize + */ + protected UdpServer( + final UdpPacketListener theListener, + final String theAddress, + final int thePort, + final int theBufferSize) { + super(theListener, theAddress, thePort, theBufferSize); + } + + + /** + * @invisible + * @param thePacket DatagramPacket + * @param thePort int + */ + public void process(DatagramPacket thePacket, int thePort) { + _myNetPlug.process(thePacket,thePort); + } + + + /** + * add a listener to the udp server. each incoming packet will be forwarded + * to the listener. + * @param theListener + * @related NetListener + */ + public void addListener(NetListener theListener) { + _myNetPlug.addListener(theListener); + } + + /** + * + * @param theListener + * @related NetListener + */ + public void removeListener(NetListener theListener) { + _myNetPlug.removeListener(theListener); + } + + /** + * + * @param theIndex + * @related NetListener + * @return + */ + public NetListener getListener(int theIndex) { + return _myNetPlug.getListener(theIndex); + } + + /** + * @related NetListener + * @return + */ + public Vector getListeners() { + return _myNetPlug.getListeners(); + } +} diff --git a/libraries/oscP5/src/oscP5/OscArgument.java b/libraries/oscP5/src/oscP5/OscArgument.java new file mode 100644 index 0000000..9b09248 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscArgument.java @@ -0,0 +1,228 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + + +package oscP5; + +/** + * an osc argument contains one value of values from a received osc message. + * you can convert the value into the required format, e.g. from Object to int + * theOscMessage.get(0).intValue(); + * @related OscMessage + * @example oscP5oscArgument + */ +public class OscArgument { + protected Object value; + + /** + * @invisible + */ + public OscArgument() {} + + /** + * get the int value of the osc argument. + * @return int + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public int intValue() { + return ((Integer) value).intValue(); + } + + /** + * get the char value of the osc argument. + * @return char + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public char charValue() { + return ((Character) value).charValue(); + } + + /** + * get the float value of the osc argument. + * @return float + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public float floatValue() { + return ((Float) value).floatValue(); + } + + /** + * get the double value of the osc argument. + * @return double + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public double doubleValue() { + return ((Double) value).doubleValue(); + } + + /** + * get the long value of the osc argument. + * @return long + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public long longValue() { + return ((Long) value).longValue(); + } + + /** + * get the boolean value of the osc argument. + * @return boolean + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public boolean booleanValue() { + return ((Boolean) value).booleanValue(); + } + + /** + * get the String value of the osc argument. + * @return String + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public String stringValue() { + return ((String) value); + } + + + /** + * + * @return String + */ + public String toString() { + return ((String) value); + } + + /** + * get the byte array of the osc argument. + * @return byte[] + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public byte[] bytesValue() { + return ((byte[]) value); + } + + /** + * get the byte array (blob) of the osc argument. + * @return byte[] + * @related intValue ( ) + * @related floatValue ( ) + * @related charValue ( ) + * @related stringValue ( ) + * @related doubleValue ( ) + * @related longValue ( ) + * @related booleanValue ( ) + * @related bytesValue ( ) + * @related blobValue ( ) + * @example oscP5parsing + */ + public byte[] blobValue() { + return ((byte[]) value); + } + + + /** + * + * @return int[] + */ + public int[] midiValue() { + int[] myInt = new int[4]; + byte[] myByte = (byte[]) value; + for (int i = 0; i < 4; i++) { + myInt[i] = (int) (myByte[i]); + } + return (myInt); + } +} diff --git a/libraries/oscP5/src/oscP5/OscBundle.java b/libraries/oscP5/src/oscP5/OscBundle.java new file mode 100644 index 0000000..d1d79f6 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscBundle.java @@ -0,0 +1,189 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + + +import java.net.DatagramPacket; +import java.util.ArrayList; +import netP5.Bytes; +import netP5.TcpPacket; + + +/** + * Osc Bundles are collections of Osc Messages. use bundles to send multiple + * osc messages to one destination. the OscBundle timetag is supported for + * sending but not for receiving yet. + * @related OscMessage + * @related OscP5 + * @example oscP5bundle + */ +public class OscBundle extends OscPacket { + + protected static final int BUNDLE_HEADER_SIZE = 16; + + protected static final byte[] BUNDLE_AS_BYTES = {0x23, 0x62, 0x75, 0x6E, + 0x64, 0x6C, 0x65, 0x00}; + + private int _myMessageSize = 0; + + /** + * instantiate a new OscBundle object. + */ + public OscBundle() { + messages = new ArrayList<OscMessage>(); + } + + + protected OscBundle(DatagramPacket theDatagramPacket) { + inetAddress = theDatagramPacket.getAddress(); + port = theDatagramPacket.getPort(); + hostAddress = inetAddress.toString(); + _myMessageSize = parseBundle(theDatagramPacket.getData(), inetAddress, port, null); + _myType = BUNDLE; + } + + + protected OscBundle(TcpPacket thePacket) { + _myTcpClient = thePacket.getTcpConnection(); + inetAddress = _myTcpClient.netAddress().inetaddress(); + port = _myTcpClient.netAddress().port(); + hostAddress = inetAddress.toString(); + _myMessageSize = parseBundle(thePacket.getData(), inetAddress, port, _myTcpClient); + _myType = BUNDLE; + } + + + /** + * add an osc message to the osc bundle. + * @param theOscMessage OscMessage + */ + public void add(OscMessage theOscMessage) { + messages.add(new OscMessage(theOscMessage)); + _myMessageSize = messages.size(); + } + + + /** + * clear and reset the osc bundle for reusing. + * @example oscP5bundle + */ + public void clear() { + messages = new ArrayList<OscMessage>(); + } + + + /** + * remove an OscMessage from an OscBundle. + * @param theIndex int + */ + public void remove(int theIndex) { + messages.remove(theIndex); + } + + + /** + * + * @param theOscMessage OscMessage + */ + public void remove(OscMessage theOscMessage) { + messages.remove(theOscMessage); + } + + + /** + * request an osc message inside the osc bundle array, + * @param theIndex int + * @return OscMessage + */ + public OscMessage getMessage(int theIndex) { + return messages.get(theIndex); + } + + + /** + * get the size of the osc bundle array which contains the osc messages. + * @return int + * @example oscP5bundle + */ + public int size() { + return _myMessageSize; + } + + + /** + * set the timetag of an osc bundle. timetags are used to synchronize events and + * execute events at a given time in the future or immediately. timetags can + * only be set for osc bundles, not for osc messages. oscP5 supports receiving + * timetags, but does not queue messages for execution at a set time. + * @param theTime long + * @example oscP5bundle + */ + public void setTimetag(long theTime) { + final long secsSince1900 = theTime / 1000 + TIMETAG_OFFSET; + final long secsFractional = ((theTime % 1000) << 32) / 1000; + timetag = (secsSince1900 << 32) | secsFractional; + } + + + /** + * returns the current time in milliseconds. use with setTimetag. + * @return long + */ + public static long now() { + return System.currentTimeMillis(); + } + + + /** + * returns a timetag as byte array. + * @return byte[] + */ + public byte[] timetag() { + return Bytes.toBytes(timetag); + } + + + /** + * @todo get timetag as Date + */ + + /** + * + * @return byte[] + * @invisible + */ + public byte[] getBytes() { + byte[] myBytes = new byte[0]; + myBytes = Bytes.append(myBytes, BUNDLE_AS_BYTES); + myBytes = Bytes.append(myBytes, timetag()); + for (int i = 0; i < size(); i++) { + byte[] tBytes = getMessage(i).getBytes(); + myBytes = Bytes.append(myBytes, Bytes.toBytes(tBytes.length)); + myBytes = Bytes.append(myBytes, tBytes); + } + return myBytes; + } +} diff --git a/libraries/oscP5/src/oscP5/OscEventListener.java b/libraries/oscP5/src/oscP5/OscEventListener.java new file mode 100644 index 0000000..18c9e2c --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscEventListener.java @@ -0,0 +1,37 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +/** + * + * @invisible + */ +public interface OscEventListener { + + public void oscEvent(OscMessage theMessage); + + public void oscStatus(OscStatus theStatus); +} diff --git a/libraries/oscP5/src/oscP5/OscIn.java b/libraries/oscP5/src/oscP5/OscIn.java new file mode 100644 index 0000000..509b8e2 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscIn.java @@ -0,0 +1,89 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +import java.util.ArrayList; + +/** + * OscIn is deprecated. for compatibility with previous versions of oscP5 OscIn + * is still available. + * + * @invisible + */ +@Deprecated +public class OscIn extends OscMessage { + + public OscIn(OscMessage theOscMessage) { + super(theOscMessage); + } + + public int getInt(int thePos) { + return get(thePos).intValue(); + } + + public char getChar(int thePos) { + return get(thePos).charValue(); + } + + public float getFloat(int thePos) { + return get(thePos).floatValue(); + } + + public String getString(int thePos) { + return get(thePos).stringValue(); + } + + public byte[] getBlob(int thePos) { + return get(thePos).bytesValue(); + } + + public int[] getMidiBytes(int thePos) { + return get(thePos).midiValue(); + } + + public int[] getMidi(int thePos) { + return get(thePos).midiValue(); + } + + public boolean getBoolean(int thePos) { + return get(thePos).booleanValue(); + } + + /** + * this is only for christian's and jens' table communication with vvvv. + * + * @return ArrayList + */ + public ArrayList getDataList() { + ArrayList myList = new ArrayList(); + Object[] myArguments = arguments(); + for (int i = 0; i < myArguments.length; i++) { + myList.add(myArguments[i]); + } + return myList; + } + +} diff --git a/libraries/oscP5/src/oscP5/OscMessage.java b/libraries/oscP5/src/oscP5/OscMessage.java new file mode 100644 index 0000000..153cfba --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscMessage.java @@ -0,0 +1,764 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + + +import java.net.DatagramPacket; + +import java.net.InetAddress; +import netP5.Bytes; +import netP5.Logger; +import netP5.TcpClient; +import netP5.TcpPacket; + + +/** + * An OSC message consists of an OSC Address Pattern, an OSC Type Tag String + * and the OSC arguments. + * + * @related OscBundle + * @example oscP5sendReceive + */ +public class OscMessage extends OscPacket { + + protected final OscArgument _myOscArgument = new OscArgument(); + + protected boolean isPlugged = false; + + protected OscMessage(final DatagramPacket theDatagramPacket) { + inetAddress = theDatagramPacket.getAddress(); + port = theDatagramPacket.getPort(); + hostAddress = inetAddress.toString(); + parseMessage(theDatagramPacket.getData()); + _myType = MESSAGE; + } + + + protected OscMessage(final TcpPacket thePacket) { + _myTcpClient = thePacket.getTcpConnection(); + inetAddress = _myTcpClient.netAddress().inetaddress(); + port = _myTcpClient.netAddress().port(); + hostAddress = inetAddress.toString(); + parseMessage(thePacket.getData()); + _myType = MESSAGE; + } + + + /** + * + * @param theOscMessage OscMessage + * @invisible + */ + + public OscMessage(final OscMessage theOscMessage) { + inetAddress = theOscMessage.inetAddress; + port = theOscMessage.port; + hostAddress = theOscMessage.hostAddress; + _myTcpClient = theOscMessage.tcpConnection(); + _myAddrPattern = theOscMessage._myAddrPattern; + _myTypetag = theOscMessage._myTypetag; + _myData = theOscMessage._myData; + _myArguments = theOscMessage._myArguments; + isValid = true; + } + + + /** + * + * @param theAddrPattern + * String + */ + public OscMessage(final String theAddrPattern) { + this(theAddrPattern, new Object[0]); + } + + + /** + * + * @param theAddrInt + * int + */ + public OscMessage(final int theAddrInt) { + this(theAddrInt, new Object[0]); + } + + + /** + * + * @param theAddrPattern String + * @param theArguments + * Object[] + */ + public OscMessage(final String theAddrPattern, + final Object[] theArguments) { + init(); + setAddrPattern(theAddrPattern); + setArguments(theArguments); + } + + + /** + * + * @param theAddrPattern int + * @param theArguments Object[] + */ + public OscMessage(final int theAddrPattern, + final Object[] theArguments) { + init(); + setAddrPattern(theAddrPattern); + setArguments(theArguments); + } + + + protected OscMessage(final byte[] theBytes, + final InetAddress theInetAddress, + final int thePort, + final TcpClient theClient + ) { + _myTcpClient = theClient; + inetAddress = theInetAddress; + port = thePort; + hostAddress = inetAddress.toString(); + parseMessage(theBytes); + } + + protected OscMessage(final byte[] theBytes, + final InetAddress theInetAddress, + final int thePort, + final long theTimetag, + final TcpClient theClient + ) { + this(theBytes,theInetAddress,thePort,theClient); + timetag = theTimetag; + } + + + + protected void init() { + _myTypetag = new byte[0]; + _myData = new byte[0]; + } + + + /** + * clear and reset an OscMessage for reuse. + */ + public void clear() { + init(); + setAddrPattern(""); + setArguments(new Object[0]); + } + + /** + * clears the arguments in a message, + * but keeps the address the address pattern. + * + */ + public void clearArguments() { + _myTypetag = new byte[0]; + _myData = new byte[0]; + _myArguments = new Object[0]; + } + + + /** + * TODO + * set should enable the programmer to set values + * of an existing osc message. + */ + public void set(final int theIndex, final Object theObject) { +// byte[] myPreTypetag = new byte[theIndex]; +// byte[] myPostTypetag = new byte[_myTypetag.length - theIndex]; + System.out.println("Typetag:\t" + _myTypetag.length); + System.out.println("Arguments:\t"); + Bytes.printBytes(_myData); + System.out.println(_myArguments.length); + for(int i=0;i<_myArguments.length;i++) { + System.out.println(_myArguments[i]); + } + } + + + /** + * + * @param theTypeTag + * String + * @return boolean + * @example oscP5parsing + */ + public boolean checkTypetag(final String theTypeTag) { + return theTypeTag.equals(typetag()); + } + + + /** + * check if an address pattern equals a specific address pattern + * you are looking for. this is usually used when parsing an osc message. + * e.g. if(theOscMessage.checkAddrPattern("/test")==true) {...} + * @param theAddrPattern + * String + * @return boolean + * @example oscP5parsing + */ + public boolean checkAddrPattern(final String theAddrPattern) { + return theAddrPattern.equals(addrPattern()); + } + + + /** + * set the address pattern of an osc message. you can set + * a string or an int as address pattern.tnt might be useful for + * supercollider users. oscP5 does support ints and strings as + * address patterns when sending and receiving messages. + * @param theAddrPattern + * String + */ + public void setAddrPattern(final String theAddrPattern) { + _myAddrPattern = theAddrPattern.getBytes(); + } + + + /** + * + * @param theAddrPattern + * int + */ + public void setAddrPattern(final int theAddrPattern) { + _myAddrPattern = Bytes.toBytes(theAddrPattern); + } + + + /** + * set the arguments of the osc message using an object array. + * with version 0.9.4 the existing arguments are overwritten, + * to add the arguments to the argument list, use addArguments(Object[]) + * @param theArguments + * Object[] + */ + public void setArguments(final Object[] theArguments) { + clearArguments(); + addArguments(theArguments); + } + + /** + * add a list of arguments to an exisiting set of arguments. + * to overwrite the existing argument list, use setArguments(Object[]) + * + * @param theArguments + */ + public OscMessage addArguments(final Object[] theArguments) { + return add(theArguments); + } + + + public String addrPattern() { + return Bytes.getAsString(_myAddrPattern); + } + + + /** + * returns the address pattern of the osc message as int. + * @return int + */ + public int addrInt() { + return _myAddrInt; + } + + + /** + * returns the typetag of the osc message. e.g. the message contains + * 3 floats then the typetag would be "fff" + * @return String + */ + public String typetag() { + return Bytes.getAsString(_myTypetag); + } + + /** + * get the timetag of an osc message. timetags are only sent by + * osc bundles. + * @return long + */ + public long timetag() { + return timetag; + } + + /** + * + * @return Object[] + */ + public Object[] arguments() { + return _myArguments; + } + + + /** + * supported arrays see OscPlug.getArgs + * @return Object[] + */ + protected Object[] argsAsArray() { + switch (_myTypetag[0]) { + case (0X66): // float f + final float[] myFloatArray = new float[_myArguments.length]; + for (int i = 0; i < myFloatArray.length; i++) { + myFloatArray[i] = ((Float) _myArguments[i]).floatValue(); + } + return new Object[] {myFloatArray}; + case (0x69): // int i + final int[] myIntArray = new int[_myArguments.length]; + for (int i = 0; i < myIntArray.length; i++) { + myIntArray[i] = ((Integer) _myArguments[i]).intValue(); + } + return new Object[] {myIntArray}; + case (0x53): // Symbol S + case (0x73): // String s + final String[] myStringArray = new String[_myArguments.length]; + for (int i = 0; i < myStringArray.length; i++) { + myStringArray[i] = ((String) _myArguments[i]); + } + return new Object[] {myStringArray}; + default: + break; + } + return new Object[] {}; + } + + /** + * + * @return byte[] + * @invisible + */ + public byte[] getAddrPatternAsBytes() { + return Bytes.append(_myAddrPattern, + new byte[align(_myAddrPattern.length)]); + } + + + /** + * + * @return byte[] + * @invisible + */ + public byte[] getTypetagAsBytes() { + return _myTypetag; + } + + + /** + * + * @return byte[] + * @invisible + */ + public byte[] getBytes() { + byte[] myBytes = new byte[0]; + byte[] myTypeTag = Bytes.copy(_myTypetag, 0); + myBytes = Bytes.append(myBytes, _myAddrPattern, + new byte[align(_myAddrPattern.length)]); + if (myTypeTag.length == 0) { + myTypeTag = new byte[] {KOMMA}; + } else if (myTypeTag[0] != KOMMA) { + myTypeTag = Bytes.append(new byte[] {KOMMA}, myTypeTag); + } + myBytes = Bytes.append(myBytes, myTypeTag, + new byte[align(myTypeTag.length)]); + myBytes = Bytes.append(myBytes, _myData, + new byte[align(_myData.length) % 4]); + return myBytes; + } + + + protected Object[] increase(int theAmount) { + if(_myArguments.length<1 || _myArguments == null) { + return new Object[1]; + } + Object[] myArguments = new Object[_myArguments.length + theAmount]; + System.arraycopy(_myArguments, 0, myArguments, 0, _myArguments.length); + return myArguments; + } + /** + * add values to an osc message. please check the + * add documentation for specific information. + * @example oscP5message + */ + public OscMessage add() { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x4e}); + return this; + } + + + /** + * @param theValue int + */ + public OscMessage add(final int theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x69}); + _myData = Bytes.append(_myData, Bytes.toBytes(theValue)); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = new Integer(theValue); + return this; + } + + + /** + * + * @param theValue String + */ + public OscMessage add(final String theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x73}); + final byte[] myString = theValue.getBytes(); + _myData = Bytes.append(_myData, myString, + new byte[align(myString.length)]); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = theValue; + return this; + } + + + /** + * + * @param theValue float + */ + public OscMessage add(final float theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x66}); + _myData = Bytes.append(_myData, Bytes.toBytes(Float + .floatToIntBits(theValue))); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = new Float(theValue); + return this; + } + + + /** + * + * @param theValue double + */ + public OscMessage add(final double theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x64}); + _myData = Bytes.append(_myData, Bytes.toBytes(Double + .doubleToLongBits(theValue))); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = new Double(theValue); + return this; + } + + + /** + * + * @param theValue boolean + */ + public OscMessage add(final boolean theValue) { + if (theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x54}); + } else { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x46}); + } + return this; + } + + + /** + * + * @param theValue Boolean + */ + public OscMessage add(final Boolean theValue) { + add((theValue).booleanValue()); + return this; + } + + + /** + * + * @param theValue Integer + */ + public OscMessage add(final Integer theValue) { + add(theValue.intValue()); + return this; + } + + + /** + * + * @param theValue + * Float + */ + public OscMessage add(final Float theValue) { + add(theValue.floatValue()); + return this; + } + + + /** + * + * @param theValue + * Double + */ + public OscMessage add(final Double theValue) { + add(theValue.doubleValue()); + return this; + } + + + /** + * + * @param theValue + * Character + */ + public OscMessage add(final Character theValue) { + add(theValue.charValue()); + return this; + } + + + /** + * + * @param theValue + * char + */ + public OscMessage add(final char theValue) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x63}); + _myData = Bytes.append(_myData, Bytes.toBytes(theValue)); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = new Character(theValue); + return this; + } + + + /** + * + * @param channel int + * @param status int + * @param value1 int + * @param value2 int + */ + + public OscMessage add(final int channel, + final int status, + final int value1, + final int value2) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x6d}); // m + final byte[] theBytes = new byte[4]; + theBytes[0] = (byte) channel; + theBytes[1] = (byte) status; + theBytes[2] = (byte) value1; + theBytes[3] = (byte) value2; + _myData = Bytes.append(_myData, theBytes); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = theBytes; + return this; + } + + + /** + * + * @param theArray + * int[] + */ + public OscMessage add(final int[] theArray) { + for (int i = 0; i < theArray.length; i++) { + add(theArray[i]); + } + return this; + } + + + /** + * + * @param theArray + * char[] + */ + public OscMessage add(final char[] theArray) { + for (int i = 0; i < theArray.length; i++) { + add(theArray[i]); + } + return this; + } + + + /** + * + * @param theArray + * float[] + */ + public OscMessage add(final float[] theArray) { + for (int i = 0; i < theArray.length; i++) { + add(theArray[i]); + } + return this; + } + + + /** + * + * @param theArray + * String[] + */ + public OscMessage add(final String[] theArray) { + for (int i = 0; i < theArray.length; i++) { + add(theArray[i]); + } + return this; + } + + + /** + * + * @param theArray + * byte[] + */ + public OscMessage add(final byte[] theArray) { + _myTypetag = Bytes.append(_myTypetag, new byte[] {0x62}); + _myData = Bytes.append(_myData, makeBlob(theArray)); + _myArguments = increase(1); + _myArguments[_myArguments.length-1] = theArray; + return this; + } + + + /** + * + * @param theArray + * Object[] + */ + public OscMessage add(final Object[] theArray) { + for (int i = 0; i < theArray.length; i++) { + if (!add(theArray[i])) { + System.out.println("type of Argument not defined in osc specs."); + } + } + return this; + } + + + private boolean add(final Object theObject) { + if (theObject instanceof Number) { + if (theObject instanceof Integer) { + add((Integer) theObject); + } else if (theObject instanceof Float) { + add((Float) theObject); + } else if (theObject instanceof Double) { + add((Double) theObject); + } else if (theObject instanceof Long) { + add((Long) theObject); + } + } else if (theObject instanceof String) { + add((String) theObject); + } else if (theObject instanceof Boolean) { + add((Boolean) theObject); + } else if (theObject instanceof Character) { + add((Character) theObject); + } + + else { + if (theObject instanceof int[]) { + add((int[]) theObject); + return true; + } else if (theObject instanceof float[]) { + add((float[]) theObject); + return true; + } else if (theObject instanceof byte[]) { + add((byte[]) theObject); + return true; + } + + else if (theObject instanceof String[]) { + add((String[]) theObject); + return true; + } else if (theObject instanceof char[]) { + add((char[]) theObject); + return true; + } else if (theObject instanceof double[]) { + add((float[]) theObject); + return true; + } + return false; + } + return true; + } + + + /** + * + * @param b byte[] + * @return byte[] + * @invisible + */ + public static byte[] makeBlob(final byte[] b) { + final int tLength = b.length; + byte[] b1 = Bytes.toBytes(tLength); + b1 = Bytes.append(b1, b); + final int t = tLength % 4; + if (t != 0) { + b1 = Bytes.append(b1, new byte[4 - t]); + } + return b1; + } + + + /** + * get a value at a specific position in the osc message. the get method + * returns an OscArgument from which the value can be parsed into the right + * format. e.g. to parse an int from the first argument in the osc message, + * use theOscMessage.get(0).intValue(); + * @param theIndex int + * @return OscArgument + */ + public OscArgument get(final int theIndex) { + if (theIndex < arguments().length) { + _myOscArgument.value = arguments()[theIndex]; + return _myOscArgument; + } + return null; + } + + + /** + * + * @return String + * @invisible + */ + public final String toString() { + return hostAddress + ":" + port + " | " + + addrPattern() + " " + typetag(); + } + + + public boolean isPlugged() { + return isPlugged; + } + + + public void print() { + Logger.println("-OscMessage----------"); + Logger.println("received from\t" + hostAddress + ":" + port); + Logger.println("addrpattern\t" + Bytes.getAsString(_myAddrPattern)); + Logger.println("typetag\t" + Bytes.getAsString(_myTypetag)); + Logger.println(Bytes.getAsString(_myArguments)); + Logger.println("---------------------"); + } + + public void printData() { + Bytes.printBytes(_myData); + } +} diff --git a/libraries/oscP5/src/oscP5/OscNetManager.java b/libraries/oscP5/src/oscP5/OscNetManager.java new file mode 100644 index 0000000..dd4f614 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscNetManager.java @@ -0,0 +1,386 @@ +/**
+ * An OSC (Open Sound Control) library for processing.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package oscP5;
+
+import java.net.DatagramPacket;
+import java.util.ArrayList;
+
+import netP5.AbstractMulticast;
+import netP5.AbstractTcpClient;
+import netP5.Logger;
+import netP5.Multicast;
+import netP5.NetAddress;
+import netP5.NetAddressList;
+import netP5.TcpClient;
+import netP5.TcpPacket;
+import netP5.TcpPacketListener;
+import netP5.TcpServer;
+import netP5.UdpClient;
+import netP5.UdpPacketListener;
+import netP5.UdpServer;
+
+
+/**
+ * @invisible
+ */
+
+public class OscNetManager
+ implements UdpPacketListener, TcpPacketListener {
+
+ protected OscProperties _myOscProperties;
+
+ protected UdpClient _myUdpClient = null;
+
+ protected UdpServer _myUdpServer = null;
+
+ protected TcpServer _myTcpServer = null;
+
+ protected TcpClient _myTcpClient = null;
+
+ protected boolean isTcpClient = false;
+
+ protected boolean isTcpServer = false;
+
+ protected AbstractMulticast _myMulticast = null;
+
+ protected ArrayList<UdpPacketListener> _myUdpListener = new ArrayList<UdpPacketListener>();
+
+ protected ArrayList<TcpPacketListener> _myTcpListener = new ArrayList<TcpPacketListener>();
+
+ public final static int NONE = 0;
+
+ public void start(final OscProperties theOscProperties) {
+ stop();
+ _myOscProperties = theOscProperties;
+ int networkProtocol = _myOscProperties.networkProtocol();
+ switch (networkProtocol) {
+ case (OscProperties.UDP):
+ newUdp();
+ break;
+ case (OscProperties.MULTICAST):
+ newMulticast();
+ break;
+ case (OscProperties.TCP):
+ newTcp();
+ break;
+ }
+ _myOscProperties.isLocked = true;
+ }
+
+
+ protected void stop() {
+ _myUdpClient = null;
+ if (_myMulticast != null) {
+ Logger.printDebug("OscP5.stop", "multicast.");
+ _myMulticast.dispose();
+ }
+ if (_myUdpServer != null) {
+ Logger.printDebug("OscP5.stop", "stopping udpserver.");
+ _myUdpServer.dispose();
+ }
+ _myMulticast = null;
+ _myUdpServer = null;
+ Logger.printProcess("OscP5", "stopped.");
+ }
+
+
+ private void newUdp() {
+ if (_myOscProperties.remoteAddress() != null && _myOscProperties.remoteAddress().isvalid()) {
+ _myUdpClient = new UdpClient(_myOscProperties.remoteAddress().address(), _myOscProperties.remoteAddress().port());
+ }
+ else {
+ _myUdpClient = new UdpClient();
+ }
+
+ if (_myOscProperties.listeningPort() > 0) {
+ _myUdpServer = new UdpServer(this, _myOscProperties.listeningPort(), _myOscProperties.datagramSize());
+ }
+ }
+
+
+ private void newTcp() {
+ if (_myOscProperties.listeningPort() > 0) {
+ _myTcpServer = new TcpServer(this, _myOscProperties.listeningPort(), TcpServer.MODE_STREAM);
+ isTcpServer = true;
+ }
+ else if (_myOscProperties.remoteAddress().isvalid()) {
+ _myTcpClient = new TcpClient(
+ this,
+ _myOscProperties.remoteAddress().address(),
+ _myOscProperties.remoteAddress().port(),
+ TcpClient.MODE_STREAM);
+ isTcpClient = true;
+ }
+ }
+
+
+ private void newMulticast() {
+ if (_myOscProperties.remoteAddress() != null && _myOscProperties.remoteAddress().isvalid()) {
+ _myMulticast = new Multicast(
+ this,
+ _myOscProperties.remoteAddress().address(),
+ _myOscProperties.remoteAddress().port(),
+ _myOscProperties.datagramSize());
+
+ }
+ else {
+ // ESCA-JAVA0266:
+ System.out.println("ERROR @ Multicast");
+ }
+
+ }
+
+
+ public void setTimeToLive(final int theTTL) {
+ if (_myMulticast != null) {
+ _myMulticast.setTimeToLive(theTTL);
+ }
+ else {
+ Logger.printWarning("OscNetManager.setTimeToLive", "only supported for multicast session.");
+ }
+ }
+
+
+ public TcpServer tcpServer() {
+ return _myTcpServer;
+ }
+
+
+ public TcpClient tcpClient() {
+ return _myTcpClient;
+ }
+
+
+ /**
+ * @param theListener DatagramPacketListener
+ */
+ public void addUdpListener(final UdpPacketListener theListener) {
+ _myUdpListener.add(theListener);
+ }
+
+
+ /**
+ * @param theListener DatagramPacketListener
+ */
+ public void removeUdpListener(final UdpPacketListener theListener) {
+ _myUdpListener.remove(theListener);
+ }
+
+
+ /**
+ * @param theListener TcpPacketListener
+ */
+ public void addTcpListener(final TcpPacketListener theListener) {
+ _myTcpListener.add(theListener);
+ }
+
+
+ /**
+ * @param theListener TcpPacketListener
+ */
+ public void removeTcpListener(final TcpPacketListener theListener) {
+ _myTcpListener.remove(theListener);
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ */
+ public void send(final OscPacket thePacket) {
+ if (_myOscProperties.sendStatus() == false && _myOscProperties.networkProtocol() != OscProperties.TCP) {
+ Logger.printWarning("OscNetManager.send", "please specify a remote address. send(OscPacket theOscPacket) "
+ + "is only supported when there is a host specified in OscProperties.");
+ }
+ else {
+ try {
+ switch (_myOscProperties.networkProtocol()) {
+ case (OscProperties.UDP):
+ if (_myOscProperties.srsp()) {
+ _myUdpServer.send(
+ thePacket.getBytes(),
+ _myOscProperties.remoteAddress().inetaddress(),
+ _myOscProperties.remoteAddress().port());
+
+ }
+ else {
+ _myUdpClient.send(
+ thePacket.getBytes(),
+ _myOscProperties.remoteAddress().inetaddress(),
+ _myOscProperties.remoteAddress().port());
+ }
+ break;
+ case (OscProperties.TCP):
+ if (isTcpServer) {
+ _myTcpServer.send(thePacket.getBytes());
+ }
+ else if (isTcpClient) {
+ _myTcpClient.send(thePacket.getBytes());
+ }
+ break;
+ case (OscProperties.MULTICAST):
+ _myMulticast.send(thePacket.getBytes());
+ break;
+ }
+ }
+ catch (final NullPointerException e) {
+ Logger.printError("OscManager.send", "NullPointerException " + e);
+ }
+ }
+ }
+
+
+ public void send(final DatagramPacket thePacket) {
+ if (_myOscProperties.srsp()) {
+ _myUdpServer.send(thePacket);
+ }
+ else {
+ _myUdpClient.send(thePacket);
+ }
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ * @param theAddress String
+ * @param thePort int
+ */
+ public void send(final OscPacket thePacket, final String theAddress, final int thePort) {
+ try {
+ switch (_myOscProperties.networkProtocol()) {
+ case (OscProperties.UDP):
+ if (_myOscProperties.srsp()) {
+ _myUdpServer.send(thePacket.getBytes(), theAddress, thePort);
+ }
+ else {
+ _myUdpClient.send(thePacket.getBytes(), theAddress, thePort);
+ }
+ break;
+ case (OscProperties.MULTICAST):
+ _myMulticast.send(thePacket.getBytes());
+ break;
+ case (OscProperties.TCP):
+ Logger.printWarning(
+ "OscP5.send",
+ "send(OscPacket thePacket,String theAddress,int thePort) is not supported in TCP mode.");
+ break;
+ }
+ }
+ catch (final NullPointerException e) {
+ Logger.printError("OscP5.send", "NullPointerException " + e);
+ }
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ * @param theList OscHostList
+ */
+ public void send(final OscPacket thePacket, final NetAddressList theList) {
+ switch (_myOscProperties.networkProtocol()) {
+ case (OscProperties.UDP):
+ final byte[] myBytes = thePacket.getBytes();
+ final DatagramPacket myPacket = new DatagramPacket(myBytes, myBytes.length);
+ for (int i = 0; i < theList.list().size(); i++) {
+ myPacket.setAddress(theList.get(i).inetaddress());
+ myPacket.setPort(theList.get(i).port());
+ send(myPacket);
+ }
+ break;
+ case (OscProperties.TCP):
+ Logger.printWarning(
+ "OscP5.send",
+ "send(OscPacket thePacket,NetAddressList theList) is not supported in TCP mode.");
+ break;
+ }
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ * @param theHost NetAddress
+ */
+ public void send(final OscPacket thePacket, final NetAddress theHost) {
+ switch (_myOscProperties.networkProtocol()) {
+
+ case (OscProperties.UDP):
+ if (theHost.isvalid()) {
+ final byte[] myBytes = thePacket.getBytes();
+ final DatagramPacket myPacket = new DatagramPacket(myBytes, myBytes.length);
+ myPacket.setAddress(theHost.inetaddress());
+ myPacket.setPort(theHost.port());
+ send(myPacket);
+ }
+ break;
+ case (OscProperties.TCP):
+ Logger.printWarning("OscP5.send", "send(OscPacket thePacket,NetAddress theHost) is not supported in TCP mode.");
+ break;
+ }
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments) {
+ send(new OscMessage(theAddrPattern, theArguments));
+ }
+
+
+ public void send(final String theAddrPattern, final Object[] theArguments, final String theAddress, final int thePort) {
+ send(new OscMessage(theAddrPattern, theArguments), theAddress, thePort);
+ }
+
+
+ public void send(final String theAddrPattern, final Object[] theArguments, final NetAddressList theList) {
+ send(new OscMessage(theAddrPattern, theArguments), theList);
+ }
+
+
+ public void send(final String theAddrPattern, final Object[] theArguments, final NetAddress theHost) {
+ send(new OscMessage(theAddrPattern, theArguments), theHost);
+ }
+
+
+ public void process(final DatagramPacket thePacket, final int thePort) {
+ for (int i = 0; i < _myUdpListener.size(); i++) {
+ _myUdpListener.get(i).process(thePacket, thePort);
+ }
+ }
+
+
+ public void process(final TcpPacket thePacket, final int thePort) {
+ for (int i = 0; i < _myTcpListener.size(); i++) {
+ _myTcpListener.get(i).process(thePacket, thePort);
+ }
+ }
+
+
+ public void remove(final AbstractTcpClient theClient) {}
+
+
+ public void status(final int theIndex) {}
+}
diff --git a/libraries/oscP5/src/oscP5/OscP5.java b/libraries/oscP5/src/oscP5/OscP5.java new file mode 100644 index 0000000..b2643dd --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscP5.java @@ -0,0 +1,991 @@ +/**
+ * An OSC (Open Sound Control) library for processing.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package oscP5;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Vector;
+
+import netP5.AbstractTcpClient;
+import netP5.Logger;
+import netP5.NetAddress;
+import netP5.NetAddressList;
+import netP5.NetInfo;
+import netP5.TcpClient;
+import netP5.TcpPacket;
+import netP5.TcpPacketListener;
+import netP5.TcpServer;
+import netP5.UdpPacketListener;
+
+/**
+ * oscP5 is an osc implementation for the programming environment processing.
+ * osc is the acronym for open sound control, a network protocol developed at
+ * cnmat, uc berkeley. open sound control is a protocol for communication among
+ * computers, sound synthesizers, and other multimedia devices that is optimized
+ * for modern networking technology and has been used in many application areas.
+ * for further specifications and application implementations please visit the
+ * official osc site.
+ *
+ * @usage Application
+ * @example oscP5sendReceive
+ * @related OscProperties
+ * @related OscMessage
+ * @related OscBundle
+ */
+
+/**
+ * TODO add better error message handling for oscEvents, see this post
+ * http://forum.processing.org/topic/oscp5-major-problems-with-error-handling# 25080000000811163
+ */
+public class OscP5 implements UdpPacketListener, TcpPacketListener {
+
+ /*
+ * @TODO implement polling option to avoid threading and synchronization
+ * issues. check email from tom lieber. look into mutex objects.
+ * http://www.google.com/search?hl=en&q=mutex+java&btnG=Search
+ */
+
+ // protected ArrayList _myOscPlugList = new ArrayList();
+
+ protected HashMap<String, ArrayList<OscPlug>> _myOscPlugMap = new HashMap<String, ArrayList<OscPlug>>();
+
+ protected NetInfo _myNetInfo;
+
+ private OscNetManager _myOscNetManager;
+
+ protected final static int NONE = OscNetManager.NONE;
+
+ public final static boolean ON = OscProperties.ON;
+
+ public final static boolean OFF = OscProperties.OFF;
+
+ /**
+ * a static variable used when creating an oscP5 instance with a sepcified network protocol.
+ */
+ public final static int UDP = OscProperties.UDP;
+
+ /**
+ * a static variable used when creating an oscP5 instance with a sepcified network protocol.
+ */
+ public final static int MULTICAST = OscProperties.MULTICAST;
+
+ /**
+ * a static variable used when creating an oscP5 instance with a sepcified network protocol.
+ */
+ public final static int TCP = OscProperties.TCP;
+
+ protected final Object parent;
+
+ private OscProperties _myOscProperties;
+
+ private Class<?> _myParentClass;
+
+ private Method _myEventMethod;
+
+ private Class<?> _myEventClass = OscMessage.class;
+
+ private boolean isEventMethod;
+
+ private boolean isBroadcast = false;
+
+ private NetAddress _myBroadcastAddress;
+
+ private boolean isOscIn = false;
+
+ /**
+ * @invisible
+ */
+ public static final String VERSION = "0.9.9";
+
+
+ /**
+ * @param theParent Object
+ * @param theProperties OscProperties
+ * @usage Application
+ */
+ public OscP5(final Object theParent, final OscProperties theProperties) {
+ welcome();
+ parent = theParent;
+
+ registerDispose(parent);
+
+ _myOscProperties = theProperties;
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ if (_myOscProperties.networkProtocol() == OscProperties.TCP) {
+ _myOscNetManager.addTcpListener(this);
+ }
+ else {
+ _myOscNetManager.addUdpListener(this);
+ }
+ isEventMethod = checkEventMethod();
+ if (_myOscProperties.networkProtocol() == OscProperties.MULTICAST) {
+ Logger.printInfo("OscP5", "is joining a multicast group @ " + _myOscProperties.remoteAddress().address() + ":" + _myOscProperties.remoteAddress().port());
+ }
+ else {
+ Logger.printInfo("OscP5", "is running. you (" + ip() + ") are listening @ port " + _myOscProperties.remoteAddress().port());
+ }
+ }
+
+
+ /**
+ * @param theParent Object
+ * @param theAddress String
+ * @param thePort int
+ * @param theMode int
+ * @usage Application
+ */
+ public OscP5(final Object theParent, final String theAddress, final int thePort, final int theMode) {
+ welcome();
+ parent = theParent;
+ _myOscProperties = new OscProperties();
+
+ registerDispose(parent);
+
+ switch (theMode) {
+ case (MULTICAST):
+ _myOscProperties.setNetworkProtocol(MULTICAST);
+ _myOscProperties.setRemoteAddress(theAddress, thePort);
+ _myOscProperties.setListeningPort(thePort);
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ _myOscNetManager.addUdpListener(this);
+ Logger.printInfo("OscP5", "is joining a multicast group @ " + _myOscProperties.remoteAddress().address() + ":" + _myOscProperties.remoteAddress().port());
+ break;
+ case (UDP):
+ _myOscProperties.setRemoteAddress(theAddress, thePort);
+ initUDP(thePort);
+ break;
+ case (TCP):
+ _myOscProperties.setNetworkProtocol(TCP);
+ _myOscProperties.setRemoteAddress(theAddress, thePort);
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ _myOscNetManager.addTcpListener(this);
+ break;
+ }
+ isEventMethod = checkEventMethod();
+ }
+
+
+ public OscP5(final Object theParent, final int theReceiveAtPort, final int theMode) {
+ welcome();
+ parent = theParent;
+
+ registerDispose(parent);
+
+ _myOscProperties = new OscProperties();
+ switch (theMode) {
+ case (UDP):
+ initUDP(theReceiveAtPort);
+ break;
+ case (TCP):
+ _myOscProperties.setNetworkProtocol(TCP);
+ _myOscProperties.setListeningPort(theReceiveAtPort);
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ _myOscNetManager.addTcpListener(this);
+ break;
+ case (MULTICAST):
+ Logger.printWarning("OscP5", "please specify a multicast address. use " + "OscP5(Object theObject, String theMulticastAddress, int thePort, int theMode)");
+ break;
+ }
+ isEventMethod = checkEventMethod();
+ }
+
+
+ /**
+ * @param theParent Object
+ * @param theReceiveAtPort int
+ * @usage Application
+ */
+ public OscP5(final Object theParent, final int theReceiveAtPort) {
+ welcome();
+ parent = theParent;
+
+ registerDispose(parent);
+
+ initUDP(theReceiveAtPort);
+ isEventMethod = checkEventMethod();
+ }
+
+
+ private void welcome() {
+ System.out.println("OscP5 " + VERSION + " " + "infos, comments, questions at http://www.sojamo.de/oscP5\n\n");
+ }
+
+
+ private void registerDispose(Object theObject) {
+ try {
+ Object parent = null;
+ String child = "processing.core.PApplet";
+ try {
+ Class<?> childClass = Class.forName(child);
+ Class<?> parentClass = Object.class;
+
+ if (parentClass.isAssignableFrom(childClass)) {
+ parent = childClass.newInstance();
+ parent = theObject;
+ }
+ } catch (Exception e) {
+ // System.out.println(e);
+ }
+ try {
+ Method method = parent.getClass().getMethod("registerDispose", Object.class);
+ try {
+ method.invoke(parent, new Object[] { this });
+ } catch (IllegalArgumentException e) {
+ // System.out.println(e);
+ } catch (IllegalAccessException e) {
+ // System.out.println(e);
+ } catch (InvocationTargetException e) {
+ // System.out.println(e);
+ }
+ } catch (SecurityException e) {
+ // System.out.println("fail (1) " + e);
+ } catch (NoSuchMethodException e) {
+ // System.out.println("fail (2) " + e);
+ }
+ } catch (NullPointerException e) {
+ System.err.println("Register Dispose\n" + e);
+ }
+ }
+
+
+ private void initUDP(final int theReceiveAtPort) {
+ _myOscProperties = new OscProperties();
+ _myOscProperties.setListeningPort(theReceiveAtPort);
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ _myOscNetManager.addUdpListener(this);
+ Logger.printInfo("OscP5", "is running. you (" + ip() + ") are listening @ port " + theReceiveAtPort);
+ }
+
+
+ /**
+ * check which eventMethod exists in the Object oscP5 was started from. this is necessary for
+ * backwards compatibility for oscP5 because the previous parameterType for the eventMethod was
+ * OscIn and is now OscMessage.
+ *
+ * @return boolean
+ * @invisible
+ */
+ private boolean checkEventMethod() {
+ _myParentClass = parent.getClass();
+ try {
+ Method[] myMethods = _myParentClass.getDeclaredMethods();
+ for (int i = 0; i < myMethods.length; i++) {
+ if (myMethods[i].getName().indexOf(_myOscProperties.eventMethod()) != -1) {
+ Class<?>[] myClasses = myMethods[i].getParameterTypes();
+ if (myClasses.length == 1) {
+ _myEventClass = myClasses[0];
+ isOscIn = ((_myEventClass.toString()).indexOf("OscIn") != -1) ? true : false;
+ break;
+ }
+ }
+ }
+
+ } catch (Throwable e) {
+ System.err.println(e);
+ }
+
+ String tMethod = _myOscProperties.eventMethod();
+ if (tMethod != null) {
+ try {
+ Class<?>[] tClass = { _myEventClass };
+ _myEventMethod = _myParentClass.getDeclaredMethod(tMethod, tClass);
+ _myEventMethod.setAccessible(true);
+ return true;
+ } catch (SecurityException e1) {
+ // e1.printStackTrace();
+ Logger.printWarning("OscP5.plug", "### security issues in OscP5.checkEventMethod(). (this occures when running in applet mode)");
+ } catch (NoSuchMethodException e1) {
+ }
+ }
+ // online fix, since an applet throws a security exception when calling
+ // setAccessible(true);
+ if (_myEventMethod != null) {
+ return true;
+ }
+ return false;
+ }
+
+
+ /**
+ * get the current version of oscP5.
+ *
+ * @return String
+ */
+ public String version() {
+ return VERSION;
+ }
+
+
+ /**
+ * @invisible
+ */
+ public void dispose() {
+ stop();
+ }
+
+
+ public void addListener(OscEventListener theListener) {
+ _myOscProperties.listeners().add(theListener);
+ }
+
+
+ public void removeListener(OscEventListener theListener) {
+ _myOscProperties.listeners().remove(theListener);
+ }
+
+
+ public Vector<OscEventListener> listeners() {
+ return _myOscProperties.listeners();
+ }
+
+
+ /**
+ * osc messages can be automatically forwarded to a specific method of an object. the plug
+ * method can be used to by-pass parsing raw osc messages - this job is done for you with the
+ * plug mechanism. you can also use the following array-types int[], float[], String[]. (but
+ * only as on single parameter e.g. somemethod(int[] theArray) {} ).
+ *
+ * @param theObject Object, can be any Object
+ * @param theMethodName String, the method name an osc message should be forwarded to
+ * @param theAddrPattern String, the address pattern of the osc message
+ * @param theTypeTag String
+ * @example oscP5plug
+ * @usage Application
+ */
+ public void plug(final Object theObject, final String theMethodName, final String theAddrPattern, final String theTypeTag) {
+ final OscPlug myOscPlug = new OscPlug();
+ myOscPlug.plug(theObject, theMethodName, theAddrPattern, theTypeTag);
+ // _myOscPlugList.add(myOscPlug);
+ if (_myOscPlugMap.containsKey(theAddrPattern)) {
+ _myOscPlugMap.get(theAddrPattern).add(myOscPlug);
+ }
+ else {
+ ArrayList<OscPlug> myOscPlugList = new ArrayList<OscPlug>();
+ myOscPlugList.add(myOscPlug);
+ _myOscPlugMap.put(theAddrPattern, myOscPlugList);
+ }
+ }
+
+
+ /**
+ * @param theObject Object, can be any Object
+ * @param theMethodName String, the method name an osc message should be forwarded to
+ * @param theAddrPattern String, the address pattern of the osc message
+ * @example oscP5plug
+ * @usage Application
+ */
+ public void plug(final Object theObject, final String theMethodName, final String theAddrPattern) {
+ final Class<?> myClass = theObject.getClass();
+ final Method[] myMethods = myClass.getDeclaredMethods();
+ Class<?>[] myParams = null;
+ for (int i = 0; i < myMethods.length; i++) {
+ String myTypetag = "";
+ try {
+ myMethods[i].setAccessible(true);
+ } catch (Exception e) {
+ }
+ if ((myMethods[i].getName()).equals(theMethodName)) {
+ myParams = myMethods[i].getParameterTypes();
+ OscPlug myOscPlug = new OscPlug();
+ for (int j = 0; j < myParams.length; j++) {
+ myTypetag += myOscPlug.checkType(myParams[j].getName());
+ }
+
+ myOscPlug.plug(theObject, theMethodName, theAddrPattern, myTypetag);
+ // _myOscPlugList.add(myOscPlug);
+ if (_myOscPlugMap.containsKey(theAddrPattern)) {
+ _myOscPlugMap.get(theAddrPattern).add(myOscPlug);
+ }
+ else {
+ ArrayList<OscPlug> myOscPlugList = new ArrayList<OscPlug>();
+ myOscPlugList.add(myOscPlug);
+ _myOscPlugMap.put(theAddrPattern, myOscPlugList);
+ }
+
+ }
+ }
+ }
+
+
+ private void handleSystemMessage(final OscMessage theOscMessage) {
+ if (theOscMessage.addrPattern().startsWith("/sys/ping")) {
+ send("/sys/pong", new Object[0], _myBroadcastAddress);
+ }
+ else if (theOscMessage.addrPattern().startsWith("/sys/register")) {
+ if (theOscMessage.tcpConnection() != null) {
+ if (theOscMessage.checkTypetag("s")) {
+ theOscMessage.tcpConnection().setName(theOscMessage.get(0).stringValue());
+ }
+ }
+ }
+ }
+
+
+ private void callMethod(final OscMessage theOscMessage) {
+
+ if (theOscMessage.addrPattern().startsWith("/sys/")) {
+ handleSystemMessage(theOscMessage);
+ // finish this for oscbroadcaster
+ // return;
+ }
+
+ // forward the message to all OscEventListeners
+ for (int i = listeners().size() - 1; i >= 0; i--) {
+ ((OscEventListener) listeners().get(i)).oscEvent(theOscMessage);
+ }
+
+ /* check if the arguments can be forwarded as array */
+
+ if (theOscMessage.isArray) {
+ // for (int i = 0; i < _myOscPlugList.size(); i++) {
+ // OscPlug myPlug = ((OscPlug) _myOscPlugList.get(i));
+ // if (myPlug.isArray && myPlug.checkMethod(theOscMessage, true)) {
+ // invoke(myPlug.getObject(), myPlug.getMethod(),
+ // theOscMessage.argsAsArray());
+ // }
+ // }
+
+ if (_myOscPlugMap.containsKey(theOscMessage.addrPattern())) {
+ ArrayList<OscPlug> myOscPlugList = _myOscPlugMap.get(theOscMessage.addrPattern());
+ for (int i = 0; i < myOscPlugList.size(); i++) {
+ OscPlug myPlug = (OscPlug) myOscPlugList.get(i);
+ if (myPlug.isArray && myPlug.checkMethod(theOscMessage, true)) {
+ // Should we set the following here? The old code did
+ // not:
+ // theOscMessage.isPlugged = true;
+ invoke(myPlug.getObject(), myPlug.getMethod(), theOscMessage.argsAsArray());
+ }
+ }
+ }
+
+ }
+ /* check if there is a plug method for the current message */
+ // for (int i = 0; i < _myOscPlugList.size(); i++) {
+ // OscPlug myPlug = ((OscPlug) _myOscPlugList.get(i));
+ // if (!myPlug.isArray && myPlug.checkMethod(theOscMessage, false)) {
+ // theOscMessage.isPlugged = true;
+ // invoke(myPlug.getObject(), myPlug.getMethod(), theOscMessage
+ // .arguments());
+ // }
+ // }
+
+ if (_myOscPlugMap.containsKey(theOscMessage.addrPattern())) {
+ ArrayList<OscPlug> myOscPlugList = _myOscPlugMap.get(theOscMessage.addrPattern());
+ for (int i = 0; i < myOscPlugList.size(); i++) {
+ OscPlug myPlug = (OscPlug) myOscPlugList.get(i);
+ if (!myPlug.isArray && myPlug.checkMethod(theOscMessage, false)) {
+ theOscMessage.isPlugged = true;
+ invoke(myPlug.getObject(), myPlug.getMethod(), theOscMessage.arguments());
+ }
+ }
+ }
+
+ /* if no plug method was detected, then use the default oscEvent mehtod */
+ Logger.printDebug("OscP5.callMethod ", "" + isEventMethod);
+ if (isEventMethod) {
+ try {
+ if (isOscIn) {
+ invoke(parent, _myEventMethod, new Object[] { new OscIn(theOscMessage) });
+ Logger.printDebug("OscP5.callMethod ", "invoking OscIn " + isEventMethod);
+ }
+ else {
+ invoke(parent, _myEventMethod, new Object[] { theOscMessage });
+ Logger.printDebug("OscP5.callMethod ", "invoking OscMessage " + isEventMethod);
+ }
+ } catch (ClassCastException e) {
+ Logger.printError("OscHandler.callMethod", " ClassCastException." + e);
+ }
+ }
+ }
+
+
+ private void invoke(final Object theObject, final Method theMethod, final Object[] theArgs) {
+ try {
+ theMethod.invoke(theObject, theArgs);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ Logger.printError("OscP5", "ERROR. an error occured while forwarding an OscMessage\n " + "to a method in your program. please check your code for any \n"
+ + "possible errors that might occur in the method where incoming\n " + "OscMessages are parsed e.g. check for casting errors, possible\n "
+ + "nullpointers, array overflows ... .\n" + "method in charge : " + theMethod.getName() + " " + e);
+ }
+ }
+
+
+ /**
+ * incoming osc messages from an udp socket are parsed, processed and forwarded to the parent.
+ *
+ * @invisible
+ * @param thePacket DatagramPacket
+ * @param thePort int
+ */
+ public void process(final DatagramPacket thePacket, final int thePort) {
+ synchronized (this) {
+ OscPacket p = OscPacket.parse(thePacket);
+ if (p.isValid()) {
+ if (p.type() == OscPacket.BUNDLE) {
+ for (int i = 0; i < ((OscBundle) p).size(); i++) {
+ callMethod(((OscBundle) p).getMessage(i));
+ }
+ }
+ else {
+ callMethod((OscMessage) p);
+ }
+ }
+ notifyAll();
+ }
+ }
+
+
+ /**
+ * @invisible
+ * @see netP5.TcpPacketListener#process(netP5.TcpPacket, int)
+ */
+ public void process(final TcpPacket thePacket, final int thePort) {
+ synchronized (this) {
+ OscPacket p = OscPacket.parse(thePacket);
+ if (p.isValid()) {
+ if (p.type() == OscPacket.BUNDLE) {
+ for (int i = 0; i < ((OscBundle) p).size(); i++) {
+ callMethod(((OscBundle) p).getMessage(i));
+ }
+ }
+ else {
+ callMethod((OscMessage) p);
+ }
+ }
+ notifyAll();
+ }
+ }
+
+
+ /**
+ * @invisible
+ * @param theTcpClient AbstractTcpClient
+ */
+ public void remove(AbstractTcpClient theTcpClient) {
+ }
+
+
+ /**
+ * @invisible
+ * @param theIndex int
+ */
+ public void status(int theIndex) {
+ }
+
+
+ /**
+ * returns the current properties of oscP5.
+ *
+ * @return OscProperties
+ * @related OscProperties
+ * @usage Application
+ */
+ public OscProperties properties() {
+ return _myOscProperties;
+ }
+
+
+ /**
+ * @invisible
+ * @return boolean
+ */
+ public boolean isBroadcast() {
+ return isBroadcast;
+ }
+
+
+ /**
+ * @return String
+ * @invisible
+ */
+ public String ip() {
+ return NetInfo.getHostAddress();
+ }
+
+
+ /**
+ * oscP5 has a logging mechanism which prints out processes, warnings and errors into the
+ * console window. e.g. turn off the error log with setLogStatus(Logger.ERROR, Logger.OFF);
+ *
+ * @param theIndex int
+ * @param theValue int
+ * @usage Application
+ */
+ public static void setLogStatus(final int theIndex, final int theValue) {
+ Logger.set(theIndex, theValue);
+ }
+
+
+ /**
+ * @param theValue
+ */
+ public static void setLogStatus(final int theValue) {
+ for (int i = 0; i < Logger.ALL; i++) {
+ Logger.set(i, theValue);
+ }
+ }
+
+
+ /**
+ * set timeToLive of a multicast packet.
+ *
+ * @param theTTL int
+ */
+ public void setTimeToLive(int theTTL) {
+ _myOscNetManager.setTimeToLive(theTTL);
+ }
+
+
+ /**
+ * @param theHost NetAddress
+ * @invisible
+ */
+ public void disconnect(final NetAddress theHost) {
+ if (theHost.isvalid() && theHost.name.length() > 1) {
+ String myAddrPattern = "/sys/disconnect/" + theHost.name + "/" + theHost.port();
+ send(myAddrPattern, new Object[0], theHost);
+ isBroadcast = false;
+ _myBroadcastAddress = null;
+ }
+ }
+
+
+ /**
+ * @param theNetAddress NetAddress
+ * @param theName String
+ * @param theArguments String[]
+ * @invisible
+ */
+ public void connect(final NetAddress theNetAddress, final String theName, final String[] theArguments) {
+ if (theNetAddress.isvalid()) {
+ _myBroadcastAddress = theNetAddress;
+ _myBroadcastAddress.name = theName;
+ String myAddrPattern = "/sys/connect/" + theName + "/" + _myOscProperties.listeningPort();
+ send(myAddrPattern, theArguments, _myBroadcastAddress);
+ isBroadcast = true;
+ }
+ }
+
+
+ /**
+ * netinfo() returns an instance of a NetInfo Object from which you can get LAN and WAN
+ * information.
+ *
+ * @return NetInfo
+ */
+ public NetInfo netInfo() {
+ return _myNetInfo;
+ }
+
+
+ /**
+ * return the instance of the running TCP server if in TCP mode.
+ *
+ * @return TcpServer
+ */
+ public TcpServer tcpServer() {
+ return _myOscNetManager.tcpServer();
+ }
+
+
+ /**
+ * return the instance of the running TCP client if in TCP mode.
+ *
+ * @return TcpClient
+ */
+ public TcpClient tcpClient() {
+ return _myOscNetManager.tcpClient();
+ }
+
+
+ /**
+ * you can send osc packets in many different ways. see below and use the send method that fits
+ * your needs.
+ *
+ *
+ * @param thePacket OscPacket
+ * @param theNetAddress NetAddress
+ * @usage Application
+ */
+ public void send(final OscPacket thePacket, final NetAddress theNetAddress) {
+ _myOscNetManager.send(thePacket, theNetAddress);
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ * @usage Application
+ * @example oscP5sendReceive
+ */
+ public void send(final OscPacket thePacket) {
+ _myOscNetManager.send(thePacket);
+ }
+
+
+ /**
+ * @param thePacket OscPacket
+ * @param theNetAddressList NetAddressList
+ * @usage Application
+ */
+ public void send(final OscPacket thePacket, final NetAddressList theNetAddressList) {
+ _myOscNetManager.send(thePacket, theNetAddressList);
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ * @usage Application
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments) {
+ _myOscNetManager.send(theAddrPattern, theArguments);
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ * @param theNetAddressList NetAddressList
+ * @usage Application
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments, final NetAddressList theNetAddressList) {
+ _myOscNetManager.send(theAddrPattern, theArguments, theNetAddressList);
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ * @param theNetAddress NetAddress
+ * @usage Application
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments, final NetAddress theNetAddress) {
+ _myOscNetManager.send(theAddrPattern, theArguments, theNetAddress);
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ * @param theNetAddress NetAddress
+ * @usage Application
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments, final String theAddress, int thePort) {
+ _myOscNetManager.send(theAddrPattern, theArguments, theAddress, thePort);
+ }
+
+
+ /**
+ * send to tcp client
+ *
+ * @param thePacket OscPacket
+ * @param theClient TcpClient
+ */
+ public void send(final OscPacket thePacket, final TcpClient theClient) {
+ theClient.send(thePacket.getBytes());
+ }
+
+
+ /**
+ * @param theAddrPattern String
+ * @param theArguments Object[]
+ * @param theClient TcpClient
+ */
+ public void send(final String theAddrPattern, final Object[] theArguments, final TcpClient theClient) {
+ send(new OscMessage(theAddrPattern, theArguments), theClient);
+ }
+
+
+ /**
+ * the send method offers a lot of possibilities. have a look at the send documentation.
+ *
+ * @param thePacket OscPacket
+ * @param theIpAddress String
+ * @param thePort int
+ * @usage Application
+ * @deprecated
+ */
+ public void send(final OscPacket thePacket, final String theIpAddress, final int thePort) {
+ _myOscNetManager.send(thePacket, theIpAddress, thePort);
+ }
+
+
+ /**
+ * stop oscP5 and close open Sockets.
+ */
+ public void stop() {
+ Logger.printDebug("OscP5.stop", "starting to stop oscP5.");
+ _myOscNetManager.stop();
+ Logger.printDebug("OscP5.stop", "stopping oscP5.");
+ }
+
+
+ /**
+ * a static method to send an OscMessage straight out of the box without having to instantiate
+ * oscP5.
+ *
+ * @param theOscMessage OscMessage
+ * @param theNetAddress NetAddress
+ * @example oscP5flush
+ */
+ public static void flush(final OscMessage theOscMessage, final NetAddress theNetAddress) {
+ flush(theOscMessage.getBytes(), theNetAddress);
+ }
+
+
+ public static void flush(final OscPacket theOscPacket, final NetAddress theNetAddress) {
+ flush(theOscPacket.getBytes(), theNetAddress);
+ }
+
+
+ public static void flush(final String theAddrPattern, final Object[] theArguments, final NetAddress theNetAddress) {
+ flush((new OscMessage(theAddrPattern, theArguments)).getBytes(), theNetAddress);
+ }
+
+
+ public static void flush(final byte[] theBytes, final NetAddress theNetAddress) {
+ DatagramSocket mySocket;
+ try {
+ mySocket = new DatagramSocket();
+
+ DatagramPacket myPacket = new DatagramPacket(theBytes, theBytes.length, theNetAddress.inetaddress(), theNetAddress.port());
+ mySocket.send(myPacket);
+ } catch (SocketException e) {
+ Logger.printError("OscP5.openSocket", "cant create socket " + e.getMessage());
+ } catch (IOException e) {
+ Logger.printError("OscP5.openSocket", "cant create multicastSocket " + e.getMessage());
+ }
+ }
+
+
+ /*
+ * DEPRECATED methods and constructors.
+ */
+
+ /**
+ * @param theBytes byte[]
+ * @param theAddress String
+ * @param thePort int
+ * @deprecated
+ */
+ public static void flush(final byte[] theBytes, final String theAddress, final int thePort) {
+ flush(theBytes, new NetAddress(theAddress, thePort));
+ }
+
+
+ /**
+ * @param theOscMessage OscMessage
+ * @param theAddress String
+ * @param thePort int
+ * @deprecated
+ */
+ public static void flush(final OscMessage theOscMessage, final String theAddress, final int thePort) {
+ flush(theOscMessage.getBytes(), new NetAddress(theAddress, thePort));
+ }
+
+
+ /**
+ * old version of constructor. still in here for backwards compatibility.
+ *
+ * @deprecated
+ * @invisible
+ */
+ public OscP5(final Object theParent, final String theHost, final int theSendToPort, final int theReceiveAtPort, final String theMethodName) {
+ welcome();
+ parent = theParent;
+
+ registerDispose(parent);
+
+ _myOscProperties = new OscProperties();
+ _myOscProperties.setRemoteAddress(theHost, theSendToPort);
+ _myOscProperties.setListeningPort(theReceiveAtPort);
+ _myOscProperties.setEventMethod(theMethodName);
+ _myOscNetManager = new OscNetManager();
+ _myOscNetManager.start(_myOscProperties);
+ _myOscNetManager.addUdpListener(this);
+ isEventMethod = checkEventMethod();
+ }
+
+
+ /**
+ * @deprecated
+ * @param theAddrPattern String
+ * @return OscMessage
+ * @invisible
+ */
+ public OscMessage newMsg(String theAddrPattern) {
+ return new OscMessage(theAddrPattern);
+ }
+
+
+ /**
+ * @deprecated
+ * @param theAddrPattern String
+ * @return OscMessage
+ * @invisible
+ */
+
+ public OscBundle newBundle() {
+ return new OscBundle();
+ }
+
+
+ /**
+ * used by the monome library by jklabs
+ *
+ * @deprecated
+ * @invisible
+ */
+ public void disconnectFromTEMP() {
+ }
+
+
+ /**
+ * @deprecated
+ * @param theParent Object
+ * @param theAddress String
+ * @param thePort int
+ */
+ public OscP5(final Object theParent, final String theAddress, final int thePort) {
+ this(theParent, theAddress, thePort, OscProperties.MULTICAST);
+ }
+
+}
diff --git a/libraries/oscP5/src/oscP5/OscPacket.java b/libraries/oscP5/src/oscP5/OscPacket.java new file mode 100644 index 0000000..4e9cc59 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscPacket.java @@ -0,0 +1,143 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +import java.net.DatagramPacket; +import java.net.InetAddress; +import netP5.Bytes; +import netP5.NetAddress; +import netP5.TcpPacket; +import netP5.TcpClient; + +/** + * @invisible + */ +public abstract class OscPacket extends OscPatcher { + + protected static final int MESSAGE = 0; + + + protected static final int BUNDLE = 1; + + + protected InetAddress inetAddress; + + + protected String hostAddress; + + + protected int _myType; + + + protected TcpClient _myTcpClient = null; + + + protected int port; + + /** + * @invisible + */ + public OscPacket() {} + + + protected static OscPacket parse(DatagramPacket theDatagramPacket) { + if (evaluatePacket(theDatagramPacket.getData()) == MESSAGE) { + return new OscMessage(theDatagramPacket); + } else { + return new OscBundle(theDatagramPacket); + } + } + + + protected static OscPacket parse(TcpPacket theTcpPacket) { + if (evaluatePacket(theTcpPacket.getData()) == MESSAGE) { + return new OscMessage(theTcpPacket); + } else { + return new OscBundle(theTcpPacket); + } + } + + + private static int evaluatePacket(byte[] theBytes) { + return (Bytes.areEqual(OscBundle.BUNDLE_AS_BYTES, Bytes.copy(theBytes, 0, OscBundle.BUNDLE_AS_BYTES.length))) ? BUNDLE + : MESSAGE; + } + + + /** + * when in TCP mode, tcpConnection() returns the instance of the TcpClient that has sent the OscMessage. + * @return TcpClient + */ + public TcpClient tcpConnection() { + return _myTcpClient; + } + + + protected boolean isValid() { + return isValid; + } + + + protected int type() { + return _myType; + } + + + public int port() { + return port; + } + + + public NetAddress netAddress() { + return new NetAddress(inetAddress, port); + } + + + /** + * @deprecated + * @invisible + * @return NetAddress + */ + public NetAddress netaddress() { + return new NetAddress(inetAddress, port); + } + + + /** + * @return String + */ + public String address() { + return hostAddress; + } + + + /** + * @return byte[] + * @invisible + */ + public abstract byte[] getBytes(); + +} diff --git a/libraries/oscP5/src/oscP5/OscPatcher.java b/libraries/oscP5/src/oscP5/OscPatcher.java new file mode 100644 index 0000000..aade541 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscPatcher.java @@ -0,0 +1,245 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +import java.net.InetAddress; +import java.util.ArrayList; +import netP5.Bytes; +import netP5.TcpClient; + +/** + * + * @invisible + */ +public abstract class OscPatcher { + + +protected static final byte ZEROBYTE = 0x00; + + protected static final byte KOMMA = 0x2c; + + protected static final long TIMETAG_OFFSET = 2208988800L; + + protected static final long TIEMTAG_NOW = 1; + + protected ArrayList<OscMessage> messages; + + protected byte[] _myAddrPattern; + + protected int _myAddrInt = -1; + + protected byte[] _myTypetag = new byte[0]; + + protected byte[] _myData = new byte[0]; + + protected Object[] _myArguments; + + protected boolean isValid = false; + + protected long timetag = 1; + + protected boolean isArray = false; + + protected byte _myArrayType = 0X00; + + protected OscPatcher() { + } + + + protected int parseBundle(final byte[] theBytes, + final InetAddress theAddress, final int thePort, + final TcpClient theClient) { + if (theBytes.length > OscBundle.BUNDLE_HEADER_SIZE) { + timetag = (new Long(Bytes.toLong(Bytes.copy(theBytes, 8, 8)))).longValue(); + int myPosition = OscBundle.BUNDLE_HEADER_SIZE; + messages = new ArrayList<OscMessage>(); + int myMessageLength = Bytes.toInt(Bytes.copy(theBytes, myPosition,4)); + while (myMessageLength != 0 && (myMessageLength % 4 == 0) + && myPosition < theBytes.length) { + myPosition += 4; + messages.add(new OscMessage(Bytes.copy(theBytes, myPosition,myMessageLength), + theAddress, + thePort, + timetag, + theClient)); + myPosition += myMessageLength; + if(myPosition >= theBytes.length) + break; + myMessageLength = Bytes.toInt(Bytes.copy(theBytes, myPosition,4)); + } + } + for (int i = 0; i < messages.size(); i++) { + if (!messages.get(i).isValid) { + messages.remove(messages.get(i)); + } + } + + if (messages.size() > 0) { + isValid = true; + } + return messages.size(); + } + + + protected void parseMessage(final byte[] theBytes) { + int myLength = theBytes.length; + int myIndex = 0; + myIndex = parseAddrPattern(theBytes, myLength, myIndex); + if (myIndex != -1) { + myIndex = parseTypetag(theBytes, myLength, myIndex); + } + if (myIndex != -1) { + _myData = Bytes.copy(theBytes, myIndex); + _myArguments = parseArguments(_myData); + isValid = true; + } + } + + + protected int parseAddrPattern(final byte[] theBytes, final int theLength, + final int theIndex) { + if (theLength > 4 && theBytes[4] == KOMMA) { + _myAddrInt = Bytes.toInt(Bytes.copy(theBytes, 0, 4)); + } + for (int i = theIndex; i < theLength; i++) { + if (theBytes[i] == ZEROBYTE) { + _myAddrPattern = Bytes.copy(theBytes, theIndex, i); + return i + align(i); + } + } + return -1; + } + + + protected int parseTypetag(final byte[] theBytes, final int theLength, + int theIndex) { + if (theBytes[theIndex] == KOMMA) { + theIndex++; + for (int i = theIndex; i < theLength; i++) { + if (theBytes[i] == ZEROBYTE) { + _myTypetag = Bytes.copy(theBytes, theIndex, i - theIndex); + return i + align(i); + } + } + } + return -1; + } + + + /** + * cast the arguments passed with the incoming osc message and store them in + * an object array. + * + * @param theBytes + * @return + */ + protected Object[] parseArguments(final byte[] theBytes) { + Object[] myArguments = new Object[0]; + int myTagIndex = 0; + int myIndex = 0; + myArguments = new Object[_myTypetag.length]; + isArray = (_myTypetag.length > 0) ? true : false; + while (myTagIndex < _myTypetag.length) { + /* check if we still save the arguments as an array */ + if (myTagIndex == 0) { + _myArrayType = _myTypetag[myTagIndex]; + } else { + if (_myTypetag[myTagIndex] != _myArrayType) { + isArray = false; + } + } + switch (_myTypetag[myTagIndex]) { + case (0x63): // char c + myArguments[myTagIndex] = (new Character((char) (Bytes + .toInt(Bytes.copy(theBytes, myIndex, 4))))); + myIndex += 4; + break; + case (0x69): // int i + myArguments[myTagIndex] = (new Integer(Bytes.toInt(Bytes.copy( + theBytes, myIndex, 4)))); + myIndex += 4; + break; + case (0x66): // float f + myArguments[myTagIndex] = (new Float(Bytes.toFloat(Bytes.copy( + theBytes, myIndex, 4)))); + myIndex += 4; + + break; + case (0x6c): // long l + case (0x68): // long h + myArguments[myTagIndex] = (new Long(Bytes.toLong(Bytes.copy( + theBytes, myIndex, 8)))); + myIndex += 8; + break; + case (0x64): // double d + myArguments[myTagIndex] = (new Double(Bytes.toDouble(Bytes + .copy(theBytes, myIndex, 8)))); + myIndex += 8; + break; + case (0x53): // Symbol S + case (0x73): // String s + int newIndex = myIndex; + StringBuffer stringBuffer = new StringBuffer(); + + stringLoop: + do { + if (theBytes[newIndex] == 0x00) { + break stringLoop; + } else { + stringBuffer.append((char) theBytes[newIndex]); + } + newIndex++; + } while (newIndex < theBytes.length); + + myArguments[myTagIndex] = (stringBuffer.toString()); + myIndex = newIndex + align(newIndex); + break; + case 0x62: // byte[] b - blob + int myLen = Bytes.toInt(Bytes.copy(theBytes, myIndex, 4)); + myIndex += 4; + myArguments[myTagIndex] = Bytes.copy(theBytes, myIndex, myLen); + myIndex += myLen + (align(myLen) % 4); + break; + case 0x6d: // midi m + myArguments[myTagIndex] = Bytes.copy(theBytes, myIndex, 4); + myIndex += 4; + break; + /* + * no arguments for typetags T,F,N T = true F = false N = false + */ + } + myTagIndex++; + } + _myData = Bytes.copy(_myData, 0, myIndex); + return myArguments; + } + + + protected static int align(int theInt) { + return (4 - (theInt % 4)); + } + +}
\ No newline at end of file diff --git a/libraries/oscP5/src/oscP5/OscPlug.java b/libraries/oscP5/src/oscP5/OscPlug.java new file mode 100644 index 0000000..1fcec89 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscPlug.java @@ -0,0 +1,258 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +import java.lang.reflect.Method; +import netP5.Logger; + +/** + * + * @invisible + */ +public class OscPlug { + + private boolean _isValid = true; + + private String _myTypetag = ""; + + private String _myAddrPattern = ""; + + private String _myPattern = ""; + + private String _myMethodName; + + private Object _myObject; + + public Method method = null; + + private int _myChecker = 0; + + protected boolean isArray = false; + + private static final int CHECK_ADDRPATTERN_TYPETAG = 0; + + private static final int CHECK_ADDRPATTERN = 1; + + private static final int CHECK_TYPETAG = 2; + + public void plug(final Object theObject, final String theMethodName, + final String theAddrPattern) { + _myObject = theObject; + _myMethodName = theMethodName; + _myAddrPattern = theAddrPattern; + _myChecker = CHECK_ADDRPATTERN_TYPETAG; + if (_myMethodName != null && _myMethodName.length() > 0) { + Class<?> myClass = theObject.getClass(); + Class<?>[] myParams = null; + Method[] myMethods = myClass.getMethods(); + _myTypetag = ""; + for (int i = 0; i < myMethods.length; i++) { + if ((myMethods[i].getName()).equals(_myMethodName)) { + myParams = myMethods[i].getParameterTypes(); + for (int j = 0; j < myParams.length; j++) { + _myTypetag += checkType(myParams[j].getName()); + } + break; + } + } + if (myParams != null) { + makeMethod(theObject.getClass(), myParams); + } else { + Logger.printWarning("OscPlug.plug()", + "no arguments found for method " + _myMethodName); + } + } + } + + public void plug(final Object theObject, final String theMethodName, + final String theAddrPattern, final String theTypetag) { + _myObject = theObject; + _myMethodName = theMethodName; + _myAddrPattern = theAddrPattern; + _myTypetag = theTypetag; + _myChecker = CHECK_ADDRPATTERN_TYPETAG; + + if (_myMethodName != null && _myMethodName.length() > 0) { + int tLen = _myTypetag.length(); + Class<?>[] myParams; + if (tLen > 0) { + myParams = getArgs(_myTypetag); + } else { + myParams = null; + } + + if (_isValid) { + makeMethod(theObject.getClass(), myParams); + } + } + } + + public Object getObject() { + return _myObject; + } + + private void makeMethod(final Class<?> theObjectsClass, final Class<?>[] theClass) { + try { + method = theObjectsClass.getDeclaredMethod(_myMethodName, theClass); + _myPattern = _myAddrPattern + _myTypetag; + method.setAccessible(true); + Logger.printProcess("OscPlug", "plugging " + theObjectsClass + + " | " + "addrPattern:" + _myAddrPattern + " typetag:" + + _myTypetag + " method:" + _myMethodName); + + } catch (Exception e) { + final Class<?> theObjecsSuperClass = theObjectsClass.getSuperclass(); + if (theObjecsSuperClass.equals(Object.class)) { + if (theObjectsClass.getName().equals("java.awt.Component") == false) { // applet fix. + Logger.printError("OscPlug", "method " + + theObjectsClass.getName() + + " does not exist in your code."); + } + } else { + makeMethod(theObjecsSuperClass, theClass); + } + } + return; + } + + public boolean checkMethod(final OscMessage theOscMessage, + final boolean isArray) { + String myTypetag; + /* + * if theFlag is true and the arguments of theOscmessage can be + * represented as an array of the same type, then only fetch the first + * character of the typetag, otherwise use the full typetag. + */ + if (isArray) { + myTypetag = "" + theOscMessage.typetag().charAt(0); + } else { + myTypetag = theOscMessage.typetag(); + } + switch (_myChecker) { + case (CHECK_ADDRPATTERN_TYPETAG): + String thePattern = theOscMessage.addrPattern() + myTypetag; + return thePattern.equals(_myPattern); + case (CHECK_ADDRPATTERN): + return (theOscMessage.addrPattern().equals(_myAddrPattern)); + case (CHECK_TYPETAG): + return (myTypetag.equals(_myTypetag)); + default: + return false; + } + } + + public Method getMethod() { + return method; + } + + + public String checkType(final String theName) { + if (theName.equals("int")) { + return "i"; + } else if (theName.equals("float")) { + return "f"; + } else if (theName.equals("java.lang.String")) { + return "s"; + } else if (theName.equals("[Ljava.lang.String;")) { + isArray = true; + return "s"; + } + + else if (theName.equals("char")) { + return "c"; + } else if (theName.equals("[B")) { + return "b"; + } else if (theName.equals("[F")) { + isArray = true; + return "f"; + } else if (theName.equals("[I")) { + isArray = true; + return "i"; + } + + else if (theName.equals("double")) { + return "d"; + } else if (theName.equals("boolean")) { + return "T"; + } else if (theName.equals("long")) { + return "h"; + } + return ""; + } + + private Class<?>[] getArgs(final String theArgs) { + char[] tChar = theArgs.toCharArray(); + int tLen = theArgs.length(); + Class<?>[] tClass = new Class[tLen]; + for (int i = 0; i < tLen; i++) { + switch (tChar[i]) { + case ('i'): + tClass[i] = (isArray == true) ? int[].class : int.class; + break; + case ('S'): + case ('s'): + tClass[i] = (isArray == true) ? String[].class : String.class; + break; + case ('f'): + tClass[i] = (isArray == true) ? float[].class : float.class; + break; + case ('d'): + tClass[i] = double.class; + break; + case ('c'): + tClass[i] = char.class; + break; + case ('h'): + case ('l'): + tClass[i] = long.class; + break; + case ('T'): + tClass[i] = boolean.class; + break; + case ('F'): + tClass[i] = boolean.class; + break; + case ('b'): + tClass[i] = byte[].class; + break; + case ('o'): + _myChecker = CHECK_ADDRPATTERN; + tClass = new Class[] { Object[].class }; + break; + + default: + _isValid = false; + break; + } + } + if (!_isValid) { + tClass = null; + System.out.println("ERROR could't plug method " + _myMethodName); + } + return tClass; + } + +} diff --git a/libraries/oscP5/src/oscP5/OscProperties.java b/libraries/oscP5/src/oscP5/OscProperties.java new file mode 100644 index 0000000..281eb1f --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscProperties.java @@ -0,0 +1,319 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + + +import netP5.Logger; +import netP5.NetAddress; +import java.util.Vector; + +/** + * osc properties are used to start oscP5 with more specific settings. + * osc properties have to be passed to oscP5 in the constructor when + * starting a new instance of oscP5. + * @related OscP5 + * @example oscP5properties + */ +public class OscProperties { + + public static final boolean ON = true; + + public static final boolean OFF = false; + + /** + * @related setNetworkProtocol ( ) + */ + public static final int UDP = 0; + + /** + * @related setNetworkProtocol ( ) + */ + public static final int MULTICAST = 1; + + + /** + * @related setNetworkProtocol ( ) + */ + public static final int TCP = 2; + + + protected static final String[] _myProtocols = {"udp", "tcp", "multicast"}; + + protected boolean isLocked = false; + + protected final Vector<OscEventListener> listeners; + + private NetAddress _myRemoteAddress = new NetAddress("", 0); + + private int _myListeningPort = 0; + + private int _myDatagramSize = 1536; // common MTU + + protected String _myDefaultEventMethodName = "oscEvent"; + + private int _myNetworkProtocol = UDP; + + private boolean _mySendStatus = false; + + private boolean _mySRSP = OFF; // (S)end (R)eceive (S)ame (P)ort + + public OscProperties(OscEventListener theParent) { + this(); + listeners.add(theParent); + } + + + + /** + * create a new OscProperties Object. + */ + public OscProperties() { + listeners = new Vector<OscEventListener>(); + } + + + + /** + * + * @return OscEventListener + * @invisible + */ + public Vector<OscEventListener> listeners() { + return listeners; + } + + + + /** + * + * @return boolean + * @related OscProperties + * @invisible + */ + public boolean sendStatus() { + return _mySendStatus; + } + + + + /** + * set the remote host address. set ip address and port of the host + * message should be sent to. + * @param theHostAddress String + * @param thePort int + * @related OscProperties + */ + public void setRemoteAddress(final String theHostAddress, final int thePort) { + _myRemoteAddress = new NetAddress(theHostAddress, thePort); + _mySendStatus = _myRemoteAddress.isvalid(); + } + + /** + * set the remote host address. set ip address and port of the host + * message should be sent to. + * @param theNetAddress NetAddress + * @related OscProperties + */ + public void setRemoteAddress(NetAddress theNetAddress) { + _myRemoteAddress = theNetAddress; + _mySendStatus = _myRemoteAddress.isvalid(); + } + + + /** + *set port number you are listening for incoming osc packets. + * @param thePort int + * @related OscProperties + */ + public void setListeningPort(final int thePort) { + _myListeningPort = thePort; + } + + + + /** + * set the size of the datagrampacket byte buffer. + * the default size is 1536 bytes. + * @param theSize int + * @related OscProperties + */ + public void setDatagramSize(final int theSize) { + if (!isLocked) { + _myDatagramSize = theSize; + } + else { + Logger.printWarning("OscProperties.setDatagramSize", + "datagram size can only be set before initializing oscP5\ncurrent datagram size is " + + _myDatagramSize); + } + } + + + + /** + * set the name of the default event method. + * the event method is the method to which incoming osc messages + * are forwarded. the default name for the event method is + * "oscEvent" + * @param theEventMethod String + * @related OscProperties + */ + public void setEventMethod(final String theEventMethod) { + _myDefaultEventMethodName = theEventMethod; + } + + + + /** + * set the network protocol over which osc messages are transmitted. + * options are OscProperties.UDP and OscProperties.MULTICAST + * the network protocol can only be set before initializing + * oscP5. + * @param theProtocol int + * @related OscProperties + * @related UDP + * @related TCP + * @related MULTICAST + * @related networkProtocol ( ) + */ + public void setNetworkProtocol(final int theProtocol) { + if (!isLocked) { + if (theProtocol > 2) { + Logger.printWarning("OscProperties.setNetworkProtocol", + "not in the range of supported Network protocols. the network protocol defaults to UDP"); + } + else { + _myNetworkProtocol = theProtocol; + } + } + else { + Logger.printWarning("OscProperties.setNetworkProtocol", + "network protocol can only be set before initializing oscP5."); + } + } + + + + /** + * SRSP stand for Send and Receive on Same Port. + * by default osc packets are not received and sent by the same port. + * if you need to send and receive on the same port call + * setSRSP(OscProperties.ON) + * @param theFlag boolean + * @related OscProperties + */ + public void setSRSP(final boolean theFlag) { + _mySRSP = theFlag; + } + + + + /** + * you can send and receive at the same port while on a udp con + * @return boolean + * @related OscProperties + */ + public boolean srsp() { + return _mySRSP; + } + + + + /** + * returns the port number currently used to receive osc packets. + * @return int + * @related OscProperties + */ + public int listeningPort() { + return _myListeningPort; + } + + + + /** + * returns a NetAddress of the remote host you are sending + * osc packets to. by default this is null. + * @return NetAddress + * @related OscProperties + */ + public NetAddress remoteAddress() { + return _myRemoteAddress; + } + + + + /** + * returns the current size of the datagram bytebuffer. + * @return int + * @related OscProperties + */ + public int datagramSize() { + return _myDatagramSize; + } + + + + /** + * + * @return String + * @related OscProperties + */ + public String eventMethod() { + return _myDefaultEventMethodName; + } + + + + /** + * returns the network protocol being used to transmit osc packets. returns an int. + * 0 (UDP), 1 (MULTICAST), 2 (TCP) + * @return int + * @related OscProperties + */ + public int networkProtocol() { + return _myNetworkProtocol; + } + + + + /** + * prints out the current osc properties settings. + * @return String + * @related OscProperties + */ + public String toString() { + String s = "\nnetwork protocol: " + (_myProtocols[_myNetworkProtocol]) + + "\n"; + s += "host: " + ((_myRemoteAddress.address()!=null) ? _myRemoteAddress.address():"host address not set.") + "\n"; + s += "sendToPort: " + _myRemoteAddress.port() + "\n"; + s += "receiveAtPort: " + listeningPort() + "\n"; + s += "datagramSize: " + _myDatagramSize + "\n"; + s += "event Method: " + _myDefaultEventMethodName + "\n"; + s += "(S)end(R)eceive(S)ame(P)ort: " + this._mySRSP + "\n\n"; + return s; + } + +} diff --git a/libraries/oscP5/src/oscP5/OscStatus.java b/libraries/oscP5/src/oscP5/OscStatus.java new file mode 100644 index 0000000..9744a98 --- /dev/null +++ b/libraries/oscP5/src/oscP5/OscStatus.java @@ -0,0 +1,63 @@ +/** + * An OSC (Open Sound Control) library for processing. + * + * (c) 2004-2012 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Schlegel http://www.sojamo.de + * @modified 12/23/2012 + * @version 0.9.9 + */ + +package oscP5; + +public class OscStatus { + + + public static int ERROR = -1; + + public static int DEFAULT = 0; + + public static int CONNECTION_CLOSED = 1; + + public static int CONNECTION_REFUSED = 2; + + public static int CONNECTION_TERMINATED = 4; + + public static int CONNECTION_FAILED = 8; + + public static int SERVER_CLOSED = 16; + + public static int CLIENT_CLOSED = 32; + + public static int SEND_FAILED = 64; + + public static int OSCP5_CLOSED = 1024; + + private int _myIndex = DEFAULT; + + + public OscStatus(int theIndex) { + _myIndex = theIndex; + } + + + public int id() { + return _myIndex; + } + +} |