// Path: src/main/java/com/wizzardo/epoll/readable/ReadableByteArray.java
// public class ReadableByteArray extends ReadableData {
//     protected byte[] bytes;
//     protected int offset, length, position;
// 
//     public ReadableByteArray(byte[] bytes) {
//         this(bytes, 0, bytes.length);
//     }
// 
//     public ReadableByteArray(byte[] bytes, int offset, int length) {
//         this.bytes = bytes;
//         this.offset = offset;
//         this.length = length;
//         position = offset;
//     }
// 
//     @Override
//     public int read(ByteBuffer byteBuffer) {
//         int r = Math.min(byteBuffer.remaining(), length + offset - position);
//         byteBuffer.put(bytes, position, r);
//         position += r;
//         return r;
//     }
// 
//     @Override
//     public void unread(int i) {
//         if (i < 0)
//             throw new IllegalArgumentException("can't unread negative value: " + i);
//         if (position - i < offset)
//             throw new IllegalArgumentException("can't unread value bigger than offset (" + offset + "): " + i);
//         position -= i;
//     }
// 
//     @Override
//     public boolean isComplete() {
//         return length == position - offset;
//     }
// 
//     @Override
//     public long complete() {
//         return position - offset;
//     }
// 
//     @Override
//     public long length() {
//         return length;
//     }
// 
//     public long remains() {
//         return length + offset - position;
//     }
// 
//     @Override
//     public String toString() {
//         return new String(bytes, offset, length);
//     }
// }


import com.wizzardo.epoll.readable.ReadableByteArray;
import com.wizzardo.tools.io.BytesTools;
import java.nio.ByteBuffer;
package com.wizzardo.epoll.sized;



/**
 * @author: wizzardo
 * Date: 3/1/14
 */
public class ReadableByteArrayWithSize extends ReadableByteArray {

    private ReadableByteArray size;

    public ReadableByteArrayWithSize(byte[] bytes) {
        this(bytes, 0, bytes.length);
    }

    public ReadableByteArrayWithSize(byte[] bytes, int offset, int length) {
        super(bytes, offset, length);
        size = new ReadableByteArray(BytesTools.toBytes(length));
    }

    @Override
    public int read(ByteBuffer byteBuffer) {
        if (size.isComplete())
            return super.read(byteBuffer);

        int r = size.read(byteBuffer);
        if (!size.isComplete())
            return r;

        return r + super.read(byteBuffer);
    }

    @Override
    public void unread(int i) {
        if (i <= position)
            super.unread(i);
        else {
            i -= position;
            super.unread(position);
// Path: src/main/java/com/wizzardo/epoll/readable/ReadableByteArray.java
// public class ReadableByteArray extends ReadableData {
//     protected byte[] bytes;
//     protected int offset, length, position;
// 
//     public ReadableByteArray(byte[] bytes) {
//         this(bytes, 0, bytes.length);
//     }
// 
//     public ReadableByteArray(byte[] bytes, int offset, int length) {
//         this.bytes = bytes;
//         this.offset = offset;
//         this.length = length;
//         position = offset;
//     }
// 
//     @Override
//     public int read(ByteBuffer byteBuffer) {
//         int r = Math.min(byteBuffer.remaining(), length + offset - position);
//         byteBuffer.put(bytes, position, r);
//         position += r;
//         return r;
//     }
// 
//     @Override
//     public void unread(int i) {
//         if (i < 0)
//             throw new IllegalArgumentException("can't unread negative value: " + i);
//         if (position - i < offset)
//             throw new IllegalArgumentException("can't unread value bigger than offset (" + offset + "): " + i);
//         position -= i;
//     }
// 
//     @Override
//     public boolean isComplete() {
//         return length == position - offset;
//     }
// 
//     @Override
//     public long complete() {
//         return position - offset;
//     }
// 
//     @Override
//     public long length() {
//         return length;
//     }
// 
//     public long remains() {
//         return length + offset - position;
//     }
// 
//     @Override
//     public String toString() {
//         return new String(bytes, offset, length);
//     }
// }


// Path: src/main/java/com/wizzardo/epoll/sized/ReadableByteArrayWithSize.java
import com.wizzardo.epoll.readable.ReadableByteArray;
import com.wizzardo.tools.io.BytesTools;
import java.nio.ByteBuffer;

package com.wizzardo.epoll.sized;



/**
 * @author: wizzardo
 * Date: 3/1/14
 */
public class ReadableByteArrayWithSize extends ReadableByteArray {

    private ReadableByteArray size;

    public ReadableByteArrayWithSize(byte[] bytes) {
        this(bytes, 0, bytes.length);
    }

    public ReadableByteArrayWithSize(byte[] bytes, int offset, int length) {
        super(bytes, offset, length);
        size = new ReadableByteArray(BytesTools.toBytes(length));
    }

    @Override
    public int read(ByteBuffer byteBuffer) {
        if (size.isComplete())
            return super.read(byteBuffer);

        int r = size.read(byteBuffer);
        if (!size.isComplete())
            return r;

        return r + super.read(byteBuffer);
    }

    @Override
    public void unread(int i) {
        if (i <= position)
            super.unread(i);
        else {
            i -= position;
            super.unread(position);
            size.unread(i);