author | Tero Marttila <terom@fixme.fi> |
Fri, 16 Jan 2009 21:24:45 +0200 | |
changeset 399 | c7295b72731a |
parent 380 | d193dd1d8a7e |
child 400 | d64bf28c4340 |
permissions | -rw-r--r-- |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
1 |
#ifndef NETWORK_BUFFER_HH |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
2 |
#define NETWORK_BUFFER_HH |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
3 |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
4 |
/** |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
5 |
* @file |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
6 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
7 |
* Buffering of network streams |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
8 |
*/ |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
9 |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
10 |
#include "Socket.hh" |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
11 |
#include "../Error.hh" |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
12 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
13 |
#include <cassert> |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
14 |
|
284 | 15 |
/** |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
16 |
* Minimum chunk size to avoid handling single bytes at a time (for resize, mainly) |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
17 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
18 |
const size_t NETWORK_BUFFER_CHUNK_SIZE = 1024; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
19 |
|
284 | 20 |
/** |
21 |
* Base class of errors thrown by NetworkBuffer* methods |
|
22 |
*/ |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
23 |
class NetworkBufferError : public Error { |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
24 |
public: |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
25 |
NetworkBufferError (const std::string &message) : Error(message) { } |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
26 |
}; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
27 |
|
284 | 28 |
/** |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
29 |
* Base buffer-manipulation operations for buffered socket send/recv. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
30 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
31 |
* This implements a simple linear in-memory buffer which can contain data that must be buffered for send/recv. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
32 |
* New data can be written to the end of the buffer, and data can be read/discarded from the beginning. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
33 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
34 |
* A buffer is associated with a NetworkSocket, and takes care of all send/recv activity. |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
35 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
36 |
class NetworkBufferBase { |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
37 |
protected: |
284 | 38 |
/** The socket that we use */ |
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
365
diff
changeset
|
39 |
NetworkSocket *socket; |
284 | 40 |
|
41 |
/** The buffer itself */ |
|
42 |
char *buf; |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
43 |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
44 |
/** Buffer size and current write offset */ |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
45 |
size_t size, offset; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
46 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
47 |
public: |
284 | 48 |
/** |
49 |
* Allocate buf using the given initial size, and set offset to zero |
|
50 |
*/ |
|
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
365
diff
changeset
|
51 |
NetworkBufferBase (NetworkSocket *socket, size_t size_hint); |
284 | 52 |
|
53 |
/** |
|
54 |
* Free()'s the buf |
|
55 |
*/ |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
56 |
~NetworkBufferBase (void); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
57 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
58 |
private: |
284 | 59 |
/** |
60 |
* No copying, these are undefined |
|
61 |
*/ |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
62 |
NetworkBufferBase (const NetworkBufferBase ©); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
63 |
NetworkBufferBase& operator= (const NetworkBufferBase ©); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
64 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
65 |
protected: |
284 | 66 |
/** |
67 |
* Resize the buffer, allocating enough new space to hold <item_size> bytes at the end, and leaving any |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
68 |
* existing data at the beginning in-place. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
69 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
70 |
* This is done by doubling the buffer size until item_size fits, and then reallocing (if needed). |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
71 |
* Currently, the buffer is never shrunk, although it probably should be to adapt better to peak load (e.g. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
72 |
* when a player joins and the map data is transmitted...). |
284 | 73 |
* |
74 |
* @param item_size the number of bytes that must fit at the end of the buffer |
|
75 |
*/ |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
76 |
void resize (size_t item_size); |
284 | 77 |
|
78 |
/** |
|
79 |
* Trim the buffer, discarding <prefix_size> bytes at the beginning. Updates offset to match. |
|
80 |
* |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
81 |
* Currently, this is implemented as a simple memmove() of all the remaining data in the buffer, which may be |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
82 |
* slow under some load patterns. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
83 |
* |
284 | 84 |
* @param prefix_size the number of bytes to discard |
85 |
*/ |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
86 |
void trim (size_t prefix_size); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
87 |
}; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
88 |
|
284 | 89 |
/** |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
90 |
* Buffered prefix-len socket input |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
91 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
92 |
* This handles calling recv() on the socket, and is specialized to handle a stream of messages prefixed with a length |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
93 |
* header (uint16_t or uint32_t). Use the peek_data() method to receive these messages when NetworkSocket::sig_read() |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
94 |
* indicates that more data is available. |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
95 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
96 |
class NetworkBufferInput : public NetworkBufferBase { |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
97 |
public: |
284 | 98 |
/** |
99 |
* @see NetworkBufferBase |
|
100 |
*/ |
|
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
365
diff
changeset
|
101 |
NetworkBufferInput (NetworkSocket *socket, size_t size_hint); |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
102 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
103 |
private: |
284 | 104 |
/** |
105 |
* Attempts to recv the given number of bytes into our buf, returning true on success |
|
106 |
* |
|
107 |
* @param item_size minimum number of bytes of data that we need in the buffer |
|
108 |
* @return bool true if the buffer now contains at least item_size bytes |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
109 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
110 |
bool try_read (size_t item_size); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
111 |
|
284 | 112 |
/** |
113 |
* Tests if the buffer contains at least the given amount of data, but doesn't recv or anything |
|
114 |
* |
|
115 |
* @param data_size number of bytes that we are expecting |
|
116 |
* @return bool true if the buffer contains at least data_size bytes |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
117 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
118 |
bool have_data (size_t data_size); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
119 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
120 |
public: |
284 | 121 |
// @{ |
122 |
/** |
|
123 |
* |
|
124 |
* Attempts to read the length prefix into val_ref, returning true on success, false if there's not enough data |
|
125 |
* in the buffer |
|
126 |
* |
|
127 |
* @param val_ref stores the value read here if we have it |
|
128 |
* @return bool was val_ref set |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
129 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
130 |
bool peek_prefix (uint16_t &val_ref); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
131 |
bool peek_prefix (uint32_t &val_ref); |
284 | 132 |
// @} |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
133 |
|
284 | 134 |
/** |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
135 |
* This attempts to locate a full message in the buffer (calling recv as nessecary), prefixed with a length |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
136 |
* prefix of the given type (using peek_prefix). If succesfull (we have a full message in the buffer), |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
137 |
* \a prefix will be updated to the length of the message (not including the prefix), and \a buf_ref will be |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
138 |
* updated to point at the message of \a prefix bytes (not including the prefix) in our internal buffer memory. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
139 |
* If a full message could not be received (recv would block), this will return false. |
284 | 140 |
* |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
141 |
* Once you have processed the message, call flush_data() to remove the unused message from the buffer. |
284 | 142 |
* |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
143 |
* @param prefix updated to the message length |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
144 |
* @param buf_ref updated to point at the message data |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
145 |
* @return bool true if we have a full message, false if we need to wait for more data on the socket |
284 | 146 |
* |
147 |
* @see peek_prefix |
|
148 |
* @see flush_data |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
149 |
*/ |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
150 |
template <typename PrefixType> bool peek_data (PrefixType &prefix, char *&buf_ref); |
284 | 151 |
|
152 |
/** |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
153 |
* This flushes the current message from the buffer, as returned when peek_data returns true. It is a bug to |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
154 |
* call flush_data when there is no full message present, the behaviour is unspecified (most likely an |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
155 |
* assert()). |
284 | 156 |
* |
157 |
* @see peek_data |
|
158 |
*/ |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
159 |
template <typename PrefixType> void flush_data (void); |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
160 |
}; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
161 |
|
284 | 162 |
/** |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
163 |
* Buffered prefix-len socket output. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
164 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
165 |
* This handles calling send() on the socket, and is specialized to handle a stream of message prefixed with a length |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
166 |
* header (uint16_t or uint32_t). You can write messages using write_prefix(), and they will be buffered if needed. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
167 |
* If write_prefix() returns true (socket buffer full), then you must register the socket for |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
168 |
* NetworkSocket::set_poll_write(), and call flush_write() once NetworkSocket::sig_write() is triggered. The socket's |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
169 |
* poll_write should be unregistered once flush_write returns false (no more buffered data remaining to be sent), or |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
170 |
* an many processor cycles will be wasted, for the socket will remain ready for write until its buffer fills up again. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
171 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
172 |
* Data is not buffered needlessly; if the socket's buffer has room, write_prefix will not have to touch our internal |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
173 |
* buffer. In fact, write_prefix will rarely return false except under heavy network congestion with high levels of |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
174 |
* traffic on the socket. |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
175 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
176 |
class NetworkBufferOutput : public NetworkBufferBase { |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
177 |
public: |
284 | 178 |
/** |
179 |
* @see NetworkBufferBase |
|
180 |
*/ |
|
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
365
diff
changeset
|
181 |
NetworkBufferOutput (NetworkSocket *socket, size_t size_hint); |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
182 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
183 |
private: |
284 | 184 |
/** |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
185 |
* Write the given data to the socket, either now or later. |
284 | 186 |
* |
187 |
* If our buffer is empty, fast-path the given buf_ptr directly to send(), then copy the remaining portion to |
|
188 |
* our buffer for later use with flush_write. |
|
189 |
* |
|
190 |
* @param buf_ptr the data that we need to send |
|
191 |
* @param buf_size number of bytes in buf_ptr |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
192 |
*/ |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
193 |
void push_write (char *buf_ptr, size_t buf_size); |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
194 |
|
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
195 |
public: |
284 | 196 |
/** |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
197 |
* If we have data in our buffer, flush it out using send(). This should be called once the socket indicates it |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
198 |
* is ready for write again after a call to write_prefix that returned false. Once this returns false, the |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
199 |
* NetworkSocket::set_poll_write() flag should be unset again to avoid needless calls to this. |
380 | 200 |
* |
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
201 |
* @return true if there's still buffered data left to write, false otherwise (buffer is empty) |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
202 |
*/ |
380 | 203 |
bool flush_write (void); |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
204 |
|
284 | 205 |
// @{ |
206 |
/** |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
207 |
* Write out the given message, writing first the prefix, and then the data itself, using push_write. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
208 |
* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
209 |
* Returns true if the data was passed on to the socket API directly, false if a portion of it had to be |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
210 |
* buffered (if there is already data buffered, all subsequent write_prefix's will buffer the full message |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
211 |
* until our buffer is empty again). If this method returns false, you must register the socket for |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
212 |
* poll_write and call flush_write later. |
380 | 213 |
* |
284 | 214 |
* @param buf the data to write |
215 |
* @param prefix the amount of data |
|
380 | 216 |
* @return true if we had to buffer data, false otherwise |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
217 |
*/ |
380 | 218 |
bool write_prefix (char *buf, uint16_t prefix); |
219 |
bool write_prefix (char *buf, uint32_t prefix); |
|
284 | 220 |
// @} |
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
221 |
}; |
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
222 |
|
399
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
223 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
224 |
/* |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
225 |
* NetworkBufferInput template method implementation |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
226 |
*/ |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
227 |
template <typename PrefixType> bool NetworkBufferOutput::peek_data (PrefixType &prefix, char *&buf_ref) { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
228 |
size_t missing = 0; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
229 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
230 |
do { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
231 |
// do we have the prefix? |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
232 |
if (peek_prefix(prefix)) { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
233 |
// do we already have the payload? |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
234 |
if (offset >= sizeof(PrefixType) + prefix) { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
235 |
break; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
236 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
237 |
} else { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
238 |
missing = (sizeof(PrefixType) + prefix) - offset; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
239 |
} |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
240 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
241 |
} else { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
242 |
missing = sizeof(PrefixType); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
243 |
} |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
244 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
245 |
// sanity-check (above >= and - should never happen like this) |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
246 |
assert(missing); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
247 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
248 |
// try and read the missing data |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
249 |
if (try_read(missing) == false) { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
250 |
// if unable to read what we need, return zero. |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
251 |
return false; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
252 |
} |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
253 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
254 |
// assess the situation again |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
255 |
} while (true); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
256 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
257 |
// update the buf_ref to point past the prefix-length |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
258 |
buf_ref = buf + sizeof(PrefixType); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
259 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
260 |
// return message |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
261 |
return true; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
262 |
} |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
263 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
264 |
template <typename PrefixType> void NetworkBufferOutput::flush_data (void) { |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
265 |
PrefixType prefix; |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
266 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
267 |
// we *must* have a valid prefix |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
268 |
if (!peek_prefix(prefix)) |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
269 |
assert(false); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
270 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
271 |
// ensure that we have the data to trim... |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
272 |
assert(offset >= sizeof(PrefixType) + prefix); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
273 |
|
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
274 |
// trim the bytes out |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
275 |
trim(sizeof(PrefixType) + prefix); |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
276 |
} |
c7295b72731a
documentation work on Network
Tero Marttila <terom@fixme.fi>
parents:
380
diff
changeset
|
277 |
|
200
2dbf40661580
better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff
changeset
|
278 |
#endif |