private BigInteger readBigInteger(final Input rawInput, final int numBytes) { final byte[] myBytes = new byte[numBytes]; System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), myBytes, 0, numBytes); rawInput.addToStreamPosition(numBytes); return new BigInteger(myBytes); }
/** * Reads a string from the byte stream. * @return the next string in the byte stream */ private String readString(final Input rawInput) { final int strLen = lengthOfCurrentString(rawInput); final String res = new String(rawInput.getBytes(), rawInput.getStreamPosition(), strLen, charset); rawInput.addToStreamPosition(strLen); moveToFourByteBoundry(rawInput); return res; }
/** * Converts the byte array to a bundle. * Assumes that the byte array is a bundle. * @return a bundle containing the data specified in the byte stream */ private OSCBundle convertBundle(final Input rawInput) { // skip the "#bundle " stuff rawInput.addToStreamPosition(BUNDLE_START.length() + 1); final Date timestamp = readTimeTag(rawInput); final OSCBundle bundle = new OSCBundle(timestamp); final OSCByteArrayToJavaConverter myConverter = new OSCByteArrayToJavaConverter(); myConverter.setCharset(charset); while (rawInput.getStreamPosition() < rawInput.getBytesLength()) { // recursively read through the stream and convert packets you find final int packetLength = readInteger(rawInput); if (packetLength == 0) { throw new IllegalArgumentException("Packet length may not be 0"); } else if ((packetLength % 4) != 0) { throw new IllegalArgumentException("Packet length has to be a multiple of 4, is:" + packetLength); } final byte[] packetBytes = new byte[packetLength]; System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), packetBytes, 0, packetLength); rawInput.addToStreamPosition(packetLength); final OSCPacket packet = myConverter.convert(packetBytes, packetLength); bundle.addPacket(packet); } return bundle; }
/** * Reads the types of the arguments from the byte stream. * @return a char array with the types of the arguments, * or <code>null</code>, in case of no arguments */ private CharSequence readTypes(final Input rawInput) { final String typesStr; // The next byte should be a ',', but some legacy code may omit it // in case of no arguments, refering to "OSC Messages" in: // http://opensoundcontrol.org/spec-1_0 if (rawInput.getBytes().length <= rawInput.getStreamPosition()) { typesStr = NO_ARGUMENT_TYPES; } else if (rawInput.getBytes()[rawInput.getStreamPosition()] != ',') { // XXX should we not rather fail-fast -> throw exception? typesStr = NO_ARGUMENT_TYPES; } else { rawInput.getAndIncreaseStreamPositionByOne(); typesStr = readString(rawInput); } return typesStr; }
/** * Reads an unsigned integer (32 bit) from the byte stream. * This code is copied from {@see http://darksleep.com/player/JavaAndUnsignedTypes.html}, * which is licensed under the Public Domain. * @return single precision, unsigned integer (32 bit) wrapped in a 64 bit integer (long) */ private Long readUnsignedInteger(final Input rawInput) { final int firstByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()])); final int secondByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()])); final int thirdByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()])); final int fourthByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()])); return ((long) (firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte)) & 0xFFFFFFFFL; }
/** * Checks whether my byte array is a bundle. * From the OSC 1.0 specifications: * <quote> * The contents of an OSC packet must be either an OSC Message * or an OSC Bundle. The first byte of the packet's contents unambiguously * distinguishes between these two alternatives. * </quote> * @return true if it the byte array is a bundle, false o.w. */ private boolean isBundle(final Input rawInput) { // The shortest valid packet may be no shorter then 4 bytes, // thus we may assume to always have a byte at index 0. return rawInput.getBytes()[0] == BUNDLE_IDENTIFIER; }
/** * Reads a char from the byte stream. * @return a {@link Character} */ private Character readChar(final Input rawInput) { return (char) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()]; }
/** * Reads a binary blob from the byte stream. * @return the next blob in the byte stream */ private byte[] readBlob(final Input rawInput) { final int blobLen = readInteger(rawInput); final byte[] res = new byte[blobLen]; System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), res, 0, blobLen); rawInput.addToStreamPosition(blobLen); moveToFourByteBoundry(rawInput); return res; }
/** * Get the length of the string currently in the byte stream. */ private int lengthOfCurrentString(final Input rawInput) { int len = 0; while (rawInput.getBytes()[rawInput.getStreamPosition() + len] != 0) { len++; } return len; }