~ubuntu-branches/ubuntu/lucid/ktorrent/lucid

« back to all changes in this revision

Viewing changes to libktorrent/torrent/packet.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Richard Birnie
  • Date: 2008-06-03 20:32:46 UTC
  • mfrom: (1.1.20 upstream)
  • Revision ID: james.westby@ubuntu.com-20080603203246-dfyemn010uhsf433
Tags: 3.1~rc1+dfsg.1-1ubuntu1
* New upstream development release      
 - Dropped 01_support_external_libbtcore.diffm,
   97_fix_target_link_libraries.diff,
   99_libbtcore_scramble_soname.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *   Copyright (C) 2005 by Joris Guisson                                   *
3
 
 *   joris.guisson@gmail.com                                               *
4
 
 *                                                                         *
5
 
 *   This program is free software; you can redistribute it and/or modify  *
6
 
 *   it under the terms of the GNU General Public License as published by  *
7
 
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 
 *   (at your option) any later version.                                   *
9
 
 *                                                                         *
10
 
 *   This program is distributed in the hope that it will be useful,       *
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 
 *   GNU General Public License for more details.                          *
14
 
 *                                                                         *
15
 
 *   You should have received a copy of the GNU General Public License     *
16
 
 *   along with this program; if not, write to the                         *
17
 
 *   Free Software Foundation, Inc.,                                       *
18
 
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.             *
19
 
 ***************************************************************************/
20
 
#include <qstring.h>
21
 
#include <string.h>
22
 
#include <util/log.h>
23
 
#include <util/bitset.h>
24
 
#include <util/functions.h>
25
 
#include <torrent/globals.h>
26
 
#include "packet.h"
27
 
#include "request.h"
28
 
#include "chunk.h"
29
 
#include "peer.h"
30
 
 
31
 
namespace bt
32
 
{
33
 
 
34
 
        static Uint8* AllocPacket(Uint32 size,Uint8 type)
35
 
        {
36
 
                Uint8* data = new Uint8[size];
37
 
                WriteUint32(data,0,size - 4);
38
 
                data[4] = type;
39
 
                return data;
40
 
        }
41
 
 
42
 
 
43
 
        Packet::Packet(Uint8 type) : data(0),size(0),written(0)
44
 
        {
45
 
                size = 5;
46
 
                data = AllocPacket(size,type);
47
 
        }
48
 
        
49
 
        Packet::Packet(Uint16 port) : data(0),size(0),written(0)
50
 
        {
51
 
                size = 7;
52
 
                data = AllocPacket(size,PORT);
53
 
                WriteUint16(data,5,port);
54
 
                
55
 
        }
56
 
        
57
 
        Packet::Packet(Uint32 chunk,Uint8 type) : data(0),size(0),written(0)
58
 
        {
59
 
                size = 9;
60
 
                data = AllocPacket(size,type);
61
 
                WriteUint32(data,5,chunk);
62
 
        }
63
 
        
64
 
        Packet::Packet(const BitSet & bs) : data(0),size(0),written(0)
65
 
        {
66
 
                size = 5 + bs.getNumBytes();
67
 
                data = AllocPacket(size,BITFIELD);
68
 
                memcpy(data+5,bs.getData(),bs.getNumBytes());
69
 
        }
70
 
        
71
 
        Packet::Packet(const Request & r,Uint8 type) : data(0),size(0),written(0)
72
 
        {
73
 
                size = 17;
74
 
                data = AllocPacket(size,type);
75
 
                WriteUint32(data,5,r.getIndex());
76
 
                WriteUint32(data,9,r.getOffset());
77
 
                WriteUint32(data,13,r.getLength());
78
 
        }
79
 
        
80
 
        Packet::Packet(Uint32 index,Uint32 begin,Uint32 len,Chunk* ch) : data(0),size(0),written(0)
81
 
        {
82
 
                size = 13 + len;
83
 
                data = AllocPacket(size,PIECE);
84
 
                WriteUint32(data,5,index);
85
 
                WriteUint32(data,9,begin);
86
 
                memcpy(data+13,ch->getData() + begin,len);
87
 
        }
88
 
 
89
 
        Packet::Packet(Uint8 ext_id,const QByteArray & ext_data) : data(0),size(0),written(0)
90
 
        {
91
 
                size = 6 + ext_data.size();
92
 
                data = AllocPacket(size,EXTENDED);
93
 
                data[5] = ext_id;
94
 
                memcpy(data + 6,ext_data.data(),ext_data.size());
95
 
        }
96
 
 
97
 
        Packet::~Packet()
98
 
        {
99
 
                delete [] data;
100
 
        }
101
 
        
102
 
        bool Packet::isPiece(const Request & req) const
103
 
        {
104
 
                if (data[4] == PIECE)
105
 
                {
106
 
                        if (ReadUint32(data,5) != req.getIndex())
107
 
                                return false;
108
 
                        
109
 
                        if (ReadUint32(data,9) != req.getOffset())
110
 
                                return false; 
111
 
                        
112
 
                        if (ReadUint32(data,13) != req.getLength())
113
 
                                return false;
114
 
                        
115
 
                        return true;
116
 
                }
117
 
                return false;
118
 
        }
119
 
        
120
 
        Packet* Packet::makeRejectOfPiece()
121
 
        {
122
 
                if (getType() != PIECE)
123
 
                        return 0;
124
 
                
125
 
                Uint32 idx = bt::ReadUint32(data,5);
126
 
                Uint32 off = bt::ReadUint32(data,9);
127
 
                Uint32 len = size - 13;
128
 
                
129
 
        //      Out(SYS_CON|LOG_DEBUG) << "Packet::makeRejectOfPiece " << idx << " " << off << " " << len << endl;
130
 
                return new Packet(Request(idx,off,len,0),bt::REJECT_REQUEST);
131
 
        }
132
 
        
133
 
        /*
134
 
        QString Packet::debugString() const
135
 
        {
136
 
                if (!data)
137
 
                        return QString::null;
138
 
                
139
 
                switch (data[4])
140
 
                {
141
 
                        case CHOKE : return QString("CHOKE %1 %2").arg(hdr_length).arg(data_length);
142
 
                        case UNCHOKE : return QString("UNCHOKE %1 %2").arg(hdr_length).arg(data_length);
143
 
                        case INTERESTED : return QString("INTERESTED %1 %2").arg(hdr_length).arg(data_length);
144
 
                        case NOT_INTERESTED : return QString("NOT_INTERESTED %1 %2").arg(hdr_length).arg(data_length);
145
 
                        case HAVE : return QString("HAVE %1 %2").arg(hdr_length).arg(data_length);
146
 
                        case BITFIELD : return QString("BITFIELD %1 %2").arg(hdr_length).arg(data_length);
147
 
                        case PIECE : return QString("PIECE %1 %2").arg(hdr_length).arg(data_length);
148
 
                        case REQUEST : return QString("REQUEST %1 %2").arg(hdr_length).arg(data_length);
149
 
                        case CANCEL : return QString("CANCEL %1 %2").arg(hdr_length).arg(data_length);
150
 
                        default: return QString("UNKNOWN %1 %2").arg(hdr_length).arg(data_length);
151
 
                }
152
 
        }
153
 
        */
154
 
        bool Packet::isOK() const
155
 
        {
156
 
                if (!data)
157
 
                        return false;
158
 
 
159
 
                return true;
160
 
        }
161
 
 
162
 
        Uint32 Packet::putInOutputBuffer(Uint8* buf,Uint32 max_to_put,bool & piece)
163
 
        {
164
 
                piece = data[4] == PIECE;
165
 
                Uint32 bw = size - written;
166
 
                if (!bw) // nothing to write
167
 
                        return 0;
168
 
                
169
 
                if (bw > max_to_put)
170
 
                        bw = max_to_put;
171
 
                memcpy(buf,data + written,bw);
172
 
                written += bw;
173
 
                return bw;
174
 
        }
175
 
}