/* * 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; } }