Class OSCPacketCodec


  • public class OSCPacketCodec
    extends Object
    A packet codec defines how the translation between Java objects and OSC atoms is accomplished. For example, by default, when an OSC message is assembled for transmission, the encoder will translate ajava.lang.Integer argument into a four byte integer with typetag 'i'. Or when a received message is being decoded, finding an atom typetagged 'f', the decoder will create a java.lang.Float out of it.

    This example sounds trivial, but the codec is also able to handle type conversions. For instance, in the strict OSC 1.0 specification, only 32bit numeric atoms are defined ('i' and 'f'). A codec with mode MODE_STRICT_V1 will reject a java.lang.Double in the encoding process and not be able to decode a typetag 'd'. A codec with mode MODE_MODEST automatically breaks down everything the 32bit, so a java.lang.Double gets encoded as 32bit 'f' and a received atom tagged 'd' becomes a java.lang.Float. Other configurations exist.

    Another important function of the codec is to specify the charset encoding of strings, something that was overseen in the OSC 1.0 spec. By default, UTF-8 is used so all special characters can be safely encoded.

    Last but not least, using the putDecoder and putEncoder methods, the codec can be extended to support additional Java classes or OSC typetags, without the need to subclass OSCPacketCodec.

    Since:
    NetUtil 0.35
    Version:
    0.36, 18-Feb-09
    Author:
    Hanns Holger Rutz
    • Field Detail

      • MODE_READ_DOUBLE_AS_FLOAT

        public static final int MODE_READ_DOUBLE_AS_FLOAT
        See Also:
        Constant Field Values
      • MODE_READ_LONG_AS_INTEGER

        public static final int MODE_READ_LONG_AS_INTEGER
        See Also:
        Constant Field Values
      • MODE_WRITE_DOUBLE_AS_FLOAT

        public static final int MODE_WRITE_DOUBLE_AS_FLOAT
        See Also:
        Constant Field Values
      • MODE_WRITE_LONG_AS_INTEGER

        public static final int MODE_WRITE_LONG_AS_INTEGER
        See Also:
        Constant Field Values
      • MODE_READ_SYMBOL_AS_STRING

        public static final int MODE_READ_SYMBOL_AS_STRING
        See Also:
        Constant Field Values
      • MODE_WRITE_PACKET_AS_BLOB

        public static final int MODE_WRITE_PACKET_AS_BLOB
        See Also:
        Constant Field Values
      • MODE_STRICT_V1

        public static final int MODE_STRICT_V1
        Support mode: coder only accepts java.lang.Integer, java.lang.Float, java.lang.String, and byte[]. Decoder only accepts 'i', 'f', 's', and 'b'. Note that byte[] is used to represents blobs ('b').
        See Also:
        Constant Field Values
      • MODE_MODEST

        public static final int MODE_MODEST
        Support mode: like MODE_STRICT_V1, but coder additionally encodes java.lang.Long as a 'i', java.lang.Double as a 'f', and de.sciss.net.OSCPacket as a blob 'b'. The decoder decodes 'h' into java.lang.Integer, 'd' into java.lang.Float, and 'S' (Symbol) into java.lang.String.
        See Also:
        Constant Field Values
      • MODE_GRACEFUL

        public static final int MODE_GRACEFUL
        Support mode: like MODE_MODEST, that is, it will downgrade to 32bit in the encoding process, but decoding leaves 64bit values intact, so 'h' becomes java.lang.Long, and 'd' into java.lang.Double.
        See Also:
        Constant Field Values
      • MODE_FAT_V1

        public static final int MODE_FAT_V1
        Support mode: like MODE_STRICT_V1, but with additional 64bit support, that is a mutual mapping between 'h' <--> java.lang.Long, and 'd' <--> java.lang.Double. Also, 'S' (Symbol) is decoded into java.lang.String, and de.sciss.net.OSCPacket is encoded as a blob 'b'.
        See Also:
        Constant Field Values
      • charsetName

        protected String charsetName
    • Constructor Detail

      • OSCPacketCodec

        public OSCPacketCodec()
        Creates a new codec with MODE_GRACEFUL and UTF-8 encoding. Note that since a codec and be shared between OSCServer or OSCClient instances, usually you will just want to call getDefaultCodec!
        See Also:
        MODE_GRACEFUL, getDefaultCodec()
      • OSCPacketCodec

        public OSCPacketCodec​(int mode)
        Creates a new codec with a given support mode and UTF-8 encoding.
        Parameters:
        mode - the support mode flag field to use
      • OSCPacketCodec

        public OSCPacketCodec​(int mode,
                              String charset)
        Creates a new codec with a given support mode and a given charset for string encoding.
        Parameters:
        mode - the support mode flag mask to use
        charset - the name of the charset to use for string coding and decoding, like "UTF-8", "ISO-8859-1" etc.
        See Also:
        Charset
    • Method Detail

      • getDefaultCodec

        public static OSCPacketCodec getDefaultCodec()
        Queries the standard codec which is used in all implicit client and server creations. This codec adheres to the MODE_GRACEFUL scheme and uses UTF-8 string encoding.

        Note that although it is not recommended, it is possible to modify the returned codec. That means that upon your application launch, you could query the default codec and switch its behaviour, e.g. change the string charset, so all successive operations with the default codec will be subject to those customizations.

        Returns:
        the default codec
        See Also:
        MODE_GRACEFUL
      • setStringCharsetCodec

        public void setStringCharsetCodec​(String charsetName)
        Specifies the charset to use in string coding and decoding.
        Parameters:
        charsetName - the name of the charset, e.g. "UTF-8", "ISO-8859-1" etc.
        See Also:
        Charset
      • putDecoder

        public void putDecoder​(byte typeTag,
                               OSCPacketCodec.Atom a)
        Registers an atomic decoder with the packet codec. This decoder is called whenever an OSC message with the given typetag is encountered.
        Parameters:
        typeTag - the typetag which is to be decoded with the new Atom. typeTag must be in the ASCII value range 0 to 127.
        a - the decoder to use
        See Also:
        OSCPacketCodec.Atom
      • putEncoder

        public void putEncoder​(Class javaClass,
                               OSCPacketCodec.Atom a)
        Registers an atomic encoder with the packet codec. This encoder is called whenever an OSC message to be assembled contains an argument of the given Java class.
        Parameters:
        javaClass - the class for which the encoder is responsible
        a - the encoder to use
        See Also:
        OSCPacketCodec.Atom
      • setSupportMode

        public void setSupportMode​(int mode)
        Adjusts the support mode for type tag handling. Usually you specify the mode directly in the instantiation of OSCPacketCodec, but you can change it later using this method.
        Parameters:
        mode - the new mode to use. A flag field combination of MODE_READ_DOUBLE or MODE_READ_DOUBLE_AS_FLOAT etc., or a ready made combination such as MODE_FAT_V1.
        See Also:
        OSCPacketCodec( int )
      • decode

        public OSCPacket decode​(ByteBuffer b)
                         throws IOException
        Creates a new packet decoded from the ByteBuffer. This method tries to read a null terminated string at the beginning of the provided buffer. If it equals the bundle identifier, the decode of OSCBundle is called (which may recursively decode nested bundles), otherwise the one from OSCMessage.
        Parameters:
        b - ByteBuffer pointing right at the beginning of the packet. the buffer's limited should be set appropriately to allow the complete packet to be read. when the method returns, the buffer's position is right after the end of the packet.
        Returns:
        new decoded OSC packet
        Throws:
        IOException - in case some of the reading or decoding procedures failed.
        BufferUnderflowException - in case of a parsing error that causes the method to read past the buffer limit
        IllegalArgumentException - occurs in some cases of buffer underflow
      • encode

        public void encode​(OSCPacket p,
                           ByteBuffer b)
                    throws IOException
        Encodes the contents of this packet into the provided ByteBuffer, beginning at the buffer's current position. To write the encoded packet, you will typically call flip() on the buffer, then write() on the channel.
        Parameters:
        b - ByteBuffer pointing right at the beginning of the osc packet. buffer position will be right after the end of the packet when the method returns.
        Throws:
        IOException - in case some of the writing procedures failed.
      • getSize

        public int getSize​(OSCPacket p)
                    throws IOException
        Calculates and returns the packet's size in bytes
        Returns:
        the size of the packet in bytes, including the initial osc command and aligned to 4-byte boundary. this is the amount of bytes written by the encode method.
        Throws:
        IOException - if an error occurs during the calculation
      • getMessageSize

        protected int getMessageSize​(OSCMessage msg)
                              throws IOException
        Calculates the byte size of the encoded message
        Returns:
        the size of the OSC message in bytes
        Throws:
        IOException - if the message contains invalid arguments
      • decodeMessage

        protected OSCMessage decodeMessage​(String command,
                                           ByteBuffer b)
                                    throws IOException
        Creates a new message with arguments decoded from the ByteBuffer. Usually you call decode from the OSCPacket superclass which will invoke this method of it finds an OSC message.
        Parameters:
        b - ByteBuffer pointing right at the beginning of the type declaration section of the OSC message, i.e. the name was skipped before.
        Returns:
        new OSC message representing the received message described by the ByteBuffer.
        Throws:
        IOException - in case some of the reading or decoding procedures failed.
        BufferUnderflowException - in case of a parsing error that causes the method to read past the buffer limit
        IllegalArgumentException - occurs in some cases of buffer underflow
      • encodeMessage

        protected void encodeMessage​(OSCMessage msg,
                                     ByteBuffer b)
                              throws BufferOverflowException,
                                     IOException
        Encodes the message onto the given ByteBuffer, beginning at the buffer's current position. To write the encoded message, you will typically call flip() on the buffer, then write() on the channel.
        Parameters:
        b - ByteBuffer pointing right at the beginning of the osc packet. buffer position will be right after the end of the message when the method returns.
        Throws:
        IOException - in case some of the writing procedures failed (buffer overflow, illegal arguments).
        BufferOverflowException
      • readString

        public static String readString​(ByteBuffer b)
        Reads a null terminated string from the current buffer position
        Parameters:
        b - buffer to read from. position and limit must be set appropriately. new position will be right after the terminating zero byte when the method returns
        Throws:
        BufferUnderflowException - in case the string exceeds the provided buffer limit
      • terminateAndPadToAlign

        public static void terminateAndPadToAlign​(ByteBuffer b)
        Adds as many zero padding bytes as necessary to stop on a 4 byte alignment. if the buffer position is already on a 4 byte alignment when calling this function, another 4 zero padding bytes are added. buffer position will be on the new aligned boundary when return from this method
        Parameters:
        b - the buffer to pad
        Throws:
        BufferOverflowException - in case the padding exceeds the provided buffer limit
      • padToAlign

        public static void padToAlign​(ByteBuffer b)
        Adds as many zero padding bytes as necessary to stop on a 4 byte alignment. if the buffer position is already on a 4 byte alignment when calling this function, this method does nothing.
        Parameters:
        b - the buffer to align
        Throws:
        BufferOverflowException - in case the padding exceeds the provided buffer limit
      • skipToAlign

        public static void skipToAlign​(ByteBuffer b)
        Advances the current buffer position to an integer of four bytes. The position is not altered if it is already aligned to a four byte boundary.
        Parameters:
        b - the buffer to advance
        Throws:
        IllegalArgumentException - in case the skipping exceeds the provided buffer limit