@@ -0,0 +1,2832 @@
+package net.nitroshare.android.transfer;%0A%0Aimport java.io.IOException;%0Aimport java.nio.ByteBuffer;%0Aimport java.nio.ByteOrder;%0Aimport java.nio.channels.SocketChannel;%0A%0A/**%0A * Individual packet of information in a transfer%0A *%0A * Transfers are (at a high level) essentially a stream of packets being%0A * exchanged back and forth. The packet format is described here:%0A * https://goo.gl/fL890p%0A */%0Aclass Packet %7B%0A%0A    /**%0A     * Transfer succeeded%0A     *%0A     * This packet is sent by the receiver to indicate the transfer succeeded%0A     * and the connection may be closed.%0A     */%0A    public static final int SUCCESS = 0;%0A%0A    /**%0A     * Transfer failed%0A     *%0A     * This packet is sent by either end to indicate an error. The content of%0A     * packet describes the error.%0A     */%0A    public static final int ERROR = 1;%0A%0A    /**%0A     * JSON data%0A     */%0A    public static final int JSON = 2;%0A%0A    /**%0A     * Binary data%0A     */%0A    public static final int BINARY = 3;%0A%0A    private int mType;%0A    private ByteBuffer mBuffer;%0A    private boolean mHaveSize = false;%0A%0A    /**%0A     * Retrieve the packet type%0A     * @return packet type%0A     */%0A    public int getType() %7B%0A        return mType;%0A    %7D%0A%0A    /**%0A     * Retrieve the buffer for the packet%0A     * @return byte array%0A     */%0A    public ByteBuffer getBuffer() %7B%0A        return mBuffer;%0A    %7D%0A%0A    /**%0A     * Determine if the buffer is full%0A     * @return true if full%0A     */%0A    public boolean isFull() %7B%0A        return mBuffer.position() == mBuffer.capacity();%0A    %7D%0A%0A    /**%0A     * Create an empty packet of the specified type%0A     * @param type%0A     */%0A    public Packet(int type) %7B%0A        mType = type;%0A        mBuffer = ByteBuffer.allocate(5);%0A        mBuffer.order(ByteOrder.LITTLE_ENDIAN);%0A    %7D%0A%0A    /**%0A     * Create a packet of the specified type with the specified data%0A     */%0A    public Packet(int type, byte%5B%5D data) %7B%0A        mBuffer = ByteBuffer.allocate(5 + data.length);%0A        mBuffer.order(ByteOrder.LITTLE_ENDIAN);%0A        mBuffer.putInt(data.length + 1).put((byte) mType).put(data);%0A    %7D%0A%0A    /**%0A     * Read a packet from a socket channel%0A     * @param socketChannel%0A     */%0A    public void read(SocketChannel socketChannel) throws IOException %7B%0A%0A        // If the 32-bit size hasn't yet been read, do so%0A        if (!mHaveSize) %7B%0A            socketChannel.read(mBuffer);%0A            if (mBuffer.position() != 5) %7B%0A                return;%0A            %7D%0A%0A            // Remaining data is 8-bit type and data%0A            mBuffer.flip();%0A            int size = mBuffer.getInt() - 1;%0A            mType = mBuffer.get();%0A            mBuffer = ByteBuffer.allocate(size);%0A            mBuffer.order(ByteOrder.LITTLE_ENDIAN);%0A            mHaveSize = true;%0A        %7D%0A%0A        // The size is known, read data into the buffer%0A        socketChannel.read(mBuffer);%0A    %7D%0A%7D%0A

Add Packet class.