// Path: src/main/java/com/wizzardo/epoll/ByteBufferProvider.java
// public interface ByteBufferProvider {
//     ByteBufferWrapper getBuffer();
// 
//     /**
//      * @return result of casting Thread.currentThread() to {@link ByteBufferProvider}
//      * @throws ClassCastException if current thread doesn't implement {@link ByteBufferProvider}
//      **/
//     static ByteBufferProvider current() {
//         return (ByteBufferProvider) Thread.currentThread();
//     }
// }
// 
// Path: src/main/java/com/wizzardo/epoll/ByteBufferWrapper.java
// public class ByteBufferWrapper {
// 
//     private final ByteBuffer buffer;
//     private int offset = 0;
// 
//     public final long address;
// 
//     public ByteBufferWrapper(ByteBuffer buffer) {
//         if (!buffer.isDirect())
//             throw new IllegalArgumentException("byte buffer must be direct");
// 
//         this.buffer = buffer;
//         address = EpollCore.address(buffer);
//     }
// 
//     public ByteBufferWrapper(ReadableData data) {
//         this.buffer = ByteBuffer.allocateDirect((int) data.length());
//         address = EpollCore.address(buffer);
//         data.read(buffer);
//         flip();
//     }
// 
//     public ByteBufferWrapper(int length) {
//         this.buffer = ByteBuffer.allocateDirect(length);
//         address = EpollCore.address(buffer);
//     }
// 
//     public ByteBufferWrapper(byte[] bytes) {
//         this(bytes, 0, bytes.length);
//     }
// 
//     public ByteBufferWrapper(byte[] bytes, int offset, int length) {
//         this.buffer = ByteBuffer.allocateDirect(length);
//         address = EpollCore.address(buffer);
//         put(bytes, offset, length);
//         flip();
//     }
// 
//     public int limit() {
//         return buffer.limit();
//     }
// 
//     public ByteBufferWrapper position(int r) {
//         buffer.position(r);
//         return this;
//     }
// 
//     public ByteBufferWrapper flip() {
//         buffer.flip();
//         return this;
//     }
// 
//     public ByteBufferWrapper put(byte[] b, int offset, int l) {
//         buffer.put(b, offset, l);
//         return this;
//     }
// 
//     public int remaining() {
//         return buffer.remaining();
//     }
// 
//     public int position() {
//         return buffer.position();
//     }
// 
//     public void clear() {
//         buffer.clear();
//     }
// 
//     public ByteBuffer buffer() {
//         return buffer;
//     }
// 
//     public int capacity() {
//         return buffer.capacity();
//     }
// 
//     public int offset() {
//         return offset;
//     }
// 
//     public void offset(int offset) {
//         //TODO check usage of offset
//         this.offset = offset;
//     }
// 
//     @Override
//     public String toString() {
//         int position = buffer.position();
//         int limit = buffer.limit();
//         buffer.position(0);
//         buffer.limit(buffer.capacity());
//         byte[] bytes = new byte[buffer.limit()];
//         buffer.get(bytes);
// 
//         buffer.clear();
//         buffer.limit(limit);
//         buffer.position(position);
//         return new String(bytes);
//     }
// }


import com.wizzardo.epoll.ByteBufferProvider;
import com.wizzardo.epoll.ByteBufferWrapper;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
package com.wizzardo.epoll.readable;



/**
 * @author: wizzardo
 * Date: 2/27/14
 */
public abstract class ReadableData implements Closeable {

    public ByteBufferWrapper getByteBuffer(ByteBufferProvider bufferProvider) {
        return bufferProvider.getBuffer();
    }

    public void close() throws IOException {
    }

    public abstract int read(ByteBuffer byteBuffer);

    public int read(ByteBufferWrapper wrapper) {
        return read(wrapper.buffer());
    }

    public abstract void unread(int i);

    public abstract boolean isComplete();

    public abstract long complete();

    public abstract long length();

    public abstract long remains();

    public boolean hasOwnBuffer() {
// Path: src/main/java/com/wizzardo/epoll/ByteBufferProvider.java
// public interface ByteBufferProvider {
//     ByteBufferWrapper getBuffer();
// 
//     /**
//      * @return result of casting Thread.currentThread() to {@link ByteBufferProvider}
//      * @throws ClassCastException if current thread doesn't implement {@link ByteBufferProvider}
//      **/
//     static ByteBufferProvider current() {
//         return (ByteBufferProvider) Thread.currentThread();
//     }
// }
// 
// Path: src/main/java/com/wizzardo/epoll/ByteBufferWrapper.java
// public class ByteBufferWrapper {
// 
//     private final ByteBuffer buffer;
//     private int offset = 0;
// 
//     public final long address;
// 
//     public ByteBufferWrapper(ByteBuffer buffer) {
//         if (!buffer.isDirect())
//             throw new IllegalArgumentException("byte buffer must be direct");
// 
//         this.buffer = buffer;
//         address = EpollCore.address(buffer);
//     }
// 
//     public ByteBufferWrapper(ReadableData data) {
//         this.buffer = ByteBuffer.allocateDirect((int) data.length());
//         address = EpollCore.address(buffer);
//         data.read(buffer);
//         flip();
//     }
// 
//     public ByteBufferWrapper(int length) {
//         this.buffer = ByteBuffer.allocateDirect(length);
//         address = EpollCore.address(buffer);
//     }
// 
//     public ByteBufferWrapper(byte[] bytes) {
//         this(bytes, 0, bytes.length);
//     }
// 
//     public ByteBufferWrapper(byte[] bytes, int offset, int length) {
//         this.buffer = ByteBuffer.allocateDirect(length);
//         address = EpollCore.address(buffer);
//         put(bytes, offset, length);
//         flip();
//     }
// 
//     public int limit() {
//         return buffer.limit();
//     }
// 
//     public ByteBufferWrapper position(int r) {
//         buffer.position(r);
//         return this;
//     }
// 
//     public ByteBufferWrapper flip() {
//         buffer.flip();
//         return this;
//     }
// 
//     public ByteBufferWrapper put(byte[] b, int offset, int l) {
//         buffer.put(b, offset, l);
//         return this;
//     }
// 
//     public int remaining() {
//         return buffer.remaining();
//     }
// 
//     public int position() {
//         return buffer.position();
//     }
// 
//     public void clear() {
//         buffer.clear();
//     }
// 
//     public ByteBuffer buffer() {
//         return buffer;
//     }
// 
//     public int capacity() {
//         return buffer.capacity();
//     }
// 
//     public int offset() {
//         return offset;
//     }
// 
//     public void offset(int offset) {
//         //TODO check usage of offset
//         this.offset = offset;
//     }
// 
//     @Override
//     public String toString() {
//         int position = buffer.position();
//         int limit = buffer.limit();
//         buffer.position(0);
//         buffer.limit(buffer.capacity());
//         byte[] bytes = new byte[buffer.limit()];
//         buffer.get(bytes);
// 
//         buffer.clear();
//         buffer.limit(limit);
//         buffer.position(position);
//         return new String(bytes);
//     }
// }


// Path: src/main/java/com/wizzardo/epoll/readable/ReadableData.java
import com.wizzardo.epoll.ByteBufferProvider;
import com.wizzardo.epoll.ByteBufferWrapper;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;

package com.wizzardo.epoll.readable;



/**
 * @author: wizzardo
 * Date: 2/27/14
 */
public abstract class ReadableData implements Closeable {

    public ByteBufferWrapper getByteBuffer(ByteBufferProvider bufferProvider) {
        return bufferProvider.getBuffer();
    }

    public void close() throws IOException {
    }

    public abstract int read(ByteBuffer byteBuffer);

    public int read(ByteBufferWrapper wrapper) {
        return read(wrapper.buffer());
    }

    public abstract void unread(int i);

    public abstract boolean isComplete();

    public abstract long complete();

    public abstract long length();

    public abstract long remains();

    public boolean hasOwnBuffer() {
        return false;