/* * Copyright (c) 2010 Remko Tronçon * All rights reserved. */ /* * Copyright (c) 2010-2012, Isode Limited, London, England. * All rights reserved. */ package com.isode.stroke.network; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.isode.stroke.base.ByteArray; import com.isode.stroke.eventloop.Event.Callback; import com.isode.stroke.eventloop.EventLoop; import com.isode.stroke.eventloop.EventOwner; public class JavaConnection extends Connection implements EventOwner { private class Worker implements Runnable { private final HostAddressPort address_; private final List writeBuffer_ = Collections.synchronizedList(new ArrayList()); public Worker(HostAddressPort address) { address_ = address; } public void run() { try { socketChannel_ = SocketChannel.open( new InetSocketAddress(address_.getAddress().getInetAddress(),address_.getPort())); /* By default, SocketChannels start off in blocking mode, which * isn't what we want */ socketChannel_.configureBlocking(false); } catch (IOException ex) { handleConnected(true); return; } handleConnected(false); while (!disconnecting_) { while (!writeBuffer_.isEmpty()) { ByteArray data = writeBuffer_.get(0); ByteBuffer byteBuffer = ByteBuffer.wrap(data.getData()); try { /* Because the SocketChannel is non-blocking, we have to * be prepared to cope with the write operation not * consuming all of the data */ boolean finishedWriting = false; while (!finishedWriting && !disconnecting_) { socketChannel_.write(byteBuffer); finishedWriting = (byteBuffer.remaining() == 0); if (!finishedWriting) { try { /* Give the output buffer a chance to empty */ Thread.sleep(100); } catch (InterruptedException e) { /* Perhaps someone has set disconnecting_ */ } } } } catch (IOException ex) { disconnecting_ = true; handleDisconnected(Error.WriteError); } writeBuffer_.remove(0); } ByteArray data = new ByteArray(); try { ByteBuffer byteBuffer = ByteBuffer.allocate(1024); int count = socketChannel_.read(byteBuffer); while (count > 0) { byteBuffer.flip(); byte[] result = new byte[byteBuffer.remaining()]; byteBuffer.get(result); byteBuffer.compact(); for (int i=0; i