summaryrefslogtreecommitdiffstats
path: root/libktorrent/net/bufferedsocket.h
blob: 2c0c3ec10704090f730ea48243c5a0f73720a93c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/***************************************************************************
 *   Copyright (C) 2005 by Joris Guisson                                   *
 *   [email protected]                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 ***************************************************************************/
#ifndef NETBUFFEREDSOCKET_H
#define NETBUFFEREDSOCKET_H

#include <qmutex.h>
#include <net/socket.h>

namespace net
{
	using bt::Uint8;
	using bt::Uint32;
	
	class Speed;
	
	class SocketReader
	{
	public:
		SocketReader() {}
		virtual ~SocketReader() {}
		
		/**
		 * Function which will be called whenever data has been read from the socket.
		 * This data should be dealt with, otherwise it will be discarded.
		 * @param buf The buffer
		 * @param size The size of the buffer
		 */
		virtual void onDataReady(Uint8* buf,Uint32 size) = 0;	
	};
	
	class SocketWriter
	{
	public:	
		SocketWriter() {}
		virtual ~SocketWriter() {}

		/**
		 * The socket is ready to write, the writer is asked to provide the data.
		 * The data will be fully sent, before another request is done.
		 * @param data The data
		 * @param max_to_write The maximum number of bytes to put in the buffer
		 * @param The number of bytes placed in the buffer 
		 */
		virtual Uint32 onReadyToWrite(Uint8* data,Uint32 max_to_write) = 0;	
		
		/// Check if data is ready to write
		virtual bool hasBytesToWrite() const = 0;

	};

	/**
	 * @author Joris Guisson <[email protected]>
	 * 
	 * Extends the Socket class with
	 */
	class BufferedSocket : public Socket
	{
		mutable QMutex mutex;
		SocketReader* rdr;
		SocketWriter* wrt;
		Uint8* output_buffer;
		Uint32 bytes_in_output_buffer; // bytes in the output buffer
		Uint32 bytes_sent; // bytes written of the output buffer
		Speed* down_speed;
		Speed* up_speed;
		int poll_index;
		
		Uint32 up_gid;
		Uint32 down_gid; // group id which this torrent belongs to, group 0 means the default group
		
	public:
		BufferedSocket(int fd);
		BufferedSocket(bool tcp);
		virtual ~BufferedSocket();

		/**
		 * Set the group ID of the socket
		 * @param gid THe ID (0 is default group)
		 * @param upload Wether this is an upload group or a download group
		 */
		void setGroupID(Uint32 gid,bool upload);
		
		/// Get the download group ID
		Uint32 downloadGroupID() const {return down_gid;}
		
		/// Get the upload group ID
		Uint32 uploadGroupID() const {return up_gid;}
		
		void setReader(SocketReader* r) {rdr = r;}
		void setWriter(SocketWriter* r) {wrt = r;}
		
		/**
		 * Reads data from the socket to the buffer.
		 * @param max_bytes_to_read Maximum number of bytes to read (0 is no limit)
		 * @param now Current time stamp
		 * @return The number of bytes read
		 */
		Uint32 readBuffered(Uint32 max_bytes_to_read,bt::TimeStamp now);
		
		/**
		 * Writes data from the buffer to the socket.
		 * @param max The maximum number of bytes to send over the socket (0 = no limit)
		 * * @param now Current time stamp
		 * @return The number of bytes written
		 */
		Uint32 writeBuffered(Uint32 max,bt::TimeStamp now);
		
		/// See if the socket has something ready to write
		bool bytesReadyToWrite() const 
		{
			return bytes_in_output_buffer > 0 || (!wrt ? false : wrt->hasBytesToWrite());
		}
		
		
		/// Get the current download rate
		float getDownloadRate() const;
		
		/// Get the current download rate
		float getUploadRate() const;
		
		/// Update up and down speed
		void updateSpeeds(bt::TimeStamp now);
		
		int getPollIndex() const {return poll_index;}
		void setPollIndex(int pi) {poll_index = pi;}
		
	private:
		Uint32 sendOutputBuffer(Uint32 max,bt::TimeStamp now);
	};

}

#endif