package org.torrent.internal.transfer; import java.io.IOException; import java.nio.ByteBuffer; import java.util.logging.Logger; import org.torrent.internal.data.BTPart; import org.torrent.internal.data.TorrentMetaInfo; import org.torrent.internal.io.NBDataReader; import org.torrent.internal.peer.connection.BTConnection; import org.torrent.internal.protocol.message.BTMessageVisitorAdapter; import org.torrent.internal.protocol.message.BittorrentMessage; import org.torrent.internal.protocol.message.Piece; import org.torrent.internal.protocol.message.Request; import org.torrent.internal.util.Validator; public class UploadSlot extends BTSessionListenerAdapter { private static final Logger LOG = Logger.getLogger(UploadSlot.class .getName()); private BTConnection activeUpload; private final NBDataReader reader; private final TorrentMetaInfo contentInfo; public UploadSlot(BTSession session, NBDataReader reader, TorrentMetaInfo contentInfo) { Validator.nonNull(session, reader, contentInfo); this.reader = reader; this.contentInfo = contentInfo; session.addBTSessionListener(this); } @Override public synchronized void receivedBTMessage(final BTConnection from, BittorrentMessage message) { if (!from.equals(activeUpload)) { return; } message.accept(new BTMessageVisitorAdapter() { @Override public void visitRequest(final Request request) { send(); } }); } private synchronized void send() { BTPart item = activeUpload.takeRemoteRequest(); if (item == null) { return; } final BTPart info = item; final BTConnection target = activeUpload; reader.read(ByteBuffer.allocate(info.getLength()), contentInfo .getAbsoluteStart(info), new NBDataReader.Callback() { @Override public void caughtException(IOException e) { LOG.info(e.getLocalizedMessage()); } @Override public void read(final ByteBuffer dst, long position) { dst.flip(); target.send(new Piece(info, dst), null); } }); } public synchronized BTConnection getSlotTarget() { return activeUpload; } public synchronized void setSlotTo(BTConnection con) { if (activeUpload != null) { if (activeUpload.isConnectionEstablished() && !activeUpload.getMyPeerStatus().isChoking()) { activeUpload.sendChoked(true); } } activeUpload = con; if (activeUpload != null) { LOG.finer("Now uploading to " + con); if (activeUpload.getMyPeerStatus().isChoking()) { activeUpload.sendChoked(false); } if (activeUpload != null) { send(); } } } @Override public synchronized void sentBTMessage(BTConnection from, BittorrentMessage message) { if (from == activeUpload && from.hasNoPending()) { send(); } } }