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