/*
* Created on Oct 5, 2003
* Created by Paul Gardner
* Modified Apr 13, 2004 by Alon Rohter
* Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.frostwire.torrent;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
public class TOTorrentFileHasher {
protected boolean do_other_per_file_hash;
protected int piece_length;
protected Vector<byte[]> pieces = new Vector<byte[]>();
protected byte[] buffer;
protected int buffer_pos;
protected SHA1Hasher overall_sha1_hash;
//protected ED2KHasher overall_ed2k_hash;
protected byte[] sha1_digest;
//protected byte[] ed2k_digest;
protected byte[] per_file_sha1_digest;
//protected byte[] per_file_ed2k_digest;
protected TOTorrentFileHasherListener listener;
protected boolean cancelled;
protected TOTorrentFileHasher(boolean _do_other_overall_hashes, boolean _do_other_per_file_hash, int _piece_length, TOTorrentFileHasherListener _listener) {
if (_do_other_overall_hashes) {
overall_sha1_hash = new SHA1Hasher();
//overall_ed2k_hash = new ED2KHasher();
}
do_other_per_file_hash = _do_other_per_file_hash;
piece_length = _piece_length;
listener = _listener;
buffer = new byte[piece_length];
}
long add(File _file)
throws TOTorrentException {
long file_length = 0;
InputStream is = null;
SHA1Hasher sha1_hash = null;
//ED2KHasher ed2k_hash = null;
try {
if (do_other_per_file_hash) {
sha1_hash = new SHA1Hasher();
//ed2k_hash = new ED2KHasher();
}
is = new BufferedInputStream(new FileInputStream(_file), 65536);
while (true) {
if (cancelled) {
try {
is.close();
} catch (IOException e) {
// ignore
}
throw (new TOTorrentException("TOTorrentCreate: operation cancelled", TOTorrentException.RT_CANCELLED));
}
int len = is.read(buffer, buffer_pos, piece_length - buffer_pos);
if (len > 0) {
if (do_other_per_file_hash) {
sha1_hash.update(buffer, buffer_pos, len);
//ed2k_hash.update( buffer, buffer_pos, len );
}
file_length += len;
buffer_pos += len;
if (buffer_pos == piece_length) {
// hash this piece
byte[] hash = new SHA1Hasher().calculateHash(buffer);
if (overall_sha1_hash != null) {
overall_sha1_hash.update(buffer);
//overall_ed2k_hash.update( buffer );
}
pieces.add(hash);
if (listener != null) {
listener.pieceHashed(pieces.size());
}
buffer_pos = 0;
}
} else {
break;
}
}
if (do_other_per_file_hash) {
per_file_sha1_digest = sha1_hash.getDigest();
//per_file_ed2k_digest = ed2k_hash.getDigest();
}
} catch (TOTorrentException e) {
throw (e);
} catch (Throwable e) {
throw (new TOTorrentException("TOTorrentFileHasher: file read fails '" + e.toString() + "'", TOTorrentException.RT_READ_FAILS));
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
}
}
}
return (file_length);
}
protected byte[] getPerFileSHA1Digest() {
return (per_file_sha1_digest);
}
// protected byte[]
// getPerFileED2KDigest()
// {
// return( per_file_ed2k_digest );
// }
protected byte[][] getPieces()
throws TOTorrentException {
try {
if (buffer_pos > 0) {
byte[] rem = new byte[buffer_pos];
System.arraycopy(buffer, 0, rem, 0, buffer_pos);
pieces.addElement(new SHA1Hasher().calculateHash(rem));
if (overall_sha1_hash != null) {
overall_sha1_hash.update(rem);
//overall_ed2k_hash.update( rem );
}
if (listener != null) {
listener.pieceHashed(pieces.size());
}
buffer_pos = 0;
}
if (overall_sha1_hash != null && sha1_digest == null) {
sha1_digest = overall_sha1_hash.getDigest();
//ed2k_digest = overall_ed2k_hash.getDigest();
}
byte[][] res = new byte[pieces.size()][];
pieces.copyInto(res);
return (res);
} catch (Throwable e) {
throw (new TOTorrentException("TOTorrentFileHasher: file read fails '" + e.toString() + "'", TOTorrentException.RT_READ_FAILS));
}
}
// protected byte[]
// getED2KDigest()
//
// throws TOTorrentException
// {
// if ( ed2k_digest == null ){
//
// getPieces();
// }
//
// return( ed2k_digest );
// }
protected byte[] getSHA1Digest()
throws TOTorrentException {
if (sha1_digest == null) {
getPieces();
}
return (sha1_digest);
}
protected void cancel() {
cancelled = true;
}
}