~ubuntu-branches/ubuntu/oneiric/libktorrent/oneiric

« back to all changes in this revision

Viewing changes to src/download/chunkdownload.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Modestas Vainius
  • Date: 2011-05-26 00:33:38 UTC
  • mfrom: (5.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110526003338-2r4zwyzn8bovsxay
Tags: 1.1.1-2
Release to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <util/file.h>
24
24
#include <util/log.h>
25
25
#include <util/array.h>
 
26
#include <util/error.h>
26
27
#include <diskio/chunk.h>
27
28
#include <diskio/piecedata.h>
28
29
#include <download/piece.h>
78
79
                
79
80
                pieces = BitSet(num);
80
81
                pieces.clear();
81
 
                piece_data = new PieceDataPtr[num]; // array of pointers to the piece data
82
 
                
83
 
                for (Uint32 i = 0;i < num;i++)
84
 
                {
85
 
                        piece_data[i] = 0;
86
 
                }
 
82
                piece_data = new PieceData::Ptr[num]; // array of pointers to the piece data
87
83
                
88
84
                dstatus.setAutoDelete(true);
89
85
 
102
98
                timer.update();
103
99
                        
104
100
                Uint32 pp = p.getOffset() / MAX_PIECE_LEN;
105
 
                if (pieces.get(pp))
 
101
                Uint32 len = pp == num - 1 ? last_size : MAX_PIECE_LEN;
 
102
                if (pp >= num || pieces.get(pp) || p.getLength() != len)
106
103
                        return false;
107
104
 
108
105
        
110
107
                if (ds)
111
108
                        ds->remove(pp);
112
109
                
113
 
                PieceDataPtr buf = chunk->getPiece(p.getOffset(),p.getLength(),false);
114
 
                if (buf)
115
 
                { 
 
110
                PieceData::Ptr buf = chunk->getPiece(p.getOffset(),p.getLength(),false);
 
111
                if (buf && buf->write(p.getData(),p.getLength()) == p.getLength())
 
112
                {
116
113
                        piece_data[pp] = buf;
117
114
                        ok = true;
118
 
                        memcpy(buf->data(),p.getData(),p.getLength());  
119
115
                        pieces.set(pp,true);
120
116
                        piece_providers.insert(p.getPieceDownloader());
121
117
                        num_downloaded++;
166
162
                return true;
167
163
        }
168
164
        
 
165
        void ChunkDownload::release(PieceDownloader* pd)
 
166
        {
 
167
                if (!pdown.contains(pd))
 
168
                        return;
 
169
                
 
170
                pd->release();
 
171
                sendCancels(pd);
 
172
                disconnect(pd,SIGNAL(timedout(const bt::Request& )),this,SLOT(onTimeout(const bt::Request& )));
 
173
                disconnect(pd,SIGNAL(rejected( const bt::Request& )),this,SLOT(onRejected( const bt::Request& )));
 
174
                dstatus.erase(pd);
 
175
                pdown.removeAll(pd);
 
176
        }
 
177
 
 
178
        
169
179
        void ChunkDownload::notDownloaded(const Request & r,bool reject)
170
180
        {
171
181
                // find the peer 
399
409
                // save how many PieceHeader structs are to be written
400
410
                Uint32 num_pieces_to_follow = 0;
401
411
                for (Uint32 i = 0;i < hdr.num_bits;i++)
402
 
                        if (piece_data[i])
 
412
                        if (piece_data[i] && piece_data[i]->ok())
403
413
                                num_pieces_to_follow++;
404
414
                
405
415
                file.write(&num_pieces_to_follow,sizeof(Uint32));
407
417
                // save all buffered pieces
408
418
                for (Uint32 i = 0;i < hdr.num_bits;i++)
409
419
                {
410
 
                        if (!piece_data[i])
 
420
                        if (!piece_data[i] || !piece_data[i]->ok())
411
421
                                continue;
412
422
                        
413
 
                        PieceDataPtr pd = piece_data[i];
 
423
                        PieceData::Ptr pd = piece_data[i];
414
424
                        PieceHeader phdr;
415
425
                        phdr.piece = i;
416
426
                        phdr.size = pd->length();
418
428
                        file.write(&phdr,sizeof(PieceHeader));
419
429
                        if (!pd->mapped()) // buffered pieces need to be saved
420
430
                        {
421
 
                                file.write(pd->data(),pd->length());
 
431
                                pd->writeToFile(file,pd->length());
422
432
                        }
423
433
                }
424
434
        }
447
457
                        if (phdr.piece >= num)
448
458
                                return false;
449
459
                        
450
 
                        PieceDataPtr p = chunk->getPiece(phdr.piece * MAX_PIECE_LEN,phdr.size,false);
 
460
                        PieceData::Ptr p = chunk->getPiece(phdr.piece * MAX_PIECE_LEN,phdr.size,false);
451
461
                        if (!p)
452
462
                                return false;
453
463
                        
454
464
                        if (!phdr.mapped)
455
465
                        {
456
 
                                if (file.read(p->data(),p->length()) != p->length())
 
466
                                if (p->readFromFile(file,p->length()) != p->length())
457
467
                                {
458
468
                                        return false;
459
469
                                }
544
554
                
545
555
                for (Uint32 i = num_pieces_in_hash;i < nn;i++)
546
556
                {
547
 
                        PieceDataPtr piece = piece_data[i];
 
557
                        PieceData::Ptr piece = piece_data[i];
548
558
                        Uint32 len = i == num - 1 ? last_size : MAX_PIECE_LEN;
549
559
                        if (!piece)
550
560
                                piece = chunk->getPiece(i*MAX_PIECE_LEN,len,true);
551
561
                        
552
 
                        piece_data[i] = 0;
553
 
                        if (piece)
 
562
                        if (piece && piece->ok())
554
563
                        {
555
 
                                hash_gen.update(piece->data(),len);
 
564
                                piece->updateHash(hash_gen);
556
565
                                chunk->savePiece(piece);
557
566
                        }
558
567
                }