1 /***************************************************************************
2 *                                                                         *
3 *   This program is free software; you can redistribute it and/or modify  *
4 *   it under the terms of the GNU General Public License as published by  *
5 *   the Free Software Foundation; either version 3 of the License, or     *
6 *   (at your option) any later version.                                   *
7 *                                                                         *
8 ***************************************************************************/
9 
10 #include "FileHasher.h"
11 
12 #include <QFile>
13 #include <QFileDialog>
14 #include <QUrl>
15 #include <QClipboard>
16 #include <QFileInfo>
17 #include <QMessageBox>
18 
19 #include <algorithm>
20 
21 #include "dcpp/stdinc.h"
22 #include "dcpp/HashManager.h"
23 #include "dcpp/CID.h"
24 #include "dcpp/File.h"
25 
26 #include "WulforUtil.h"
27 
28 using namespace dcpp;
29 
30 static const quint64 MIN_BLOCK_SIZE = 64 * 1024;
31 static const size_t BUF_SIZE = 64*1024;
32 
FileHasher(QWidget * parent)33 FileHasher::FileHasher(QWidget *parent) :
34     QDialog(parent)
35 {
36     setupUi(this);
37     hasher = new HashThread();
38 
39     connect(hasher, SIGNAL(finished()), this, SLOT(slotDone()));
40     pushButton_BROWSE->setIcon(WICON(WulforUtil::eiFOLDER_BLUE));
41 
42     connect(pushButton_RUN,    SIGNAL(clicked()), this, SLOT(slotStart()));
43     connect(pushButton_BROWSE, SIGNAL(clicked()), this, SLOT(slotBrowse()));
44     connect(pushButton_MAGNET, SIGNAL(clicked()), this, SLOT(slotMagnet()));
45 }
46 
~FileHasher()47 FileHasher::~FileHasher() {
48     if (hasher)
49         hasher->terminate();
50 
51 
52     delete hasher;
53 }
54 
slotStart()55 void FileHasher::slotStart(){
56 
57     QString file = lineEdit_FILE->text();
58 
59     if (!QFile::exists(file))
60         return;
61 
62     pushButton_RUN->setEnabled(false);
63     HashManager  *HM = HashManager::getInstance();
64     const TTHValue *tth= HM->getFileTTHif(_tq(file));
65     if (tth) {
66         lineEdit_HASH->setText(_q(tth->toBase32()));
67         pushButton_RUN->setEnabled(true);
68     } else {
69         if (hasher){
70             hasher-> terminate();
71             hasher->setFile(file);
72             hasher->start();
73         }
74     }
75 }
76 
slotDone()77 void FileHasher::slotDone(){
78     lineEdit_HASH->setText(hasher->getHash());
79 
80     pushButton_RUN->setEnabled(true);
81 }
82 
slotMagnet()83 void FileHasher::slotMagnet(){
84     QString tthstring = lineEdit_HASH->text(), file = lineEdit_FILE->text();
85 
86     if (tthstring.isEmpty()){
87         slotStart();
88         return;
89     }
90 
91     qlonglong filesize = QFile(file).size();
92     QStringList list = file.split("/");
93 
94     file = list.last();
95 
96     QString urlStr = WulforUtil::getInstance()->makeMagnet(file, filesize, tthstring);
97     qApp->clipboard()->setText(urlStr);
98 }
99 
slotBrowse()100 void FileHasher::slotBrowse(){
101 
102     QString file = QFileDialog::getOpenFileName(this, tr("Select file"), QDir::homePath(), tr("All files (*.*)"));
103 
104     if (!file.isEmpty()){
105         file = QDir::toNativeSeparators(file);
106         lineEdit_FILE->setText(file);
107         lineEdit_HASH->setText("");
108     }
109 }
110 
HashThread()111 HashThread::HashThread(){
112 }
113 
~HashThread()114 HashThread::~HashThread(){
115 }
116 
run()117 void HashThread::run(){
118     calculate_tth();
119 }
120 
setFile(QString f)121 void HashThread::setFile(QString f){
122     file_name = f;
123 }
124 
getHash()125 QString HashThread::getHash(){
126     return hash;
127 }
128 
calculate_tth()129 void HashThread::calculate_tth() {
130     char TTH[40] = {0};
131     char *buf = new char[BUF_SIZE];
132 
133     memset(buf, 0, BUF_SIZE);
134 
135     try {
136         File f(Text::fromT(_tq(file_name)),File::READ, File::OPEN);
137         TigerTree tth(max(TigerTree::calcBlockSize(f.getSize(), 10), static_cast<int64_t>(MIN_BLOCK_SIZE)));
138         if(f.getSize() > 0) {
139             size_t n = BUF_SIZE;
140             while( (n = f.read(&buf[0], n)) > 0) {
141                 tth.update(&buf[0], n);
142                 n = BUF_SIZE;
143             }
144         } else {
145             tth.update("", 0);
146         }
147         tth.finalize();
148         strcpy(&TTH[0], tth.getRoot().toBase32().c_str());
149         hash = _q(TTH);
150         f.close();
151     } catch (...) {}
152 
153     delete [] buf;
154 }
155