diff --git a/.gitignore b/.gitignore index 72fd2a12d..51ff16e96 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ *.bak *~ *~ +/build/ diff --git a/src/main/java/com/turn/ttorrent/client/Client.java b/src/main/java/com/turn/ttorrent/client/Client.java index 00325f078..5000546c9 100644 --- a/src/main/java/com/turn/ttorrent/client/Client.java +++ b/src/main/java/com/turn/ttorrent/client/Client.java @@ -78,14 +78,14 @@ public class Client extends Observable implements Runnable, /** Peers unchoking frequency, in seconds. Current BitTorrent specification * recommends 10 seconds to avoid choking fibrilation. */ - private static final int UNCHOKING_FREQUENCY = 3; + protected static final int UNCHOKING_FREQUENCY = 3; /** Optimistic unchokes are done every 2 loop iterations, i.e. every * 2*UNCHOKING_FREQUENCY seconds. */ - private static final int OPTIMISTIC_UNCHOKE_ITERATIONS = 3; + protected static final int OPTIMISTIC_UNCHOKE_ITERATIONS = 3; - private static final int RATE_COMPUTATION_ITERATIONS = 2; - private static final int MAX_DOWNLOADERS_UNCHOKE = 4; + protected static final int RATE_COMPUTATION_ITERATIONS = 2; + protected static final int MAX_DOWNLOADERS_UNCHOKE = 4; public enum ClientState { WAITING, @@ -96,22 +96,22 @@ public enum ClientState { DONE; }; - private static final String BITTORRENT_ID_PREFIX = "-TO0042-"; + protected static final String BITTORRENT_ID_PREFIX = "-TO0042-"; - private SharedTorrent torrent; - private ClientState state; - private Peer self; + protected SharedTorrent torrent; + protected ClientState state; + protected Peer self; - private Thread thread; - private boolean stop; - private long seed; + protected Thread thread; + protected boolean stop; + protected long seed; - private ConnectionHandler service; - private Announce announce; - private ConcurrentMap peers; - private ConcurrentMap connected; + protected ConnectionHandler service; + protected Announce announce; + protected ConcurrentMap peers = new ConcurrentHashMap(); + protected ConcurrentMap connected = new ConcurrentHashMap(); - private Random random; + protected Random random = new Random(System.currentTimeMillis()); /** * Initialize the BitTorrent client. @@ -124,13 +124,9 @@ public Client(InetAddress address, SharedTorrent torrent) this.torrent = torrent; this.state = ClientState.WAITING; - String id = Client.BITTORRENT_ID_PREFIX + UUID.randomUUID() - .toString().split("-")[4]; + String id = clientId(); - // Initialize the incoming connection handler and register ourselves to - // it. - this.service = new ConnectionHandler(this.torrent, id, address); - this.service.register(this); + initializeConnectionHandler(address, id); this.self = new Peer( this.service.getSocketAddress() @@ -138,10 +134,8 @@ public Client(InetAddress address, SharedTorrent torrent) (short)this.service.getSocketAddress().getPort(), ByteBuffer.wrap(id.getBytes(Torrent.BYTE_ENCODING))); - // Initialize the announce request thread, and register ourselves to it - // as well. - this.announce = new Announce(this.torrent, this.self); - this.announce.register(this); + + initializeAnnounceRequest(); logger.info("BitTorrent client [{}] for {} started and " + "listening at {}:{}...", @@ -151,10 +145,32 @@ public Client(InetAddress address, SharedTorrent torrent) this.self.getIp(), this.self.getPort() }); + } - this.peers = new ConcurrentHashMap(); - this.connected = new ConcurrentHashMap(); - this.random = new Random(System.currentTimeMillis()); + /** + * @return The Id of the peer. This default implementation is _random_ and will + * return a different Id on each invocation. + */ + protected String clientId() { + String id = Client.BITTORRENT_ID_PREFIX + UUID.randomUUID() + .toString().split("-")[4]; + return id; + } + + /** + * Initialize the incoming connection handler and register ourselves to it. + */ + protected void initializeConnectionHandler(InetAddress address, String id) throws IOException { + this.service = new ConnectionHandler(this.torrent, id, address); + this.service.register(this); + } + + /** + * Initialize the announce request thread, and register ourselves to it as well. + */ + protected void initializeAnnounceRequest() { + this.announce = new Announce(this.torrent, this.self); + this.announce.register(this); } /** @@ -207,7 +223,7 @@ public Set getPeers() { * * @param state The new client state. */ - private synchronized void setState(ClientState state) { + protected synchronized void setState(ClientState state) { if (this.state != state) { this.setChanged(); } @@ -417,7 +433,7 @@ public void run() { /** * Close torrent and set final client state before signing off. */ - private void finish() { + protected void finish() { this.torrent.close(); // Determine final state @@ -483,7 +499,7 @@ public synchronized void info() { * seconds). *

*/ - private synchronized void resetPeerRates() { + protected synchronized void resetPeerRates() { for (SharingPeer peer : this.connected.values()) { peer.getDLRate().reset(); peer.getULRate().reset(); @@ -501,7 +517,7 @@ private synchronized void resetPeerRates() { * * @param search The {@link Peer} specification. */ - private SharingPeer getOrCreatePeer(Peer search) { + protected SharingPeer getOrCreatePeer(Peer search) { SharingPeer peer; synchronized (this.peers) { @@ -555,7 +571,7 @@ private SharingPeer getOrCreatePeer(Peer search) { * @return A SharingPeer comparator that can be used to sort peers based on * the download or upload rate we get from them. */ - private Comparator getPeerRateComparator() { + protected Comparator getPeerRateComparator() { if (ClientState.SHARING.equals(this.state)) { return new SharingPeer.DLRateComparator(); } else if (ClientState.SEEDING.equals(this.state)) { @@ -597,7 +613,7 @@ private Comparator getPeerRateComparator() { * * @param optimistic Whether to perform an optimistic unchoke as well. */ - private synchronized void unchokePeers(boolean optimistic) { + protected synchronized void unchokePeers(boolean optimistic) { // Build a set of all connected peers, we don't care about peers we're // not connected to. TreeSet bound = new TreeSet( @@ -932,7 +948,7 @@ public void handleIOException(SharingPeer peer, IOException ioe) { * * @see ClientShutdown */ - private synchronized void seed() { + protected synchronized void seed() { // Silently ignore if we're already seeding. if (ClientState.SEEDING.equals(this.getState())) { return; diff --git a/src/main/java/com/turn/ttorrent/client/ConnectionHandler.java b/src/main/java/com/turn/ttorrent/client/ConnectionHandler.java index 4653f9466..e98b9a688 100644 --- a/src/main/java/com/turn/ttorrent/client/ConnectionHandler.java +++ b/src/main/java/com/turn/ttorrent/client/ConnectionHandler.java @@ -82,20 +82,20 @@ public class ConnectionHandler implements Runnable { public static final int PORT_RANGE_START = 6881; public static final int PORT_RANGE_END = 6889; - private static final int OUTBOUND_CONNECTIONS_POOL_SIZE = 20; - private static final int OUTBOUND_CONNECTIONS_THREAD_KEEP_ALIVE_SECS = 10; + protected static final int OUTBOUND_CONNECTIONS_POOL_SIZE = 20; + protected static final int OUTBOUND_CONNECTIONS_THREAD_KEEP_ALIVE_SECS = 10; - private static final int CLIENT_KEEP_ALIVE_MINUTES = 3; + protected static final int CLIENT_KEEP_ALIVE_MINUTES = 3; - private SharedTorrent torrent; - private String id; - private ServerSocketChannel channel; - private InetSocketAddress address; + protected SharedTorrent torrent; + protected String id; + protected ServerSocketChannel channel; + protected InetSocketAddress address; - private Set listeners; - private ExecutorService executor; - private Thread thread; - private boolean stop; + protected Set listeners; + protected ExecutorService executor; + protected Thread thread; + protected boolean stop; /** * Create and start a new listening service for out torrent, reporting @@ -269,7 +269,7 @@ public void run() { * @return A textual representation (host:port) of the given * socket. */ - private String socketRepr(SocketChannel channel) { + protected String socketRepr(SocketChannel channel) { Socket s = channel.socket(); return String.format("%s:%d%s", s.getInetAddress().getHostName(), @@ -294,7 +294,7 @@ private String socketRepr(SocketChannel channel) { * * @param client The accepted client's socket channel. */ - private void accept(SocketChannel client) + protected void accept(SocketChannel client) throws IOException, SocketTimeoutException { try { logger.debug("New incoming connection, waiting for handshake..."); @@ -364,7 +364,7 @@ public void connect(SharingPeer peer) { * any peer ID is accepted (this is the case for incoming connections). * @return The validated handshake message object. */ - private Handshake validateHandshake(SocketChannel channel, byte[] peerId) + protected Handshake validateHandshake(SocketChannel channel, byte[] peerId) throws IOException, ParseException { ByteBuffer len = ByteBuffer.allocate(1); ByteBuffer data; @@ -411,7 +411,7 @@ private Handshake validateHandshake(SocketChannel channel, byte[] peerId) * * @param channel The socket channel to the remote peer. */ - private int sendHandshake(SocketChannel channel) throws IOException { + protected int sendHandshake(SocketChannel channel) throws IOException { return channel.write( Handshake.craft( this.torrent.getInfoHash(), @@ -424,13 +424,13 @@ private int sendHandshake(SocketChannel channel) throws IOException { * @param channel The socket channel to the newly connected peer. * @param peerId The peer ID of the connected peer. */ - private void fireNewPeerConnection(SocketChannel channel, byte[] peerId) { + protected void fireNewPeerConnection(SocketChannel channel, byte[] peerId) { for (IncomingConnectionListener listener : this.listeners) { listener.handleNewPeerConnection(channel, peerId); } } - private void fireFailedConnection(SharingPeer peer, Throwable cause) { + protected void fireFailedConnection(SharingPeer peer, Throwable cause) { for (IncomingConnectionListener listener : this.listeners) { listener.handleFailedConnection(peer, cause); } @@ -443,9 +443,9 @@ private void fireFailedConnection(SharingPeer peer, Throwable cause) { * * @author mpetazzoni */ - private static class ConnectorThreadFactory implements ThreadFactory { + protected static class ConnectorThreadFactory implements ThreadFactory { - private int number = 0; + protected int number = 0; @Override public Thread newThread(Runnable r) { @@ -469,12 +469,12 @@ public Thread newThread(Runnable r) { * * @author mpetazzoni */ - private static class ConnectorTask implements Runnable { + protected static class ConnectorTask implements Runnable { - private final ConnectionHandler handler; - private final SharingPeer peer; + protected final ConnectionHandler handler; + protected final SharingPeer peer; - private ConnectorTask(ConnectionHandler handler, SharingPeer peer) { + protected ConnectorTask(ConnectionHandler handler, SharingPeer peer) { this.handler = handler; this.peer = peer; } diff --git a/src/main/java/com/turn/ttorrent/client/Handshake.java b/src/main/java/com/turn/ttorrent/client/Handshake.java index d6505d7a8..17620699d 100644 --- a/src/main/java/com/turn/ttorrent/client/Handshake.java +++ b/src/main/java/com/turn/ttorrent/client/Handshake.java @@ -36,7 +36,7 @@ public class Handshake { ByteBuffer infoHash; ByteBuffer peerId; - private Handshake(ByteBuffer data, ByteBuffer infoHash, + protected Handshake(ByteBuffer data, ByteBuffer infoHash, ByteBuffer peerId) { this.data = data; this.data.rewind(); diff --git a/src/main/java/com/turn/ttorrent/client/Piece.java b/src/main/java/com/turn/ttorrent/client/Piece.java index 5cd8534ac..0d912e68f 100644 --- a/src/main/java/com/turn/ttorrent/client/Piece.java +++ b/src/main/java/com/turn/ttorrent/client/Piece.java @@ -51,16 +51,16 @@ public class Piece implements Comparable { private static final Logger logger = LoggerFactory.getLogger(Piece.class); - private final TorrentByteStorage bucket; - private final int index; - private final long offset; - private final long length; - private final byte[] hash; - private final boolean seeder; + protected final TorrentByteStorage bucket; + protected final int index; + protected final long offset; + protected final long length; + protected final byte[] hash; + protected final boolean seeder; - private volatile boolean valid; - private int seen; - private ByteBuffer data; + protected volatile boolean valid; + protected int seen; + protected ByteBuffer data; /** * Initialize a new piece in the byte bucket. @@ -183,7 +183,7 @@ public synchronized boolean validate() throws IOException { * @throws IOException If the read can't be completed (I/O error, or EOF * reached, which can happen if the piece is not complete). */ - private ByteBuffer _read(long offset, long length) throws IOException { + protected ByteBuffer _read(long offset, long length) throws IOException { if (offset + length > this.length) { throw new IllegalArgumentException("Piece#" + this.index + " overrun (" + offset + " + " + length + " > " + diff --git a/src/main/java/com/turn/ttorrent/client/SharedTorrent.java b/src/main/java/com/turn/ttorrent/client/SharedTorrent.java index 111404712..95e7b3aec 100644 --- a/src/main/java/com/turn/ttorrent/client/SharedTorrent.java +++ b/src/main/java/com/turn/ttorrent/client/SharedTorrent.java @@ -74,34 +74,34 @@ public class SharedTorrent extends Torrent implements PeerActivityListener { * torrent is over this value. *

*/ - private static final float ENG_GAME_COMPLETION_RATIO = 0.95f; + protected static final float ENG_GAME_COMPLETION_RATIO = 0.95f; /** Default Request Strategy. * * Use the rarest-first strategy by default. */ - private static final RequestStrategy DEFAULT_REQUEST_STRATEGY = new RequestStrategyImplRarest(); + protected static final RequestStrategy DEFAULT_REQUEST_STRATEGY = new RequestStrategyImplRarest(); - private boolean stop; + protected boolean stop; - private long uploaded; - private long downloaded; - private long left; + protected long uploaded; + protected long downloaded; + protected long left; - private final TorrentByteStorage bucket; + protected final TorrentByteStorage bucket; - private final int pieceLength; - private final ByteBuffer piecesHashes; + protected final int pieceLength; + protected final ByteBuffer piecesHashes; - private boolean initialized; - private Piece[] pieces; - private SortedSet rarest; - private BitSet completedPieces; - private BitSet requestedPieces; - private RequestStrategy requestStrategy; + protected boolean initialized; + protected Piece[] pieces; + protected SortedSet rarest; + protected BitSet completedPieces; + protected BitSet requestedPieces; + protected RequestStrategy requestStrategy; - private double maxUploadRate = 0.0; - private double maxDownloadRate = 0.0; + protected double maxUploadRate = 0.0; + protected double maxDownloadRate = 0.0; /** * Create a new shared torrent from a base Torrent object. * @@ -445,7 +445,7 @@ public synchronized void init() throws InterruptedException, IOException { * * @param results The list of {@link Future}s of pieces to process. */ - private void validatePieces(List> results) + protected void validatePieces(List> results) throws IOException { try { for (Future task : results) { diff --git a/src/main/java/com/turn/ttorrent/client/announce/Announce.java b/src/main/java/com/turn/ttorrent/client/announce/Announce.java index 0146b011f..2a582da41 100644 --- a/src/main/java/com/turn/ttorrent/client/announce/Announce.java +++ b/src/main/java/com/turn/ttorrent/client/announce/Announce.java @@ -52,23 +52,23 @@ public class Announce implements Runnable { protected static final Logger logger = LoggerFactory.getLogger(Announce.class); - private final Peer peer; + protected final Peer peer; /** The tiers of tracker clients matching the tracker URIs defined in the * torrent. */ - private final List> clients; - private final Set allClients; + protected final List> clients; + protected final Set allClients; /** Announce thread and control. */ - private Thread thread; - private boolean stop; - private boolean forceStop; + protected Thread thread; + protected boolean stop; + protected boolean forceStop; /** Announce interval. */ - private int interval; + protected int interval; - private int currentTier; - private int currentClient; + protected int currentTier; + protected int currentClient; /** * Initialize the base announce class members for the announcer. @@ -268,7 +268,7 @@ public void run() { * @throws UnknownHostException If the tracker address is invalid. * @throws UnknownServiceException If the tracker protocol is not supported. */ - private TrackerClient createTrackerClient(SharedTorrent torrent, Peer peer, + protected TrackerClient createTrackerClient(SharedTorrent torrent, Peer peer, URI tracker) throws UnknownHostException, UnknownServiceException { String scheme = tracker.getScheme(); @@ -313,7 +313,7 @@ public TrackerClient getCurrentTrackerClient() throws AnnounceException { * * @throws AnnounceException */ - private void promoteCurrentTrackerClient() throws AnnounceException { + protected void promoteCurrentTrackerClient() throws AnnounceException { logger.trace("Promoting current tracker client for {} " + "(tier {}, position {} -> 0).", new Object[] { @@ -342,7 +342,7 @@ private void promoteCurrentTrackerClient() throws AnnounceException { * * @throws AnnounceException */ - private void moveToNextTrackerClient() throws AnnounceException { + protected void moveToNextTrackerClient() throws AnnounceException { int tier = this.currentTier; int client = this.currentClient + 1; @@ -377,7 +377,7 @@ private void moveToNextTrackerClient() throws AnnounceException { * @param hard Whether to force stop the announce thread or not, i.e. not * send the final 'stopped' announce request or not. */ - private void stop(boolean hard) { + protected void stop(boolean hard) { this.forceStop = hard; this.stop(); } diff --git a/src/main/java/com/turn/ttorrent/client/announce/HTTPTrackerClient.java b/src/main/java/com/turn/ttorrent/client/announce/HTTPTrackerClient.java index ae338afdf..324aecec9 100644 --- a/src/main/java/com/turn/ttorrent/client/announce/HTTPTrackerClient.java +++ b/src/main/java/com/turn/ttorrent/client/announce/HTTPTrackerClient.java @@ -164,7 +164,7 @@ public void announce(AnnounceRequestMessage.RequestEvent event, * @throws IOException * @throws MessageValidationException */ - private HTTPAnnounceRequestMessage buildAnnounceRequest( + protected HTTPAnnounceRequestMessage buildAnnounceRequest( AnnounceRequestMessage.RequestEvent event) throws UnsupportedEncodingException, IOException, MessageValidationException { diff --git a/src/main/java/com/turn/ttorrent/client/announce/TrackerClient.java b/src/main/java/com/turn/ttorrent/client/announce/TrackerClient.java index 7cfa0ece4..60645457d 100644 --- a/src/main/java/com/turn/ttorrent/client/announce/TrackerClient.java +++ b/src/main/java/com/turn/ttorrent/client/announce/TrackerClient.java @@ -29,7 +29,7 @@ public abstract class TrackerClient { /** The set of listeners to announce request answers. */ - private final Set listeners; + protected final Set listeners; protected final SharedTorrent torrent; protected final Peer peer; diff --git a/src/main/java/com/turn/ttorrent/client/announce/UDPTrackerClient.java b/src/main/java/com/turn/ttorrent/client/announce/UDPTrackerClient.java index 5df3229b0..14e49fb20 100644 --- a/src/main/java/com/turn/ttorrent/client/announce/UDPTrackerClient.java +++ b/src/main/java/com/turn/ttorrent/client/announce/UDPTrackerClient.java @@ -94,16 +94,16 @@ public class UDPTrackerClient extends TrackerClient { */ private static final int UDP_PACKET_LENGTH = 512; - private final InetSocketAddress address; - private final Random random; + protected final InetSocketAddress address; + protected final Random random; - private DatagramSocket socket; - private Date connectionExpiration; - private long connectionId; - private int transactionId; - private boolean stop; + protected DatagramSocket socket; + protected Date connectionExpiration; + protected long connectionId; + protected int transactionId; + protected boolean stop; - private enum State { + protected enum State { CONNECT_REQUEST, ANNOUNCE_REQUEST; }; @@ -265,7 +265,7 @@ protected void close() { } } - private UDPAnnounceRequestMessage buildAnnounceRequest( + protected UDPAnnounceRequestMessage buildAnnounceRequest( AnnounceRequestMessage.RequestEvent event) { return UDPAnnounceRequestMessage.craft( this.connectionId, @@ -293,7 +293,7 @@ private UDPAnnounceRequestMessage buildAnnounceRequest( * * @param message The incoming tracker message. */ - private void validateTrackerResponse(TrackerMessage message) + protected void validateTrackerResponse(TrackerMessage message) throws AnnounceException { if (message instanceof ErrorMessage) { throw new AnnounceException(((ErrorMessage)message).getReason()); @@ -311,7 +311,7 @@ private void validateTrackerResponse(TrackerMessage message) * @param message The message received from the tracker in response to the * connection request. */ - private void handleTrackerConnectResponse(TrackerMessage message) + protected void handleTrackerConnectResponse(TrackerMessage message) throws AnnounceException { this.validateTrackerResponse(message); @@ -335,7 +335,7 @@ private void handleTrackerConnectResponse(TrackerMessage message) * @param data The {@link ByteBuffer} to send in a datagram packet to the * tracker. */ - private void send(ByteBuffer data) { + protected void send(ByteBuffer data) { try { this.socket.send(new DatagramPacket( data.array(), @@ -354,7 +354,7 @@ private void send(ByteBuffer data) { * receive operation. * @return Returns a {@link ByteBuffer} containing the packet data. */ - private ByteBuffer recv(int attempt) + protected ByteBuffer recv(int attempt) throws IOException, SocketException, SocketTimeoutException { int timeout = UDP_BASE_TIMEOUT_SECONDS * (int)Math.pow(2, attempt); logger.trace("Setting receive timeout to {}s for attempt {}...", diff --git a/src/main/java/com/turn/ttorrent/client/peer/PeerExchange.java b/src/main/java/com/turn/ttorrent/client/peer/PeerExchange.java index 359bd2fed..e6109c18d 100644 --- a/src/main/java/com/turn/ttorrent/client/peer/PeerExchange.java +++ b/src/main/java/com/turn/ttorrent/client/peer/PeerExchange.java @@ -79,16 +79,16 @@ class PeerExchange { private static final int KEEP_ALIVE_IDLE_MINUTES = 2; - private SharingPeer peer; - private SharedTorrent torrent; - private SocketChannel channel; + protected SharingPeer peer; + protected SharedTorrent torrent; + protected SocketChannel channel; - private Set listeners; + protected Set listeners; private IncomingThread in; private OutgoingThread out; private BlockingQueue sendQueue; - private volatile boolean stop; + protected volatile boolean stop; /** * Initialize and start a new peer exchange. @@ -200,7 +200,7 @@ public void close() { * * @author ptgoetz */ - private abstract class RateLimitThread extends Thread { + protected abstract class RateLimitThread extends Thread { protected final Rate rate = new Rate(); protected long sleep = 1000; @@ -261,7 +261,7 @@ protected void rateLimit(double maxRate, long messageSize, PeerMessage message) * * @author mpetazzoni */ - private class IncomingThread extends RateLimitThread { + protected class IncomingThread extends RateLimitThread { /** * Read data from the incoming channel of the socket using a {@link @@ -272,7 +272,7 @@ private class IncomingThread extends RateLimitThread { * @param buffer A {@link ByteBuffer} to put the read data into. * @return The number of bytes read. */ - private long read(Selector selector, ByteBuffer buffer) throws IOException { + protected long read(Selector selector, ByteBuffer buffer) throws IOException { if (selector.select() == 0 || !buffer.hasRemaining()) { return 0; } @@ -294,7 +294,7 @@ private long read(Selector selector, ByteBuffer buffer) throws IOException { return size; } - private void handleIOE(IOException ioe) { + protected void handleIOE(IOException ioe) { logger.debug("Could not read message from {}: {}", peer, ioe.getMessage() != null diff --git a/src/main/java/com/turn/ttorrent/client/storage/FileCollectionStorage.java b/src/main/java/com/turn/ttorrent/client/storage/FileCollectionStorage.java index 6bb50d3b6..1732b8b57 100644 --- a/src/main/java/com/turn/ttorrent/client/storage/FileCollectionStorage.java +++ b/src/main/java/com/turn/ttorrent/client/storage/FileCollectionStorage.java @@ -43,8 +43,8 @@ public class FileCollectionStorage implements TorrentByteStorage { private static final Logger logger = LoggerFactory.getLogger(FileCollectionStorage.class); - private final List files; - private final long size; + protected final List files; + protected final long size; /** * Initialize a new multi-file torrent byte storage. @@ -140,7 +140,7 @@ public boolean isFinished() { * @author dgiffin * @author mpetazzoni */ - private static class FileOffset { + protected static class FileOffset { public final FileStorage file; public final long offset; @@ -172,7 +172,7 @@ private static class FileOffset { * @throws IllegalStateException If the files registered with this byte * storage can't accommodate the request (should not happen, really). */ - private List select(long offset, long length) { + protected List select(long offset, long length) { if (offset + length > this.size) { throw new IllegalArgumentException("Buffer overrun (" + offset + " + " + length + " > " + this.size + ") !"); diff --git a/src/main/java/com/turn/ttorrent/client/storage/FileStorage.java b/src/main/java/com/turn/ttorrent/client/storage/FileStorage.java index a47f053cb..ace8889b6 100644 --- a/src/main/java/com/turn/ttorrent/client/storage/FileStorage.java +++ b/src/main/java/com/turn/ttorrent/client/storage/FileStorage.java @@ -42,14 +42,14 @@ public class FileStorage implements TorrentByteStorage { private static final Logger logger = LoggerFactory.getLogger(FileStorage.class); - private final File target; - private final File partial; - private final long offset; - private final long size; - - private RandomAccessFile raf; - private FileChannel channel; - private File current; + protected final File target; + protected final File partial; + protected final long offset; + protected final long size; + + protected RandomAccessFile raf; + protected FileChannel channel; + protected File current; public FileStorage(File file, long size) throws IOException { this(file, 0, size); diff --git a/src/main/java/com/turn/ttorrent/client/strategy/RequestStrategyImplRarest.java b/src/main/java/com/turn/ttorrent/client/strategy/RequestStrategyImplRarest.java index 1bdc85920..08653716e 100644 --- a/src/main/java/com/turn/ttorrent/client/strategy/RequestStrategyImplRarest.java +++ b/src/main/java/com/turn/ttorrent/client/strategy/RequestStrategyImplRarest.java @@ -17,9 +17,9 @@ public class RequestStrategyImplRarest implements RequestStrategy { /** Randomly select the next piece to download from a peer from the * RAREST_PIECE_JITTER available from it. */ - private static final int RAREST_PIECE_JITTER = 42; + protected static final int RAREST_PIECE_JITTER = 42; - private Random random; + protected Random random; public RequestStrategyImplRarest() { this.random = new Random(System.currentTimeMillis()); diff --git a/src/main/java/com/turn/ttorrent/common/Peer.java b/src/main/java/com/turn/ttorrent/common/Peer.java index 86af9fcf0..a4860438c 100644 --- a/src/main/java/com/turn/ttorrent/common/Peer.java +++ b/src/main/java/com/turn/ttorrent/common/Peer.java @@ -34,11 +34,11 @@ */ public class Peer { - private final InetSocketAddress address; - private final String hostId; + protected final InetSocketAddress address; + protected final String hostId; - private ByteBuffer peerId; - private String hexPeerId; + protected ByteBuffer peerId; + protected String hexPeerId; /** * Instantiate a new peer. diff --git a/src/main/java/com/turn/ttorrent/common/Torrent.java b/src/main/java/com/turn/ttorrent/common/Torrent.java index 5829aaff1..f5bfd5ab3 100644 --- a/src/main/java/com/turn/ttorrent/common/Torrent.java +++ b/src/main/java/com/turn/ttorrent/common/Torrent.java @@ -604,7 +604,7 @@ public static Torrent create(File source, List files, int pieceLength, * @param createdBy The creator's name, or any string identifying the * torrent's creator. */ - private static Torrent create(File parent, List files, int pieceLength, + protected static Torrent create(File parent, List files, int pieceLength, URI announce, List> announceList, String createdBy) throws InterruptedException, IOException { if (files == null || files.isEmpty()) { @@ -716,12 +716,12 @@ public String call() throws UnsupportedEncodingException { * * @param file The file to hash. */ - private static String hashFile(File file, int pieceLenght) + protected static String hashFile(File file, int pieceLenght) throws InterruptedException, IOException { return Torrent.hashFiles(Arrays.asList(new File[] { file }), pieceLenght); } - private static String hashFiles(List files, int pieceLenght) + protected static String hashFiles(List files, int pieceLenght) throws InterruptedException, IOException { int threads = getHashingThreadsCount(); ExecutorService executor = Executors.newFixedThreadPool(threads); @@ -808,7 +808,7 @@ private static String hashFiles(List files, int pieceLenght) * @param results The list of {@link Future}s that will yield the piece * hashes. */ - private static int accumulateHashes(StringBuilder hashes, + protected static int accumulateHashes(StringBuilder hashes, List> results) throws InterruptedException, IOException { try { int pieces = results.size(); diff --git a/src/main/java/com/turn/ttorrent/common/protocol/PeerMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/PeerMessage.java index d9d01d31b..b9347369c 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/PeerMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/PeerMessage.java @@ -83,10 +83,10 @@ public static Type get(byte c) { } }; - private final Type type; - private final ByteBuffer data; + protected final Type type; + protected final ByteBuffer data; - private PeerMessage(Type type, ByteBuffer data) { + protected PeerMessage(Type type, ByteBuffer data) { this.type = type; this.data = data; this.data.rewind(); diff --git a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceRequestMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceRequestMessage.java index 3645573d0..6b49da5cc 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceRequestMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceRequestMessage.java @@ -48,17 +48,17 @@ public class HTTPAnnounceRequestMessage extends HTTPTrackerMessage implements AnnounceRequestMessage { - private final byte[] infoHash; - private final Peer peer; - private final long uploaded; - private final long downloaded; - private final long left; - private final boolean compact; - private final boolean noPeerId; - private final RequestEvent event; - private final int numWant; - - private HTTPAnnounceRequestMessage(ByteBuffer data, + protected final byte[] infoHash; + protected final Peer peer; + protected final long uploaded; + protected final long downloaded; + protected final long left; + protected final boolean compact; + protected final boolean noPeerId; + protected final RequestEvent event; + protected final int numWant; + + protected HTTPAnnounceRequestMessage(ByteBuffer data, byte[] infoHash, Peer peer, long uploaded, long downloaded, long left, boolean compact, boolean noPeerId, RequestEvent event, int numWant) { diff --git a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceResponseMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceResponseMessage.java index 01d27cd7f..6a624e111 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceResponseMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPAnnounceResponseMessage.java @@ -43,12 +43,12 @@ public class HTTPAnnounceResponseMessage extends HTTPTrackerMessage implements AnnounceResponseMessage { - private final int interval; - private final int complete; - private final int incomplete; - private final List peers; + protected final int interval; + protected final int complete; + protected final int incomplete; + protected final List peers; - private HTTPAnnounceResponseMessage(ByteBuffer data, + protected HTTPAnnounceResponseMessage(ByteBuffer data, int interval, int complete, int incomplete, List peers) { super(Type.ANNOUNCE_RESPONSE, data); this.interval = interval; @@ -128,7 +128,7 @@ public static HTTPAnnounceResponseMessage parse(ByteBuffer data) * @return A {@link List} of {@link Peer}s representing the * peers' addresses. Peer IDs are lost, but they are not crucial. */ - private static List toPeerList(List peers) + protected static List toPeerList(List peers) throws InvalidBEncodingException { List result = new LinkedList(); @@ -151,7 +151,7 @@ private static List toPeerList(List peers) * @return A {@link List} of {@link Peer}s representing the * peers' addresses. Peer IDs are lost, but they are not crucial. */ - private static List toPeerList(byte[] data) + protected static List toPeerList(byte[] data) throws InvalidBEncodingException, UnknownHostException { if (data.length % 6 != 0) { throw new InvalidBEncodingException("Invalid peers " + diff --git a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPTrackerErrorMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPTrackerErrorMessage.java index 96166ec65..9f4fffeaf 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPTrackerErrorMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/http/HTTPTrackerErrorMessage.java @@ -36,9 +36,9 @@ public class HTTPTrackerErrorMessage extends HTTPTrackerMessage implements ErrorMessage { - private final String reason; + protected final String reason; - private HTTPTrackerErrorMessage(ByteBuffer data, String reason) { + protected HTTPTrackerErrorMessage(ByteBuffer data, String reason) { super(Type.ERROR, data); this.reason = reason; } diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceRequestMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceRequestMessage.java index 3150ea890..599bf2d99 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceRequestMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceRequestMessage.java @@ -35,21 +35,21 @@ public class UDPAnnounceRequestMessage private static final int UDP_ANNOUNCE_REQUEST_MESSAGE_SIZE = 98; - private final long connectionId; - private final int actionId = Type.ANNOUNCE_REQUEST.getId(); - private final int transactionId; - private final byte[] infoHash; - private final byte[] peerId; - private final long downloaded; - private final long uploaded; - private final long left; - private final RequestEvent event; - private final InetAddress ip; - private final int numWant; - private final int key; - private final short port; - - private UDPAnnounceRequestMessage(ByteBuffer data, long connectionId, + protected final long connectionId; + protected final int actionId = Type.ANNOUNCE_REQUEST.getId(); + protected final int transactionId; + protected final byte[] infoHash; + protected final byte[] peerId; + protected final long downloaded; + protected final long uploaded; + protected final long left; + protected final RequestEvent event; + protected final InetAddress ip; + protected final int numWant; + protected final int key; + protected final short port; + + protected UDPAnnounceRequestMessage(ByteBuffer data, long connectionId, int transactionId, byte[] infoHash, byte[] peerId, long downloaded, long uploaded, long left, RequestEvent event, InetAddress ip, int key, int numWant, short port) { diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceResponseMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceResponseMessage.java index 612012d3b..4eab10101 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceResponseMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPAnnounceResponseMessage.java @@ -34,16 +34,16 @@ public class UDPAnnounceResponseMessage extends UDPTrackerMessage.UDPTrackerResponseMessage implements TrackerMessage.AnnounceResponseMessage { - private static final int UDP_ANNOUNCE_RESPONSE_MIN_MESSAGE_SIZE = 20; + protected static final int UDP_ANNOUNCE_RESPONSE_MIN_MESSAGE_SIZE = 20; - private final int actionId = Type.ANNOUNCE_RESPONSE.getId(); - private final int transactionId; - private final int interval; - private final int complete; - private final int incomplete; - private final List peers; + protected final int actionId = Type.ANNOUNCE_RESPONSE.getId(); + protected final int transactionId; + protected final int interval; + protected final int complete; + protected final int incomplete; + protected final List peers; - private UDPAnnounceResponseMessage(ByteBuffer data, int transactionId, + protected UDPAnnounceResponseMessage(ByteBuffer data, int transactionId, int interval, int complete, int incomplete, List peers) { super(Type.ANNOUNCE_REQUEST, data); this.transactionId = transactionId; diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectRequestMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectRequestMessage.java index b1b0c2ecb..33a4dd2bc 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectRequestMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectRequestMessage.java @@ -29,14 +29,14 @@ public class UDPConnectRequestMessage extends UDPTrackerMessage.UDPTrackerRequestMessage implements TrackerMessage.ConnectionRequestMessage { - private static final int UDP_CONNECT_REQUEST_MESSAGE_SIZE = 16; - private static final long UDP_CONNECT_REQUEST_MAGIC = 0x41727101980L; + protected static final int UDP_CONNECT_REQUEST_MESSAGE_SIZE = 16; + protected static final long UDP_CONNECT_REQUEST_MAGIC = 0x41727101980L; - private final long connectionId = UDP_CONNECT_REQUEST_MAGIC; - private final int actionId = Type.CONNECT_REQUEST.getId(); - private final int transactionId; + protected final long connectionId = UDP_CONNECT_REQUEST_MAGIC; + protected final int actionId = Type.CONNECT_REQUEST.getId(); + protected final int transactionId; - private UDPConnectRequestMessage(ByteBuffer data, int transactionId) { + protected UDPConnectRequestMessage(ByteBuffer data, int transactionId) { super(Type.CONNECT_REQUEST, data); this.transactionId = transactionId; } diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectResponseMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectResponseMessage.java index 0a9f4bf64..13a91e5c7 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectResponseMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPConnectResponseMessage.java @@ -29,13 +29,13 @@ public class UDPConnectResponseMessage extends UDPTrackerMessage.UDPTrackerResponseMessage implements TrackerMessage.ConnectionResponseMessage { - private static final int UDP_CONNECT_RESPONSE_MESSAGE_SIZE = 16; + protected static final int UDP_CONNECT_RESPONSE_MESSAGE_SIZE = 16; - private final int actionId = Type.CONNECT_RESPONSE.getId(); - private final int transactionId; - private final long connectionId; + protected final int actionId = Type.CONNECT_RESPONSE.getId(); + protected final int transactionId; + protected final long connectionId; - private UDPConnectResponseMessage(ByteBuffer data, int transactionId, + protected UDPConnectResponseMessage(ByteBuffer data, int transactionId, long connectionId) { super(Type.CONNECT_RESPONSE, data); this.transactionId = transactionId; diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerErrorMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerErrorMessage.java index 01bf567db..60f1039ce 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerErrorMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerErrorMessage.java @@ -31,13 +31,13 @@ public class UDPTrackerErrorMessage extends UDPTrackerMessage.UDPTrackerResponseMessage implements TrackerMessage.ErrorMessage { - private static final int UDP_TRACKER_ERROR_MIN_MESSAGE_SIZE = 8; + protected static final int UDP_TRACKER_ERROR_MIN_MESSAGE_SIZE = 8; - private final int actionId = Type.ERROR.getId(); - private final int transactionId; - private final String reason; + protected final int actionId = Type.ERROR.getId(); + protected final int transactionId; + protected final String reason; - private UDPTrackerErrorMessage(ByteBuffer data, int transactionId, + protected UDPTrackerErrorMessage(ByteBuffer data, int transactionId, String reason) { super(Type.ERROR, data); this.transactionId = transactionId; diff --git a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerMessage.java b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerMessage.java index afde16924..33604bf00 100644 --- a/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerMessage.java +++ b/src/main/java/com/turn/ttorrent/common/protocol/udp/UDPTrackerMessage.java @@ -26,7 +26,7 @@ */ public abstract class UDPTrackerMessage extends TrackerMessage { - private UDPTrackerMessage(Type type, ByteBuffer data) { + protected UDPTrackerMessage(Type type, ByteBuffer data) { super(type, data); } diff --git a/src/main/java/com/turn/ttorrent/tracker/TrackedPeer.java b/src/main/java/com/turn/ttorrent/tracker/TrackedPeer.java index f866580e8..082e60316 100644 --- a/src/main/java/com/turn/ttorrent/tracker/TrackedPeer.java +++ b/src/main/java/com/turn/ttorrent/tracker/TrackedPeer.java @@ -51,12 +51,12 @@ public class TrackedPeer extends Peer { private static final Logger logger = LoggerFactory.getLogger(TrackedPeer.class); - private static final int FRESH_TIME_SECONDS = 30; + protected static final int FRESH_TIME_SECONDS = 30; - private long uploaded; - private long downloaded; - private long left; - private Torrent torrent; + protected long uploaded; + protected long downloaded; + protected long left; + protected Torrent torrent; /** * Represents the state of a peer exchanging on this torrent. @@ -89,8 +89,8 @@ public enum PeerState { STOPPED; }; - private PeerState state; - private Date lastAnnounce; + protected PeerState state; + protected Date lastAnnounce; /** * Instantiate a new tracked peer for the given torrent. diff --git a/src/main/java/com/turn/ttorrent/tracker/TrackedTorrent.java b/src/main/java/com/turn/ttorrent/tracker/TrackedTorrent.java index 3e8e500d6..bb8304745 100644 --- a/src/main/java/com/turn/ttorrent/tracker/TrackedTorrent.java +++ b/src/main/java/com/turn/ttorrent/tracker/TrackedTorrent.java @@ -59,16 +59,16 @@ public class TrackedTorrent extends Torrent { public static final int MIN_ANNOUNCE_INTERVAL_SECONDS = 5; /** Default number of peers included in a tracker response. */ - private static final int DEFAULT_ANSWER_NUM_PEERS = 30; + protected static final int DEFAULT_ANSWER_NUM_PEERS = 30; /** Default announce interval requested from peers, in seconds. */ - private static final int DEFAULT_ANNOUNCE_INTERVAL_SECONDS = 10; + protected static final int DEFAULT_ANNOUNCE_INTERVAL_SECONDS = 10; - private int answerPeers; - private int announceInterval; + protected int answerPeers; + protected int announceInterval; /** Peers currently exchanging on this torrent. */ - private ConcurrentMap peers; + protected ConcurrentMap peers; /** * Create a new tracked torrent from meta-info binary data. diff --git a/src/main/java/com/turn/ttorrent/tracker/Tracker.java b/src/main/java/com/turn/ttorrent/tracker/Tracker.java index 638fae259..93dada9eb 100644 --- a/src/main/java/com/turn/ttorrent/tracker/Tracker.java +++ b/src/main/java/com/turn/ttorrent/tracker/Tracker.java @@ -59,15 +59,15 @@ public class Tracker { public static final String DEFAULT_VERSION_STRING = "BitTorrent Tracker (ttorrent)"; - private final Connection connection; - private final InetSocketAddress address; + protected final Connection connection; + protected final InetSocketAddress address; /** The in-memory repository of torrents tracked. */ - private final ConcurrentMap torrents; + protected final ConcurrentMap torrents; - private Thread tracker; - private Thread collector; - private boolean stop; + protected Thread tracker; + protected Thread collector; + protected boolean stop; /** * Create a new BitTorrent tracker listening at the given address on the @@ -243,10 +243,10 @@ public synchronized void remove(Torrent torrent, long delay) { * through a Timer. *

*/ - private static class TorrentRemoveTimer extends TimerTask { + protected static class TorrentRemoveTimer extends TimerTask { - private Tracker tracker; - private Torrent torrent; + protected Tracker tracker; + protected Torrent torrent; TorrentRemoveTimer(Tracker tracker, Torrent torrent) { this.tracker = tracker; @@ -269,7 +269,7 @@ public void run() { * socket. *

*/ - private class TrackerThread extends Thread { + protected class TrackerThread extends Thread { @Override public void run() { @@ -293,9 +293,9 @@ public void run() { * unfresh peers from all announced torrents. *

*/ - private class PeerCollectorThread extends Thread { + protected class PeerCollectorThread extends Thread { - private static final int PEER_COLLECTION_FREQUENCY_SECONDS = 15; + protected static final int PEER_COLLECTION_FREQUENCY_SECONDS = 15; @Override public void run() { diff --git a/src/main/java/com/turn/ttorrent/tracker/TrackerService.java b/src/main/java/com/turn/ttorrent/tracker/TrackerService.java index ae24cabd3..167b0aebd 100644 --- a/src/main/java/com/turn/ttorrent/tracker/TrackerService.java +++ b/src/main/java/com/turn/ttorrent/tracker/TrackerService.java @@ -68,14 +68,14 @@ public class TrackerService implements Container { * The list of announce request URL fields that need to be interpreted as * numeric and thus converted as such in the request message parsing. */ - private static final String[] NUMERIC_REQUEST_FIELDS = + protected static final String[] NUMERIC_REQUEST_FIELDS = new String[] { "port", "uploaded", "downloaded", "left", "compact", "no_peer_id", "numwant" }; - private final String version; - private final ConcurrentMap torrents; + protected final String version; + protected final ConcurrentMap torrents; /** @@ -135,7 +135,7 @@ public void handle(Request request, Response response) { * @param response The response object. * @param body The validated response body output stream. */ - private void process(Request request, Response response, + protected void process(Request request, Response response, OutputStream body) throws IOException { // Prepare the response headers. response.set("Content-Type", "text/plain"); @@ -251,7 +251,7 @@ private void process(Request request, Response response, * @return The {@link AnnounceRequestMessage} representing the client's * announce request. */ - private HTTPAnnounceRequestMessage parseQuery(Request request) + protected HTTPAnnounceRequestMessage parseQuery(Request request) throws IOException, MessageValidationException { Map params = new HashMap(); @@ -281,7 +281,7 @@ private HTTPAnnounceRequestMessage parseQuery(Request request) return HTTPAnnounceRequestMessage.parse(BEncoder.bencode(params)); } - private void recordParam(Map params, String key, + protected void recordParam(Map params, String key, String value) { try { value = URLDecoder.decode(value, TrackedTorrent.BYTE_ENCODING); @@ -309,7 +309,7 @@ private void recordParam(Map params, String key, * @param status The HTTP status code to return. * @param error The error reported by the tracker. */ - private void serveError(Response response, OutputStream body, + protected void serveError(Response response, OutputStream body, Status status, HTTPTrackerErrorMessage error) throws IOException { response.setCode(status.getCode()); response.setText(status.getDescription()); @@ -328,7 +328,7 @@ private void serveError(Response response, OutputStream body, * @param status The HTTP status code to return. * @param error The error message reported by the tracker. */ - private void serveError(Response response, OutputStream body, + protected void serveError(Response response, OutputStream body, Status status, String error) throws IOException { try { this.serveError(response, body, status, @@ -347,7 +347,7 @@ private void serveError(Response response, OutputStream body, * @param status The HTTP status code to return. * @param reason The failure reason reported by the tracker. */ - private void serveError(Response response, OutputStream body, + protected void serveError(Response response, OutputStream body, Status status, ErrorMessage.FailureReason reason) throws IOException { this.serveError(response, body, status, reason.getMessage()); } diff --git a/test/main/java/com/turn/ttorrent/client/storage/FileCollectionStorageTest.java b/test/main/java/com/turn/ttorrent/client/storage/FileCollectionStorageTest.java index 005013f2c..686c596b4 100644 --- a/test/main/java/com/turn/ttorrent/client/storage/FileCollectionStorageTest.java +++ b/test/main/java/com/turn/ttorrent/client/storage/FileCollectionStorageTest.java @@ -49,11 +49,11 @@ public void testSelect() throws Exception { check(new byte[]{102,11}, file2); } - private void write(byte[] bytes, int offset, FileCollectionStorage storage) throws IOException { + protected void write(byte[] bytes, int offset, FileCollectionStorage storage) throws IOException { storage.write(ByteBuffer.wrap(bytes), offset); storage.finish(); } - private void check(byte[] bytes, File f) throws IOException { + protected void check(byte[] bytes, File f) throws IOException { final byte[] temp = new byte[bytes.length]; assertEquals(new FileInputStream(f).read(temp), temp.length); assertEquals(temp, bytes);