package org.kne.io;

import java.io.EOFException;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;


public class KNEChannels {
	public static class ByteBufferWritableByteChannel implements WritableByteChannel{
		private ByteBuffer bbf;
		
		public ByteBuffer getBbf() {
			return bbf;
		}
		public ByteBufferWritableByteChannel(ByteBuffer bbf) {
			this.bbf=bbf;
		}
		@Override
		public boolean isOpen() {
			return true;
		}
		
		@Override
		public void close() throws IOException {
			
		}
		
		@Override
		public int write(ByteBuffer src) throws IOException {
			int opos=src.position();
			//System.out.println(bbf+" "+src);
			//FastLib .bufferPut(bbf,src);
			try {
			bbf.put(src);
			}catch(BufferOverflowException e) {
				throw new IOException(src.toString()+" "+bbf.toString(), e);
			}
			return src.position()-opos;
		}
	}
	public static WritableByteChannel newWritableChannel(ByteBuffer bbf) {
		return new ByteBufferWritableByteChannel(bbf);
	}
	public static class ByteBufferReadableByteChannel implements ReadableByteChannel {
		private ByteBuffer bbf;
		
		public ByteBuffer getBbf() {
			return bbf;
		}
		public ByteBufferReadableByteChannel(ByteBuffer bbf) {
			this.bbf=bbf;
		}
		@Override
		public boolean isOpen() {
			return true;
		}
		
		@Override
		public void close() throws IOException {
		}
		
		@Override
		public int read(ByteBuffer dst) throws IOException {
			if(!bbf.hasRemaining()) {
				return -1;
			}
			int lmtl=Math.min(bbf.remaining() ,dst.remaining());
			int olm=bbf.limit();
			bbf.limit(bbf.position()+lmtl);
			dst.put(bbf);
			bbf.limit(olm);
			return lmtl;
		}
	}
	public static ReadableByteChannel newReadableChannel(ByteBuffer bbf) {
		return new ByteBufferReadableByteChannel(bbf);
	}
	public static void readFully(ReadableByteChannel connectSocket, ByteBuffer szeRead) throws EOFException, IOException {
		while (szeRead.hasRemaining()) {
			if (connectSocket.read(szeRead) == -1) {
				throw new EOFException();
			}
		}
	}
}
