1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of The Qt Company Ltd nor the names of its
21 **     contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #ifndef FILEMANAGER_H
42 #define FILEMANAGER_H
43 
44 #include <QBitArray>
45 #include <QList>
46 #include <QMutex>
47 #include <QThread>
48 #include <QWaitCondition>
49 
50 #include "metainfo.h"
51 
52 QT_BEGIN_NAMESPACE
53 class QByteArray;
54 class QFile;
55 class QTimerEvent;
56 QT_END_NAMESPACE
57 
58 class FileManager : public QThread
59 {
60     Q_OBJECT
61 
62 public:
63     FileManager(QObject *parent = 0);
64     virtual ~FileManager();
65 
setMetaInfo(const MetaInfo & info)66     inline void setMetaInfo(const MetaInfo &info) { metaInfo = info; }
setDestinationFolder(const QString & directory)67     inline void setDestinationFolder(const QString &directory) { destinationPath = directory; }
68 
69     int read(int pieceIndex, int offset, int length);
70     void write(int pieceIndex, int offset, const QByteArray &data);
71     void verifyPiece(int pieceIndex);
totalSize()72     inline qint64 totalSize() const { return totalLength; }
73 
pieceCount()74     inline int pieceCount() const { return numPieces; }
75     int pieceLengthAt(int pieceIndex) const;
76 
77     QBitArray completedPieces() const;
78     void setCompletedPieces(const QBitArray &pieces);
79 
80     QString errorString() const;
81 
82 public slots:
83     void startDataVerification();
84 
85 signals:
86     void dataRead(int id, int pieceIndex, int offset, const QByteArray &data);
87     void error();
88     void verificationProgress(int percent);
89     void verificationDone();
90     void pieceVerified(int pieceIndex, bool verified);
91 
92 protected:
93     void run();
94 
95 private slots:
96     bool verifySinglePiece(int pieceIndex);
97     void wakeUp();
98 
99 private:
100     bool generateFiles();
101     QByteArray readBlock(int pieceIndex, int offset, int length);
102     bool writeBlock(int pieceIndex, int offset, const QByteArray &data);
103     void verifyFileContents();
104 
105     struct WriteRequest {
106         int pieceIndex;
107         int offset;
108         QByteArray data;
109     };
110     struct ReadRequest {
111         int pieceIndex;
112         int offset;
113         int length;
114         int id;
115     };
116 
117     QString errString;
118     QString destinationPath;
119     MetaInfo metaInfo;
120     QList<QFile *> files;
121     QList<QByteArray> sha1s;
122     QBitArray verifiedPieces;
123 
124     bool newFile;
125     int pieceLength;
126     qint64 totalLength;
127     int numPieces;
128     int readId;
129     bool startVerification;
130     bool quit;
131     bool wokeUp;
132 
133     QList<WriteRequest> writeRequests;
134     QList<ReadRequest> readRequests;
135     QList<int> pendingVerificationRequests;
136     QList<int> newPendingVerificationRequests;
137     QList<qint64> fileSizes;
138 
139     mutable QMutex mutex;
140     mutable QWaitCondition cond;
141 };
142 
143 #endif
144